Changeset 933f32f for src/ResolvExpr/Cost.h
- Timestamp:
 - May 24, 2019, 10:19:41 AM (6 years ago)
 - Branches:
 - ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
 - Children:
 - d908563
 - Parents:
 - 6a9d4b4 (diff), 292642a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
 - 
      
- 1 edited
 
- 
          
  src/ResolvExpr/Cost.h (modified) (14 diffs)
 
 
Legend:
- Unmodified
 - Added
 - Removed
 
- 
      
src/ResolvExpr/Cost.h
r6a9d4b4 r933f32f 7 7 // Cost.h -- 8 8 // 9 // Author : Richard C. Bilson9 // Author : Peter Buhr and Aaron Moss 10 10 // Created On : Sun May 17 09:39:50 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Fri Oct 05 14:32:00 201813 // Update Count : 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 29 18:33:44 2019 13 // Update Count : 49 14 14 // 15 15 … … 17 17 18 18 #include <iostream> 19 #include <cassert> 20 #include <climits> 19 21 20 22 namespace ResolvExpr { 23 #if 0 24 25 //*************************** OLD *************************** 26 21 27 class Cost { 22 28 private: 23 Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost, 24 int referenceCost ); 25 29 Cost( int unsafeCost, int polyCost, int safeCost, int signCost, 30 int varCost, int specCost, int referenceCost ); 26 31 public: 27 32 Cost & incUnsafe( int inc = 1 ); 28 33 Cost & incPoly( int inc = 1 ); 29 34 Cost & incSafe( int inc = 1 ); 35 Cost & incSign( int inc = 1 ); 30 36 Cost & incVar( int inc = 1 ); 31 37 Cost & decSpec( int inc = 1 ); … … 35 41 int get_polyCost() const { return polyCost; } 36 42 int get_safeCost() const { return safeCost; } 43 int get_signCost() const { return signCost; } 37 44 int get_varCost() const { return varCost; } 38 45 int get_specCost() const { return specCost; } … … 40 47 41 48 Cost operator+( const Cost &other ) const; 42 Cost operator-( const Cost &other ) const;43 49 Cost &operator+=( const Cost &other ); 44 50 bool operator<( const Cost &other ) const; … … 55 61 static const Cost poly; 56 62 static const Cost safe; 63 static const Cost sign; 57 64 static const Cost var; 58 65 static const Cost spec; … … 63 70 int polyCost; ///< Count of parameters and return values bound to some poly type 64 71 int safeCost; ///< Safe (widening) conversions 72 int signCost; ///< Count of safe sign conversions 65 73 int varCost; ///< Count of polymorphic type variables 66 74 int specCost; ///< Polymorphic type specializations (type assertions), negative cost … … 68 76 }; 69 77 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 ) {}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 ) {} 74 82 75 83 inline Cost & Cost::incUnsafe( int inc ) { … … 88 96 if ( *this == infinity ) return *this; 89 97 safeCost += inc; 98 return *this; 99 } 100 101 inline Cost & Cost::incSign( int inc ) { 102 if ( *this == infinity ) return *this; 103 signCost += inc; 90 104 return *this; 91 105 } … … 111 125 inline Cost Cost::operator+( const Cost &other ) const { 112 126 if ( *this == infinity || other == infinity ) return infinity; 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 }; 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 }; 125 131 } 126 132 … … 134 140 polyCost += other.polyCost; 135 141 safeCost += other.safeCost; 142 signCost += other.signCost; 136 143 varCost += other.varCost; 137 144 specCost += other.specCost; … … 156 163 } else if ( safeCost < other.safeCost ) { 157 164 return true; 165 } else if ( signCost > other.signCost ) { 166 return false; 167 } else if ( signCost < other.signCost ) { 168 return true; 158 169 } else if ( varCost > other.varCost ) { 159 170 return false; … … 180 191 c = polyCost - other.polyCost; if ( c ) return c; 181 192 c = safeCost - other.safeCost; if ( c ) return c; 193 c = signCost - other.signCost; if ( c ) return c; 182 194 c = varCost - other.varCost; if ( c ) return c; 183 195 c = specCost - other.specCost; if ( c ) return c; … … 189 201 && polyCost == other.polyCost 190 202 && safeCost == other.safeCost 203 && signCost == other.signCost 191 204 && varCost == other.varCost 192 205 && specCost == other.specCost … … 199 212 200 213 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { 201 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " 202 << cost.safeCost << ", " << cost.varCost << ", " << cost.specCost << ", " 214 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " 215 << cost.safeCost << ", " << cost.signCost << ", " 216 << cost.varCost << ", " << cost.specCost << ", " 203 217 << cost.referenceCost << " )"; 204 218 } 219 220 #else 221 222 //*************************** NEW *************************** 223 224 // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the 225 // 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; ///< unused 233 unsigned char referenceCost; ///< reference conversions 234 unsigned char specCost; ///< Polymorphic type specializations (type assertions), negative cost 235 unsigned char varCost; ///< Count of polymorphic type variables 236 unsigned char signCost; ///< Count of safe sign conversions 237 unsigned char safeCost; ///< Safe (widening) conversions 238 unsigned char polyCost; ///< Count of parameters and return values bound to some poly type 239 unsigned char unsafeCost; ///< Unsafe (narrowing) conversions 240 #else 241 #error Cost BIG_ENDIAN unsupported 242 #endif 243 } v; 244 uint64_t all; 245 }; 246 static const unsigned char correctb = 0xff; // byte correction for negative spec cost 247 static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost 248 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, // padding 268 (unsigned char)referenceCost, // low priority 269 (unsigned char)(specCost + correctb), // correct for signedness 270 (unsigned char)varCost, 271 (unsigned char)signCost, 272 (unsigned char)safeCost, 273 (unsigned char)polyCost, 274 (unsigned char)unsafeCost, // high priority 275 #else 276 #error Cost BIG_ENDIAN unsupported 277 #endif 278 }; 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 > rhs 292 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 cost 308 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 cost 366 } 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 // 0 205 374 } // namespace ResolvExpr 206 375  
  Note:
 See   TracChangeset
 for help on using the changeset viewer.