Changes in / [c64e979:98d4df9]


Ignore:
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Cost.h

    rc64e979 r98d4df9  
    1010// Created On       : Sun May 17 09:39:50 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Apr 28 18:26:36 2019
    13 // Update Count     : 29
     12// Last Modified On : Mon Apr 29 18:33:44 2019
     13// Update Count     : 49
    1414//
    1515
     
    1818#include <iostream>
    1919#include <cassert>
     20#include <climits>
    2021
    2122namespace ResolvExpr {
     
    216217                          << cost.referenceCost << " )";
    217218        }
    218 #endif // 0
     219
     220#else
    219221
    220222        //*************************** 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.
    221226
    222227        class Cost {
     
    234239                                unsigned char unsafeCost;                               ///< Unsafe (narrowing) conversions
    235240                        #else
    236                                 #error BIG_ENDIAN unsupported
     241                                #error Cost BIG_ENDIAN unsupported
    237242                        #endif
    238243                        } v;
    239244                        uint64_t all;
    240245                };
     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
    241248          public:
    242249                // Compiler adjusts constants for correct endian.
    243250                enum : uint64_t {
    244                         zero       = 0x00'00'00'00'00'ff'00'00,
    245                         infinity   = 0xff'ff'ff'ff'ff'00'ff'ff,
    246                         correction = 0x00'00'00'00'00'ff'00'00,         // correct for negative spec cost
    247                         unsafe     = 0x01'00'00'00'00'ff'00'00,
    248                         poly       = 0x00'01'00'00'00'ff'00'00,
    249                         safe       = 0x00'00'01'00'00'ff'00'00,
    250                         sign       = 0x00'00'00'01'00'ff'00'00,
    251                         var        = 0x00'00'00'00'01'ff'00'00,
    252                         spec       = 0x00'00'00'00'00'fe'00'00,
    253                         reference  = 0x00'00'00'00'00'ff'01'00,
    254                 }; //
     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                }; //'
    255261
    256262                Cost( uint64_t all ) { Cost::all = all; }
     
    258264                        // Assume little-endian => first value is low priority and last is high priority.
    259265                        v = {
     266                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    260267                                (unsigned char)0,                                               // padding
    261                                 (unsigned char)referenceCost, 
    262                                 (unsigned char)(specCost + 0xff ),              // correct for signedness
     268                                (unsigned char)referenceCost,                   // low priority
     269                                (unsigned char)(specCost + correctb),   // correct for signedness
    263270                                (unsigned char)varCost,
    264271                                (unsigned char)signCost,
    265272                                (unsigned char)safeCost,
    266273                                (unsigned char)polyCost,
    267                                 (unsigned char)unsafeCost,
     274                                (unsigned char)unsafeCost,                              // high priority
     275                        #else
     276                                #error Cost BIG_ENDIAN unsupported
     277                        #endif
    268278                        };
    269279                }
     
    274284                int get_signCost() const { return v.signCost; }
    275285                int get_varCost() const { return v.varCost; }
    276                 int get_specCost() const { return -(0xff - v.specCost); }
     286                int get_specCost() const { return -(correctb - v.specCost); }
    277287                int get_referenceCost() const { return v.referenceCost; }
    278288
     
    295305                                return *this;
    296306                        }
    297                         all += rhs.all - correction;                            // correct for negative spec cost
     307                        all += rhs.all - correctw;                                      // correct for negative spec cost
    298308                        return *this;
    299309                }
    300310
    301311                Cost incUnsafe( int inc = 1 ) {
    302                         if ( all != infinity ) { assert( v.unsafeCost + inc < 256 ); v.unsafeCost += inc; }
     312                        if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; }
    303313                        return *this;
    304314                }
    305315
    306316                Cost incPoly( int inc = 1 ) {
    307                         if ( all != infinity ) { assert( v.polyCost + inc < 256 ); v.polyCost += inc; }
     317                        if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; }
    308318                        return *this;
    309319                }
    310320
    311321                Cost incSafe( int inc = 1 ) {
    312                         if ( all != infinity ) { assert( v.safeCost + inc < 256 ); v.safeCost += inc; }
     322                        if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; }
    313323                        return *this;
    314324                }
    315325
    316326                Cost incSign( int inc = 1 ) {
    317                         if ( all != infinity ) { assert( v.signCost + inc < 256 ); v.signCost += inc; }
     327                        if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; }
    318328                        return *this;
    319329                }
    320330
    321331                Cost incVar( int inc = 1 ) {
    322                         if ( all != infinity ) { assert( v.varCost + inc < 256 ); v.varCost += inc; }
     332                        if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; }
    323333                        return *this;
    324334                }
    325335
    326336                Cost decSpec( int dec = 1 ) {
    327                         if ( all != infinity ) { v.specCost -= dec; }
     337                        if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; }
    328338                        return *this;
    329339                }
    330340
    331341                Cost incReference( int inc = 1 ) {
    332                         if ( all != infinity ) { assert( v.referenceCost + inc < 256 ); v.referenceCost += inc; }
     342                        if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; }
    333343                        return *this;
    334344                }
     
    353363        inline Cost operator+( const Cost lhs, const Cost rhs ) {
    354364                if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity };
    355                 return Cost{ lhs.all + rhs.all - Cost::correction }; // correct for negative spec cost
     365                return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost
    356366        }
    357367
     
    361371                                  << ", " << cost.get_referenceCost() << " )";
    362372        }
     373#endif // 0
    363374} // namespace ResolvExpr
    364375
  • src/ResolvExpr/ResolveAssertions.cc

    rc64e979 r98d4df9  
    155155                                        k += computeConversionCost(
    156156                                                assn.match.adjType, assn.decl->get_type(), indexer, x.env );
     157                                       
     158                                        // mark vars+specialization cost on function-type assertions
     159                                        PointerType* ptr = dynamic_cast< PointerType* >( assn.decl->get_type() );
     160                                        if ( ! ptr ) continue;
     161                                        FunctionType* func = dynamic_cast< FunctionType* >( ptr->base );
     162                                        if ( ! func ) continue;
     163                                       
     164                                        for ( DeclarationWithType* formal : func->parameters ) {
     165                                                k.decSpec( specCost( formal->get_type() ) );
     166                                        }
     167                                        k.incVar( func->forall.size() );
     168                                        for ( TypeDecl* td : func->forall ) {
     169                                                k.decSpec( td->assertions.size() );
     170                                        }
    157171                                }
    158172                                it = cache.emplace_hint( it, &x, k );
Note: See TracChangeset for help on using the changeset viewer.