Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Cost.h

    rb10c39a0 rcdcddfe1  
    77// Cost.h --
    88//
    9 // Author           : Peter Buhr and Aaron Moss
     9// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 09:39:50 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 29 18:33:44 2019
    13 // Update Count     : 49
     12// Last Modified On : Thu Feb  7 20:54:29 2019
     13// Update Count     : 8
    1414//
    1515
     
    1717
    1818#include <iostream>
    19 #include <cassert>
    20 #include <climits>
    2119
    2220namespace ResolvExpr {
    23 #if 0
    24 
    25         //*************************** OLD ***************************
    26 
    2721        class Cost {
    2822          private:
    2923                Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
    30                           int varCost, int specCost, int referenceCost );
     24                        int varCost, int specCost, int referenceCost );
    3125          public:
    3226                Cost & incUnsafe( int inc = 1 );
     
    7771
    7872        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 )
    8074                : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),
    8175                  varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}
     
    127121                return Cost{
    128122                        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 };
    131125        }
    132126
     
    217211                          << cost.referenceCost << " )";
    218212        }
    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
    374213} // namespace ResolvExpr
    375214
Note: See TracChangeset for help on using the changeset viewer.