Ignore:
Timestamp:
May 28, 2019, 2:22:03 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
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:
eba615c
Parents:
6f4b7f2
git-author:
Aaron Moss <a3moss@…> (05/28/19 14:21:58)
git-committer:
Aaron Moss <a3moss@…> (05/28/19 14:22:03)
Message:

Fix bugs in assertion satisfaction costing

  • Calculate vars/spec cost based on satisfying decl not assn decl
  • Correct caching behaviour for defer combo costs
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ResolveAssertions.cc

    r6f4b7f2 rc519942  
    103103                        OpenVarSet openVars;
    104104                        std::vector<DeferRef> assns;
     105                        Cost cost;
    105106
    106107                        OutType( const TypeEnvironment& env, const OpenVarSet& openVars,
    107108                                const std::vector<DeferRef>& assns )
    108                         : env(env), openVars(openVars), assns(assns) {}
     109                        : env(env), openVars(openVars), assns(assns), cost(Cost::infinity) {}
    109110                };
    110111
     
    140141                using Element = CandidateEnvMerger::OutType;
    141142        private:
    142                 using Memo = std::unordered_map<const Element*, Cost>;
    143                 mutable Memo cache;              ///< cache of element costs
    144143                const SymTab::Indexer& indexer;  ///< Indexer for costing
    145144
     
    148147
    149148                /// reports the cost of an element
    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 );
     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                                }
    173176                        }
    174                         return it->second;
     177
     178                        // cache and return
     179                        x.cost = k;
     180                        return k;
    175181                }
    176182               
    177183                /// compares elements by cost
    178                 bool operator() ( const Element& a, const Element& b ) const {
     184                bool operator() ( Element& a, Element& b ) const {
    179185                        return get( a ) < get( b );
    180186                }
Note: See TracChangeset for help on using the changeset viewer.