Changes in src/ResolvExpr/Cost.h [9504a89:ddf8a29]
- File:
-
- 1 edited
-
src/ResolvExpr/Cost.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Cost.h
r9504a89 rddf8a29 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 : Fri Jun 21 11:39:13 201913 // Update Count : 6312 // Last Modified On : Sat Jul 22 09:35:55 2017 13 // Update Count : 5 14 14 // 15 15 … … 17 17 18 18 #include <iostream> 19 #include <cassert>20 #include <climits>21 19 22 20 namespace ResolvExpr { 23 // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the 24 // specialization cost is a negative value so a correction is needed is a few places. 21 class Cost { 22 private: 23 Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ); 25 24 26 class Cost {27 union {28 struct {29 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__30 // Little-endian => first value is low priority and last is high priority.31 unsigned char padding; ///< unused32 unsigned char referenceCost; ///< reference conversions33 unsigned char specCost; ///< Polymorphic type specializations (type assertions), negative cost34 unsigned char varCost; ///< Count of polymorphic type variables35 unsigned char signCost; ///< Count of safe sign conversions36 unsigned char safeCost; ///< Safe (widening) conversions37 unsigned char polyCost; ///< Count of parameters and return values bound to some poly type38 unsigned char unsafeCost; ///< Unsafe (narrowing) conversions39 #else40 #error Cost BIG_ENDIAN unsupported41 #endif42 } v;43 uint64_t all;44 };45 static const unsigned char correctb = 0xff; // byte correction for negative spec cost46 static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost47 25 public: 48 // Compiler adjusts constants for correct endian. 49 enum : uint64_t { 50 zero = 0x00'00'00'00'00'ff'00'00, 51 infinity = 0xff'ff'ff'ff'ff'00'ff'ff, 52 unsafe = 0x01'00'00'00'00'ff'00'00, 53 poly = 0x00'01'00'00'00'ff'00'00, 54 safe = 0x00'00'01'00'00'ff'00'00, 55 sign = 0x00'00'00'01'00'ff'00'00, 56 var = 0x00'00'00'00'01'ff'00'00, 57 spec = 0x00'00'00'00'00'fe'00'00, 58 reference = 0x00'00'00'00'00'ff'01'00, 59 }; //' 26 Cost & incUnsafe( int inc = 1 ); 27 Cost & incPoly( int inc = 1 ); 28 Cost & incSafe( int inc = 1 ); 29 Cost & incReference( int inc = 1 ); 60 30 61 Cost( uint64_t all ) { Cost::all = all; } 62 Cost( int unsafeCost, int polyCost, int safeCost, int signCost, int varCost, int specCost, int referenceCost ) { 63 // Assume little-endian => first value is low priority and last is high priority. 64 v = { 65 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 66 (unsigned char)0, // padding 67 (unsigned char)referenceCost, // low priority 68 (unsigned char)(specCost + correctb), // correct for signedness 69 (unsigned char)varCost, 70 (unsigned char)signCost, 71 (unsigned char)safeCost, 72 (unsigned char)polyCost, 73 (unsigned char)unsafeCost, // high priority 74 #else 75 #error Cost BIG_ENDIAN unsupported 76 #endif 77 }; 78 } 31 int get_unsafeCost() const { return unsafeCost; } 32 int get_polyCost() const { return polyCost; } 33 int get_safeCost() const { return safeCost; } 34 int get_referenceCost() const { return referenceCost; } 79 35 80 int get_unsafeCost() const { return v.unsafeCost; }81 int get_polyCost() const { return v.polyCost; }82 int get_safeCost() const { return v.safeCost; }83 int get_signCost() const { return v.signCost; }84 int get_varCost() const { return v.varCost; }85 int get_specCost() const { return -(correctb - v.specCost); }86 int get_referenceCost() const { return v.referenceCost; }36 Cost operator+( const Cost &other ) const; 37 Cost operator-( const Cost &other ) const; 38 Cost &operator+=( const Cost &other ); 39 bool operator<( const Cost &other ) const; 40 bool operator==( const Cost &other ) const; 41 bool operator!=( const Cost &other ) const; 42 friend std::ostream &operator<<( std::ostream &os, const Cost &cost ); 87 43 88 friend bool operator==( const Cost, const Cost ); 89 friend bool operator!=( const Cost lhs, const Cost rhs ); 90 // returns negative for *this < rhs, 0 for *this == rhs, positive for *this > rhs 91 int compare( const Cost rhs ) const { 92 if ( all == infinity ) return 1; 93 if ( rhs.all == infinity ) return -1; 94 return all > rhs.all ? 1 : all == rhs.all ? 0 : -1; 95 } 96 friend bool operator<( const Cost lhs, const Cost rhs ); 44 static const Cost zero; 45 static const Cost infinity; 97 46 98 friend Cost operator+( const Cost lhs, const Cost rhs ); 99 100 Cost operator+=( const Cost rhs ) { 101 if ( all == infinity ) return *this; 102 if ( rhs.all == infinity ) { 103 all = infinity; 104 return *this; 105 } 106 all += rhs.all - correctw; // correct for negative spec cost 47 static const Cost unsafe; 48 static const Cost poly; 49 static const Cost safe; 50 static const Cost reference; 51 private: 52 int compare( const Cost &other ) const; 53 54 int unsafeCost; 55 int polyCost; 56 int safeCost; 57 int referenceCost; 58 }; 59 60 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ) : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), referenceCost( referenceCost ) {} 61 62 inline Cost & Cost::incUnsafe( int inc ) { 63 if ( *this == infinity ) return *this; 64 unsafeCost += inc; 65 return *this; 66 } 67 68 inline Cost & Cost::incPoly( int inc ) { 69 if ( *this == infinity ) return *this; 70 polyCost += inc; 71 return *this; 72 } 73 74 inline Cost & Cost::incSafe( int inc ) { 75 if ( *this == infinity ) return *this; 76 safeCost += inc; 77 return *this; 78 } 79 80 inline Cost & Cost::incReference( int inc ) { 81 if ( *this == infinity ) return *this; 82 referenceCost += inc; 83 return *this; 84 } 85 86 inline Cost Cost::operator+( const Cost &other ) const { 87 if ( *this == infinity || other == infinity ) return infinity; 88 return Cost( unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, referenceCost + other.referenceCost ); 89 } 90 91 inline Cost Cost::operator-( const Cost &other ) const { 92 if ( *this == infinity || other == infinity ) return infinity; 93 return Cost( unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, referenceCost - other.referenceCost ); 94 } 95 96 inline Cost &Cost::operator+=( const Cost &other ) { 97 if ( *this == infinity ) return *this; 98 if ( other == infinity ) { 99 *this = infinity; 107 100 return *this; 108 101 } 109 110 Cost incUnsafe( int inc = 1 ) { 111 if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; } 112 return *this; 113 } 114 115 Cost incPoly( int inc = 1 ) { 116 if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; } 117 return *this; 118 } 119 120 Cost incSafe( int inc = 1 ) { 121 if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; } 122 return *this; 123 } 124 125 Cost incSign( int inc = 1 ) { 126 if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; } 127 return *this; 128 } 129 130 Cost incVar( int inc = 1 ) { 131 if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; } 132 return *this; 133 } 134 135 Cost decSpec( int dec = 1 ) { 136 if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; } 137 return *this; 138 } 139 140 Cost incReference( int inc = 1 ) { 141 if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; } 142 return *this; 143 } 144 145 friend std::ostream & operator<<( std::ostream & os, const Cost cost ); 146 }; 147 148 inline bool operator==( const Cost lhs, const Cost rhs ) { 149 return lhs.all == rhs.all; 102 unsafeCost += other.unsafeCost; 103 polyCost += other.polyCost; 104 safeCost += other.safeCost; 105 referenceCost += other.referenceCost; 106 return *this; 150 107 } 151 108 152 inline bool operator!=( const Cost lhs, const Cost rhs ) { 153 return !( lhs.all == rhs.all ); 109 inline bool Cost::operator<( const Cost &other ) const { 110 if ( *this == infinity ) return false; 111 if ( other == infinity ) return true; 112 113 if ( unsafeCost > other.unsafeCost ) { 114 return false; 115 } else if ( unsafeCost < other.unsafeCost ) { 116 return true; 117 } else if ( polyCost > other.polyCost ) { 118 return false; 119 } else if ( polyCost < other.polyCost ) { 120 return true; 121 } else if ( safeCost > other.safeCost ) { 122 return false; 123 } else if ( safeCost < other.safeCost ) { 124 return true; 125 } else if ( referenceCost > other.referenceCost ) { 126 return false; 127 } else if ( referenceCost < other.referenceCost ) { 128 return true; 129 } else { 130 return false; 131 } // if 154 132 } 155 133 156 inline bool operator<( const Cost lhs, const Cost rhs ) { 157 if ( lhs.all == Cost::infinity ) return false; 158 if ( rhs.all == Cost::infinity ) return true; 159 return lhs.all < rhs.all; 134 inline bool Cost::operator==( const Cost &other ) const { 135 return unsafeCost == other.unsafeCost 136 && polyCost == other.polyCost 137 && safeCost == other.safeCost 138 && referenceCost == other.referenceCost; 160 139 } 161 140 162 inline Cost operator+( const Cost lhs, const Cost rhs ) { 163 if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity }; 164 return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost 141 inline bool Cost::operator!=( const Cost &other ) const { 142 return !( *this == other ); 165 143 } 166 144 167 inline std::ostream & operator<<( std::ostream & os, const Cost cost ) { 168 return os << "( " << cost.get_unsafeCost() << ", " << cost.get_polyCost() << ", " << cost.get_safeCost() 169 << ", " << cost.get_signCost() << ", " << cost.get_varCost() << ", " << cost.get_specCost() 170 << ", " << cost.get_referenceCost() << " )"; 145 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { 146 os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " << cost.safeCost << ", " << cost.referenceCost << " )"; 147 return os; 171 148 } 172 149 } // namespace ResolvExpr
Note:
See TracChangeset
for help on using the changeset viewer.