Changeset 0b00df0 for src/ResolvExpr
- Timestamp:
- Nov 19, 2018, 5:05:12 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- 40290497
- Parents:
- 2fd9f24
- Location:
- src/ResolvExpr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r2fd9f24 r0b00df0 114 114 template<typename OutputIterator> 115 115 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 116 /// Checks if assertion parameters match for a newalternative116 /// Sets up parameter inference for an output alternative 117 117 template< typename OutputIterator > 118 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );118 void inferParameters( Alternative &newAlt, OutputIterator out ); 119 119 private: 120 120 AlternativeFinder & altFinder; … … 486 486 487 487 // xxx -- replace with new costs in resolver 488 for ( InferredParams::const_iterator assert = appExpr-> get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {488 for ( InferredParams::const_iterator assert = appExpr->inferParams.begin(); assert != appExpr->inferParams.end(); ++assert ) { 489 489 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 490 490 } … … 595 595 // ) 596 596 // // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter). 597 // InferredParams * inferParameters = &newerAlt.expr-> get_inferParams();597 // InferredParams * inferParameters = &newerAlt.expr->inferParams; 598 598 // for ( UniqueId id : cur->second.idChain ) { 599 599 // inferParameters = (*inferParameters)[ id ].inferParams.get(); … … 608 608 // } 609 609 610 /// Unique identifier for matching expression resolutions to their requesting expression 611 UniqueId globalResnSlot = 0; 612 610 613 template< typename OutputIterator > 611 void AlternativeFinder::Finder::inferParameters( const AssertionSet &, AssertionSet &, const Alternative &newAlt, OpenVarSet &, OutputIterator out ) {614 void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) { 612 615 // SymTab::Indexer decls( indexer ); 613 616 // addToIndexer( have, decls ); … … 621 624 // inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out ); 622 625 623 // add to output list, assertion resolution is defered 626 // Set need bindings for any unbound assertions 627 UniqueId crntResnSlot = 0; // matching ID for this expression's assertions 628 for ( auto& assn : newAlt.need ) { 629 // skip already-matched assertions 630 if ( assn.info.resnSlot != 0 ) continue; 631 // assign slot for expression if needed 632 if ( crntResnSlot == 0 ) { crntResnSlot = ++globalResnSlot; } 633 // fix slot to assertion 634 assn.info.resnSlot = crntResnSlot; 635 } 636 // pair slot to expression 637 if ( crntResnSlot != 0 ) { newAlt.expr->resnSlots.push_back( crntResnSlot ); } 638 639 // add to output list, assertion resolution is deferred 624 640 *out++ = newAlt; 625 641 } … … 969 985 printAssertionSet( result.need, std::cerr, 8 ); 970 986 ) 971 inferParameters( result.need, result.have, newAlt, result.openVars, out );987 inferParameters( newAlt, out ); 972 988 } 973 989 … … 1330 1346 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1331 1347 alt.env, openVars, needAssertions, alt.cost, thisCost }; 1332 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1333 back_inserter( candidates ) ); 1348 inferParameters( newAlt, back_inserter( candidates ) ); 1334 1349 } // if 1335 1350 } // for … … 1639 1654 newExpr, std::move(compositeEnv), std::move(openVars), 1640 1655 AssertionList( need.begin(), need.end() ), cost }; 1641 inferParameters( ne ed, have, newAlt, openVars, back_inserter( alternatives ) );1656 inferParameters( newAlt, back_inserter( alternatives ) ); 1642 1657 } // if 1643 1658 } // for … … 1686 1701 newExpr, std::move(compositeEnv), std::move(openVars), 1687 1702 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1688 inferParameters( ne ed, have, newAlt, openVars, back_inserter( alternatives ) );1703 inferParameters( newAlt, back_inserter( alternatives ) ); 1689 1704 } // if 1690 1705 } // for … … 1814 1829 std::move(newEnv), std::move(openVars), 1815 1830 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1816 inferParameters( ne ed, have, newAlt, openVars, back_inserter( candidates ) );1831 inferParameters( newAlt, back_inserter( candidates ) ); 1817 1832 } 1818 1833 } -
src/ResolvExpr/ResolveAssertions.cc
r2fd9f24 r0b00df0 18 18 #include <cassert> // for assertf 19 19 #include <list> // for list 20 #include <unordered_map> // for unordered_map 20 #include <unordered_map> // for unordered_map, unordered_multimap 21 21 #include <utility> // for move 22 22 #include <vector> // for vector 23 23 24 #include "Alternative.h" // for Alternative, AssertionItem 24 #include "Alternative.h" // for Alternative, AssertionItem, AssertionList 25 25 #include "Common/FilterCombos.h" // for filterCombos 26 26 #include "Common/utility.h" // for sort_mins 27 27 #include "SymTab/Indexer.h" // for Indexer 28 #include "SynTree/Expression.h" // for InferredParams 28 29 #include "TypeEnvironment.h" // for TypeEnvironment, etc. 29 30 #include "typeops.h" // for adjustExprType … … 39 40 AssertionSet need; ///< Post-unification need-set 40 41 OpenVarSet openVars; ///< Post-unification open-var set 42 UniqueId resnSlot; ///< Slot for any recursive assertion IDs 41 43 42 44 AssnCandidate( const SymTab::Indexer::IdData& cdata, Type* adjType, TypeEnvironment&& env, 43 AssertionSet&& have, AssertionSet&& need, OpenVarSet&& openVars )45 AssertionSet&& have, AssertionSet&& need, OpenVarSet&& openVars, UniqueId resnSlot ) 44 46 : cdata(cdata), adjType(adjType), env(std::move(env)), have(std::move(have)), 45 need(std::move(need)), openVars(std::move(openVars)) {}47 need(std::move(need)), openVars(std::move(openVars)), resnSlot(resnSlot) {} 46 48 }; 47 49 … … 159 161 }; 160 162 163 /// Set of assertion resolutions, grouped by resolution ID 164 using InferCache = std::unordered_map< UniqueId, InferredParams >; 165 161 166 /// Flag for state iteration 162 167 enum IterateFlag { IterateState }; … … 164 169 /// State needed to resolve a set of assertions 165 170 struct ResnState { 166 Alternative alt; ///< Alternative assertion is rooted on 167 std::vector<AssertionItem> need; ///< Assertions to find 168 AssertionSet newNeed; ///< New assertions for current resolutions 169 DeferList deferred; ///< Deferred matches 170 SymTab::Indexer& indexer; ///< Name lookup (depends on previous assertions) 171 Alternative alt; ///< Alternative assertion is rooted on 172 AssertionList need; ///< Assertions to find 173 AssertionSet newNeed; ///< New assertions for current resolutions 174 DeferList deferred; ///< Deferred matches 175 InferCache inferred; ///< Cache of already-inferred parameters 176 SymTab::Indexer& indexer; ///< Name lookup (depends on previous assertions) 171 177 172 178 /// Initial resolution state for an alternative 173 179 ResnState( Alternative& a, SymTab::Indexer& indexer ) 174 : alt(a), need(), newNeed(), deferred(), in dexer(indexer) {180 : alt(a), need(), newNeed(), deferred(), inferred(), indexer(indexer) { 175 181 need.swap( a.need ); 176 182 } … … 179 185 ResnState( ResnState&& o, IterateFlag ) 180 186 : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(), 181 in dexer(o.indexer) {}187 inferred(std::move(o.inferred)), indexer(o.indexer) {} 182 188 }; 183 189 184 190 /// Binds a single assertion, updating resolution state 185 191 void bindAssertion( const DeclarationWithType* decl, AssertionSetValue info, Alternative& alt, 186 AssnCandidate& match ) {192 AssnCandidate& match, InferCache& inferred ) { 187 193 188 194 DeclarationWithType* candidate = match.cdata.id; … … 192 198 delete varExpr->result; 193 199 varExpr->result = match.adjType->clone(); 194 195 // follow the current assertion's ID chain to find the correct set of inferred parameters 196 // to add the candidate o (i.e. the set of inferred parameters belonging to the entity 197 // which requested the assertion parameter) 198 InferredParams* inferParams = &alt.expr->inferParams; 199 for ( UniqueId id : info.idChain ) { 200 inferParams = (*inferParams)[ id ].inferParams.get(); 201 } 202 203 (*inferParams)[ decl->get_uniqueId() ] = ParamEntry{ 200 if ( match.resnSlot ) { varExpr->resnSlots.push_back( match.resnSlot ); } 201 202 // place newly-inferred assertion in proper place in cache 203 inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{ 204 204 candidate->get_uniqueId(), match.adjType, decl->get_type()->clone(), varExpr }; 205 206 // // follow the current assertion's ID chain to find the correct set of inferred parameters 207 // // to add the candidate o (i.e. the set of inferred parameters belonging to the entity 208 // // which requested the assertion parameter) 209 // InferredParams* inferParams = &alt.expr->inferParams; 210 // for ( UniqueId id : info.idChain ) { 211 // inferParams = (*inferParams)[ id ].inferParams.get(); 212 // } 213 214 // (*inferParams)[ decl->get_uniqueId() ] = ParamEntry{ 215 // candidate->get_uniqueId(), match.adjType, decl->get_type()->clone(), varExpr }; 205 216 } 206 217 … … 214 225 } 215 226 227 // in AlternativeFinder.cc; unique ID for assertion resolutions 228 extern UniqueId globalResnSlot; 229 216 230 /// Resolve a single assertion, in context 217 231 bool resolveAssertion( AssertionItem& assn, ResnState& resn ) { … … 238 252 if ( unify( assn.decl->get_type(), adjType, newEnv, newNeed, have, newOpenVars, 239 253 resn.indexer ) ) { 240 // set up idChain on new assertions 241 for ( auto& a : newNeed ) { 242 a.second.idChain = assn.info.idChain; 243 a.second.idChain.push_back( assn.decl->get_uniqueId() ); 254 // set up binding slot for recursive assertions 255 UniqueId crntResnSlot = 0; 256 if ( ! newNeed.empty() ) { 257 crntResnSlot = ++globalResnSlot; 258 for ( auto& a : newNeed ) { 259 a.second.resnSlot = crntResnSlot; 260 } 244 261 } 262 // // set up idChain on new assertions 263 // for ( auto& a : newNeed ) { 264 // a.second.idChain = assn.info.idChain; 265 // a.second.idChain.push_back( assn.decl->get_uniqueId() ); 266 // } 245 267 246 268 matches.emplace_back( cdata, adjType, std::move(newEnv), std::move(have), 247 std::move(newNeed), std::move(newOpenVars) );269 std::move(newNeed), std::move(newOpenVars), crntResnSlot ); 248 270 } else { 249 271 delete adjType; … … 267 289 resn.alt.openVars = std::move(match.openVars); 268 290 269 bindAssertion( assn.decl, assn.info, resn.alt, match );291 bindAssertion( assn.decl, assn.info, resn.alt, match, resn.inferred ); 270 292 return true; 271 293 } 272 294 273 ///< Limit to depth of recursion of assertion satisfaction 295 /// Associates inferred parameters with an expression 296 struct InferMatcher { 297 InferCache& inferred; 298 299 InferMatcher( InferCache& inferred ) : inferred( inferred ) {} 300 301 Expression* postmutate( Expression* expr ) { 302 // place inferred parameters into resolution slots 303 for ( UniqueId slot : expr->resnSlots ) { 304 // fail if no matching parameters found 305 InferredParams& inferParams = inferred.at( slot ); 306 307 // place inferred parameters into proper place in expression 308 for ( auto& entry : inferParams ) { 309 // recurse on inferParams of resolved expressions 310 entry.second.expr = postmutate( entry.second.expr ); 311 // xxx - look at entry.second.inferParams? 312 expr->inferParams[ entry.first ] = entry.second; 313 } 314 } 315 316 // clear resolution slots and return 317 expr->resnSlots.clear(); 318 return expr; 319 } 320 }; 321 322 void finalizeAssertions( Alternative& alt, InferCache& inferred, AltList& out ) { 323 PassVisitor<InferMatcher> matcher{ inferred }; 324 alt.expr = alt.expr->acceptMutator( matcher ); 325 out.emplace_back( alt ); 326 } 327 328 /// Limit to depth of recursion of assertion satisfaction 274 329 static const int recursionLimit = /* 10 */ 4; 275 330 … … 300 355 // either add successful match or push back next state 301 356 if ( resn.newNeed.empty() ) { 302 out.emplace_back( resn.alt );357 finalizeAssertions( resn.alt, resn.inferred, out ); 303 358 } else { 304 359 new_resns.emplace_back( std::move(resn), IterateState ); … … 322 377 new_resn.newNeed.insert( match.need.begin(), match.need.end() ); 323 378 324 bindAssertion( r.decl, r.info, new_resn.alt, match );379 bindAssertion( r.decl, r.info, new_resn.alt, match, new_resn.inferred ); 325 380 } 326 381 … … 331 386 // either add sucessful match or push back next state 332 387 if ( new_resn.newNeed.empty() ) { 333 out.emplace_back( new_resn.alt );388 finalizeAssertions( new_resn.alt, new_resn.inferred, out ); 334 389 } else { 335 390 new_resns.emplace_back( std::move(new_resn), IterateState ); -
src/ResolvExpr/TypeEnvironment.h
r2fd9f24 r0b00df0 59 59 }; 60 60 struct AssertionSetValue { 61 bool isUsed; 62 // chain of Unique IDs of the assertion declarations. The first ID in the chain is the ID 63 // of an assertion on the current type, with each successive ID being the ID of an 64 // assertion pulled in by the previous ID. The last ID in the chain is the ID of the 65 // assertion that pulled in the current assertion. 66 std::list< UniqueId > idChain; 61 bool isUsed; ///< True if assertion needs to be resolved 62 UniqueId resnSlot; ///< ID of slot assertion belongs to 63 64 AssertionSetValue() : isUsed(false), resnSlot(0) {} 67 65 }; 68 66 typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet;
Note: See TracChangeset
for help on using the changeset viewer.