Changeset ddf8a29 for src/ResolvExpr/AlternativeFinder.cc
- Timestamp:
- Aug 25, 2017, 10:47:38 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- f676b84
- Parents:
- c315863
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rc315863 rddf8a29 286 286 } 287 287 288 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 288 Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 289 PRINT( 290 std::cerr << std::endl << "converting "; 291 actualType->print( std::cerr, 8 ); 292 std::cerr << std::endl << " to "; 293 formalType->print( std::cerr, 8 ); 294 std::cerr << std::endl << "environment is: "; 295 env.print( std::cerr, 8 ); 296 std::cerr << std::endl; 297 ) 298 Cost convCost = conversionCost( actualType, formalType, indexer, env ); 299 PRINT( 300 std::cerr << std::endl << "cost is" << convCost << std::endl; 301 ) 302 if ( convCost == Cost::infinity ) { 303 return convCost; 304 } 305 convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) ); 306 return convCost; 307 } 308 309 Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 310 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env ); 311 // if ( convCost != Cost::zero ) { 312 313 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize 314 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the 315 // previous line. 316 Cost tmpCost = convCost; 317 tmpCost.incPoly( -tmpCost.get_polyCost() ); 318 if ( tmpCost != Cost::zero ) { 319 Type *newType = formalType->clone(); 320 env.apply( newType ); 321 actualExpr = new CastExpr( actualExpr, newType ); 322 // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly 323 // inconsistent, once this is fixed it should be possible to resolve the cast. 324 // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing. 325 326 // AlternativeFinder finder( indexer, env ); 327 // finder.findWithAdjustment( actualExpr ); 328 // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." ); 329 // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." ); 330 // Alternative & alt = finder.get_alternatives().front(); 331 // delete actualExpr; 332 // actualExpr = alt.expr->clone(); 333 } 334 return convCost; 335 } 336 337 Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 289 338 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr ); 290 339 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); … … 304 353 actualType->print( std::cerr, 8 ); 305 354 ) 306 Cost actualCost = Cost::zero;307 355 if ( formal == formals.end() ) { 308 356 if ( function->get_isVarArgs() ) { … … 325 373 std::cerr << std::endl; 326 374 ) 327 Cost newCost = conversionCost( actualType, formalType, indexer, alt.env ); 328 PRINT( 329 std::cerr << std::endl << "cost is" << newCost << std::endl; 330 ) 331 332 if ( newCost == Cost::infinity ) { 333 return newCost; 334 } 335 convCost += newCost; 336 actualCost += newCost; 337 if ( actualCost != Cost::zero ) { 338 Type *newType = formalType->clone(); 339 alt.env.apply( newType ); 340 *actualExpr = new CastExpr( *actualExpr, newType ); 341 } 342 convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) ); 375 convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env ); 343 376 ++formal; // can't be in for-loop update because of the continue 344 377 } … … 348 381 349 382 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 350 PRINT( 351 std::cerr << std::endl << "converting "; 352 assert->second.actualType->print( std::cerr, 8 ); 353 std::cerr << std::endl << " to "; 354 assert->second.formalType->print( std::cerr, 8 ); 355 ) 356 Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 357 PRINT( 358 std::cerr << std::endl << "cost of conversion is " << newCost << std::endl; 359 ) 360 if ( newCost == Cost::infinity ) { 361 return newCost; 362 } 363 convCost += newCost; 364 convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) ); 383 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 365 384 } 366 385 … … 776 795 // compute conversionsion costs 777 796 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { 778 Cost cvtCost = compute ConversionCost( *withFunc, indexer );797 Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer ); 779 798 780 799 PRINT( … … 895 914 // count one safe conversion for each value that is thrown away 896 915 thisCost.incSafe( discardedValues ); 897 898 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); 916 Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ); 917 // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative. 918 // Once this works, it should be possible to infer parameters on a cast expression and specialize any function. 919 920 // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 921 candidates.emplace_back( std::move( newAlt ) ); 899 922 } // if 900 923 } // for … … 1139 1162 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() ); 1140 1163 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 1164 // convert both options to the conditional result type 1165 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env ); 1166 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env ); 1141 1167 newAlt.expr = newExpr; 1142 1168 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
Note: See TracChangeset
for help on using the changeset viewer.