Ignore:
Timestamp:
Apr 30, 2019, 2:53:47 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
02af79b0, 8278abf
Parents:
1bc5975 (diff), 98d4df9 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Cost.h

    r1bc5975 rec28948  
    77// Cost.h --
    88//
    9 // Author           : Richard C. Bilson
     9// Author           : Peter Buhr and Aaron Moss
    1010// Created On       : Sun May 17 09:39:50 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  7 20:54:29 2019
    13 // Update Count     : 8
     12// Last Modified On : Mon Apr 29 18:33:44 2019
     13// Update Count     : 49
    1414//
    1515
     
    1717
    1818#include <iostream>
     19#include <cassert>
     20#include <climits>
    1921
    2022namespace ResolvExpr {
     23#if 0
     24
     25        //*************************** OLD ***************************
     26
    2127        class Cost {
    2228          private:
    2329                Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
    24                         int varCost, int specCost, int referenceCost );
     30                          int varCost, int specCost, int referenceCost );
    2531          public:
    2632                Cost & incUnsafe( int inc = 1 );
     
    7177
    7278        inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
    73                         int varCost, int specCost, int referenceCost )
     79                                           int varCost, int specCost, int referenceCost )
    7480                : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),
    7581                  varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}
     
    121127                return Cost{
    122128                        unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,
    123                         signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,
    124                         referenceCost + other.referenceCost };
     129                                signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,
     130                                referenceCost + other.referenceCost };
    125131        }
    126132
     
    211217                          << cost.referenceCost << " )";
    212218        }
     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
    213374} // namespace ResolvExpr
    214375
Note: See TracChangeset for help on using the changeset viewer.