Changes in src/ResolvExpr/Cost.h [b10c39a0:cdcddfe1]
- File:
-
- 1 edited
-
src/ResolvExpr/Cost.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Cost.h
rb10c39a0 rcdcddfe1 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 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 29 18:33:44201913 // Update Count : 4912 // Last Modified On : Thu Feb 7 20:54:29 2019 13 // Update Count : 8 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 23 Cost( int unsafeCost, int polyCost, int safeCost, int signCost, 30 int varCost, int specCost, int referenceCost );24 int varCost, int specCost, int referenceCost ); 31 25 public: 32 26 Cost & incUnsafe( int inc = 1 ); … … 77 71 78 72 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost, 79 int varCost, int specCost, int referenceCost )73 int varCost, int specCost, int referenceCost ) 80 74 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ), 81 75 varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {} … … 127 121 return Cost{ 128 122 unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, 129 signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,130 referenceCost + other.referenceCost };123 signCost + other.signCost, varCost + other.varCost, specCost + other.specCost, 124 referenceCost + other.referenceCost }; 131 125 } 132 126 … … 217 211 << cost.referenceCost << " )"; 218 212 } 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 213 } // namespace ResolvExpr 375 214
Note:
See TracChangeset
for help on using the changeset viewer.