Changeset b067d9b for src/ResolvExpr/Cost.h
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (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
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Cost.h
r7951100 rb067d9b 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 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:35:55 201713 // Update Count : 512 // Last Modified On : Fri Jun 21 11:39:13 2019 13 // Update Count : 63 14 14 // 15 15 … … 17 17 18 18 #include <iostream> 19 #include <cassert> 20 #include <climits> 19 21 20 22 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. 25 21 26 class Cost { 22 private: 23 Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ); 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; ///< unused 32 unsigned char referenceCost; ///< reference conversions 33 unsigned char specCost; ///< Polymorphic type specializations (type assertions), negative cost 34 unsigned char varCost; ///< Count of polymorphic type variables 35 unsigned char signCost; ///< Count of safe sign conversions 36 unsigned char safeCost; ///< Safe (widening) conversions 37 unsigned char polyCost; ///< Count of parameters and return values bound to some poly type 38 unsigned char unsafeCost; ///< Unsafe (narrowing) conversions 39 #else 40 #error Cost BIG_ENDIAN unsupported 41 #endif 42 } v; 43 uint64_t all; 44 }; 45 static const unsigned char correctb = 0xff; // byte correction for negative spec cost 46 static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost 47 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 }; //' 24 60 25 public: 26 Cost & incUnsafe( int inc = 1 ); 27 Cost & incPoly( int inc = 1 ); 28 Cost & incSafe( int inc = 1 ); 29 Cost & incReference( int inc = 1 ); 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 } 30 79 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; } 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; } 35 87 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 ); 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 ); 43 97 44 static const Cost zero; 45 static const Cost infinity; 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 107 return *this; 108 } 46 109 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; 110 Cost incUnsafe( int inc = 1 ) { 111 if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; } 112 return *this; 113 } 53 114 54 int unsafeCost; 55 int polyCost; 56 int safeCost; 57 int referenceCost; 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 ); 58 146 }; 59 147 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; 148 inline bool operator==( const Cost lhs, const Cost rhs ) { 149 return lhs.all == rhs.all; 66 150 } 67 151 68 inline Cost & Cost::incPoly( int inc ) { 69 if ( *this == infinity ) return *this; 70 polyCost += inc; 71 return *this; 152 inline bool operator!=( const Cost lhs, const Cost rhs ) { 153 return !( lhs.all == rhs.all ); 72 154 } 73 155 74 inline Cost & Cost::incSafe( int inc) {75 if ( *this == infinity ) return *this;76 safeCost += inc;77 return *this;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; 78 160 } 79 161 80 inline Cost & Cost::incReference( int inc ) { 81 if ( *this == infinity ) return *this; 82 referenceCost += inc; 83 return *this; 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 84 165 } 85 166 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; 100 return *this; 101 } 102 unsafeCost += other.unsafeCost; 103 polyCost += other.polyCost; 104 safeCost += other.safeCost; 105 referenceCost += other.referenceCost; 106 return *this; 107 } 108 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 132 } 133 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; 139 } 140 141 inline bool Cost::operator!=( const Cost &other ) const { 142 return !( *this == other ); 143 } 144 145 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { 146 os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " << cost.safeCost << ", " << cost.referenceCost << " )"; 147 return os; 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() << " )"; 148 171 } 149 172 } // namespace ResolvExpr
Note:
See TracChangeset
for help on using the changeset viewer.