Changes in src/ResolvExpr/Cost.h [b10c39a0:d97c3a4]
- File:
-
- 1 edited
-
src/ResolvExpr/Cost.h (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Cost.h
rb10c39a0 rd97c3a4 7 7 // Cost.h -- 8 8 // 9 // Author : Peter Buhr and Aaron Moss9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 09:39:50 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Apr 29 18:33:44 201913 // Update Count : 4911 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Oct 05 14:32:00 2018 13 // Update Count : 7 14 14 // 15 15 … … 17 17 18 18 #include <iostream> 19 #include <cassert>20 #include <climits>21 19 22 20 namespace ResolvExpr { 23 #if 024 25 //*************************** OLD ***************************26 27 21 class Cost { 28 22 private: 29 Cost( int unsafeCost, int polyCost, int safeCost, int signCost, 30 int varCost, int specCost, int referenceCost ); 23 Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost, 24 int referenceCost ); 25 31 26 public: 32 27 Cost & incUnsafe( int inc = 1 ); 33 28 Cost & incPoly( int inc = 1 ); 34 29 Cost & incSafe( int inc = 1 ); 35 Cost & incSign( int inc = 1 );36 30 Cost & incVar( int inc = 1 ); 37 31 Cost & decSpec( int inc = 1 ); … … 41 35 int get_polyCost() const { return polyCost; } 42 36 int get_safeCost() const { return safeCost; } 43 int get_signCost() const { return signCost; }44 37 int get_varCost() const { return varCost; } 45 38 int get_specCost() const { return specCost; } … … 47 40 48 41 Cost operator+( const Cost &other ) const; 42 Cost operator-( const Cost &other ) const; 49 43 Cost &operator+=( const Cost &other ); 50 44 bool operator<( const Cost &other ) const; … … 61 55 static const Cost poly; 62 56 static const Cost safe; 63 static const Cost sign;64 57 static const Cost var; 65 58 static const Cost spec; … … 70 63 int polyCost; ///< Count of parameters and return values bound to some poly type 71 64 int safeCost; ///< Safe (widening) conversions 72 int signCost; ///< Count of safe sign conversions73 65 int varCost; ///< Count of polymorphic type variables 74 66 int specCost; ///< Polymorphic type specializations (type assertions), negative cost … … 76 68 }; 77 69 78 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost,79 int varCost, int specCost, int referenceCost )80 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),81 varCost( varCost ),specCost( specCost ), referenceCost( referenceCost ) {}70 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost, 71 int referenceCost ) 72 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), varCost( varCost ), 73 specCost( specCost ), referenceCost( referenceCost ) {} 82 74 83 75 inline Cost & Cost::incUnsafe( int inc ) { … … 96 88 if ( *this == infinity ) return *this; 97 89 safeCost += inc; 98 return *this;99 }100 101 inline Cost & Cost::incSign( int inc ) {102 if ( *this == infinity ) return *this;103 signCost += inc;104 90 return *this; 105 91 } … … 125 111 inline Cost Cost::operator+( const Cost &other ) const { 126 112 if ( *this == infinity || other == infinity ) return infinity; 127 return Cost{ 128 unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, 129 signCost + other.signCost, varCost + other.varCost, specCost + other.specCost, 130 referenceCost + other.referenceCost }; 113 return Cost{ 114 unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, 115 varCost + other.varCost, specCost + other.specCost, 116 referenceCost + other.referenceCost }; 117 } 118 119 inline Cost Cost::operator-( const Cost &other ) const { 120 if ( *this == infinity || other == infinity ) return infinity; 121 return Cost{ 122 unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, 123 varCost - other.varCost, specCost - other.specCost, 124 referenceCost - other.referenceCost }; 131 125 } 132 126 … … 140 134 polyCost += other.polyCost; 141 135 safeCost += other.safeCost; 142 signCost += other.signCost;143 136 varCost += other.varCost; 144 137 specCost += other.specCost; … … 163 156 } else if ( safeCost < other.safeCost ) { 164 157 return true; 165 } else if ( signCost > other.signCost ) {166 return false;167 } else if ( signCost < other.signCost ) {168 return true;169 158 } else if ( varCost > other.varCost ) { 170 159 return false; … … 191 180 c = polyCost - other.polyCost; if ( c ) return c; 192 181 c = safeCost - other.safeCost; if ( c ) return c; 193 c = signCost - other.signCost; if ( c ) return c;194 182 c = varCost - other.varCost; if ( c ) return c; 195 183 c = specCost - other.specCost; if ( c ) return c; … … 201 189 && polyCost == other.polyCost 202 190 && safeCost == other.safeCost 203 && signCost == other.signCost204 191 && varCost == other.varCost 205 192 && specCost == other.specCost … … 212 199 213 200 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { 214 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " 215 << cost.safeCost << ", " << cost.signCost << ", " 216 << cost.varCost << ", " << cost.specCost << ", " 201 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " 202 << cost.safeCost << ", " << cost.varCost << ", " << cost.specCost << ", " 217 203 << cost.referenceCost << " )"; 218 204 } 219 220 #else221 222 //*************************** NEW ***************************223 224 // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the225 // specialization cost is a negative value so a correction is needed is a few places.226 227 class Cost {228 union {229 struct {230 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__231 // Little-endian => first value is low priority and last is high priority.232 unsigned char padding; ///< unused233 unsigned char referenceCost; ///< reference conversions234 unsigned char specCost; ///< Polymorphic type specializations (type assertions), negative cost235 unsigned char varCost; ///< Count of polymorphic type variables236 unsigned char signCost; ///< Count of safe sign conversions237 unsigned char safeCost; ///< Safe (widening) conversions238 unsigned char polyCost; ///< Count of parameters and return values bound to some poly type239 unsigned char unsafeCost; ///< Unsafe (narrowing) conversions240 #else241 #error Cost BIG_ENDIAN unsupported242 #endif243 } v;244 uint64_t all;245 };246 static const unsigned char correctb = 0xff; // byte correction for negative spec cost247 static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost248 public:249 // Compiler adjusts constants for correct endian.250 enum : uint64_t {251 zero = 0x00'00'00'00'00'ff'00'00,252 infinity = 0xff'ff'ff'ff'ff'00'ff'ff,253 unsafe = 0x01'00'00'00'00'ff'00'00,254 poly = 0x00'01'00'00'00'ff'00'00,255 safe = 0x00'00'01'00'00'ff'00'00,256 sign = 0x00'00'00'01'00'ff'00'00,257 var = 0x00'00'00'00'01'ff'00'00,258 spec = 0x00'00'00'00'00'fe'00'00,259 reference = 0x00'00'00'00'00'ff'01'00,260 }; //'261 262 Cost( uint64_t all ) { Cost::all = all; }263 Cost( int unsafeCost, int polyCost, int safeCost, int signCost, int varCost, int specCost, int referenceCost ) {264 // Assume little-endian => first value is low priority and last is high priority.265 v = {266 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__267 (unsigned char)0, // padding268 (unsigned char)referenceCost, // low priority269 (unsigned char)(specCost + correctb), // correct for signedness270 (unsigned char)varCost,271 (unsigned char)signCost,272 (unsigned char)safeCost,273 (unsigned char)polyCost,274 (unsigned char)unsafeCost, // high priority275 #else276 #error Cost BIG_ENDIAN unsupported277 #endif278 };279 }280 281 int get_unsafeCost() const { return v.unsafeCost; }282 int get_polyCost() const { return v.polyCost; }283 int get_safeCost() const { return v.safeCost; }284 int get_signCost() const { return v.signCost; }285 int get_varCost() const { return v.varCost; }286 int get_specCost() const { return -(correctb - v.specCost); }287 int get_referenceCost() const { return v.referenceCost; }288 289 friend bool operator==( const Cost, const Cost );290 friend bool operator!=( const Cost lhs, const Cost rhs );291 // returns negative for *this < rhs, 0 for *this == rhs, positive for *this > rhs292 int compare( const Cost rhs ) const {293 if ( all == infinity ) return 1;294 if ( rhs.all == infinity ) return -1;295 return all > rhs.all ? 1 : all == rhs.all ? 0 : -1;296 }297 friend bool operator<( const Cost lhs, const Cost rhs );298 299 friend Cost operator+( const Cost lhs, const Cost rhs );300 301 Cost operator+=( const Cost rhs ) {302 if ( all == infinity ) return *this;303 if ( rhs.all == infinity ) {304 all = infinity;305 return *this;306 }307 all += rhs.all - correctw; // correct for negative spec cost308 return *this;309 }310 311 Cost incUnsafe( int inc = 1 ) {312 if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; }313 return *this;314 }315 316 Cost incPoly( int inc = 1 ) {317 if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; }318 return *this;319 }320 321 Cost incSafe( int inc = 1 ) {322 if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; }323 return *this;324 }325 326 Cost incSign( int inc = 1 ) {327 if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; }328 return *this;329 }330 331 Cost incVar( int inc = 1 ) {332 if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; }333 return *this;334 }335 336 Cost decSpec( int dec = 1 ) {337 if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; }338 return *this;339 }340 341 Cost incReference( int inc = 1 ) {342 if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; }343 return *this;344 }345 346 friend std::ostream & operator<<( std::ostream & os, const Cost cost );347 };348 349 inline bool operator==( const Cost lhs, const Cost rhs ) {350 return lhs.all == rhs.all;351 }352 353 inline bool operator!=( const Cost lhs, const Cost rhs ) {354 return !( lhs.all == rhs.all );355 }356 357 inline bool operator<( const Cost lhs, const Cost rhs ) {358 if ( lhs.all == Cost::infinity ) return false;359 if ( rhs.all == Cost::infinity ) return true;360 return lhs.all < rhs.all;361 }362 363 inline Cost operator+( const Cost lhs, const Cost rhs ) {364 if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity };365 return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost366 }367 368 inline std::ostream & operator<<( std::ostream & os, const Cost cost ) {369 return os << "( " << cost.get_unsafeCost() << ", " << cost.get_polyCost() << ", " << cost.get_safeCost()370 << ", " << cost.get_signCost() << ", " << cost.get_varCost() << ", " << cost.get_specCost()371 << ", " << cost.get_referenceCost() << " )";372 }373 #endif // 0374 205 } // namespace ResolvExpr 375 206
Note:
See TracChangeset
for help on using the changeset viewer.