Changes in / [eba615c:0d70e0d]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ResolveAssertions.cc

    reba615c r0d70e0d  
    103103                        OpenVarSet openVars;
    104104                        std::vector<DeferRef> assns;
    105                         Cost cost;
    106105
    107106                        OutType( const TypeEnvironment& env, const OpenVarSet& openVars,
    108107                                const std::vector<DeferRef>& assns )
    109                         : env(env), openVars(openVars), assns(assns), cost(Cost::infinity) {}
     108                        : env(env), openVars(openVars), assns(assns) {}
    110109                };
    111110
     
    141140                using Element = CandidateEnvMerger::OutType;
    142141        private:
     142                using Memo = std::unordered_map<const Element*, Cost>;
     143                mutable Memo cache;              ///< cache of element costs
    143144                const SymTab::Indexer& indexer;  ///< Indexer for costing
    144145
     
    147148
    148149                /// reports the cost of an element
    149                 Cost get( Element& x ) const {
    150                         // check cached cost
    151                         if ( x.cost != Cost::infinity ) return x.cost;
    152 
    153                         // generate cost
    154                         Cost k = Cost::zero;
    155                         for ( const auto& assn : x.assns ) {
    156                                 k += computeConversionCost(
    157                                         assn.match.adjType, assn.decl->get_type(), indexer, x.env );
    158                                
    159                                 // mark vars+specialization cost on function-type assertions
    160                                 Type* assnType = assn.match.cdata.id->get_type();
    161                                 FunctionType* func;
    162                                 if ( PointerType* ptr = dynamic_cast< PointerType* >( assnType ) ) {
    163                                         func = dynamic_cast< FunctionType* >( ptr->base );
    164                                 } else {
    165                                         func = dynamic_cast< FunctionType* >( assnType );
    166                                 }
    167                                 if ( ! func ) continue;
    168                                
    169                                 for ( DeclarationWithType* formal : func->parameters ) {
    170                                         k.decSpec( specCost( formal->get_type() ) );
    171                                 }
    172                                 k.incVar( func->forall.size() );
    173                                 for ( TypeDecl* td : func->forall ) {
    174                                         k.decSpec( td->assertions.size() );
    175                                 }
     150                Cost get( const Element& x ) const {
     151                        Memo::const_iterator it = cache.find( &x );
     152                        if ( it == cache.end() ) {
     153                                Cost k = Cost::zero;
     154                                for ( const auto& assn : x.assns ) {
     155                                        k += computeConversionCost(
     156                                                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                                        }
     171                                }
     172                                it = cache.emplace_hint( it, &x, k );
    176173                        }
    177 
    178                         // cache and return
    179                         x.cost = k;
    180                         return k;
     174                        return it->second;
    181175                }
    182176               
    183177                /// compares elements by cost
    184                 bool operator() ( Element& a, Element& b ) const {
     178                bool operator() ( const Element& a, const Element& b ) const {
    185179                        return get( a ) < get( b );
    186180                }
Note: See TracChangeset for help on using the changeset viewer.