- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ResolveAssertions.cc
r493a992 rc519942 103 103 OpenVarSet openVars; 104 104 std::vector<DeferRef> assns; 105 Cost cost; 105 106 106 107 OutType( const TypeEnvironment& env, const OpenVarSet& openVars, 107 108 const std::vector<DeferRef>& assns ) 108 : env(env), openVars(openVars), assns(assns) {}109 : env(env), openVars(openVars), assns(assns), cost(Cost::infinity) {} 109 110 }; 110 111 … … 140 141 using Element = CandidateEnvMerger::OutType; 141 142 private: 142 using Memo = std::unordered_map<const Element*, Cost>;143 mutable Memo cache; ///< cache of element costs144 143 const SymTab::Indexer& indexer; ///< Indexer for costing 145 144 … … 148 147 149 148 /// 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 } 173 176 } 174 return it->second; 177 178 // cache and return 179 x.cost = k; 180 return k; 175 181 } 176 182 177 183 /// compares elements by cost 178 bool operator() ( const Element& a, constElement& b ) const {184 bool operator() ( Element& a, Element& b ) const { 179 185 return get( a ) < get( b ); 180 186 }
Note: See TracChangeset
for help on using the changeset viewer.