- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rddf8a29 r5ccb10d 14 14 // 15 15 16 #include <algorithm> // for copy 17 #include <cassert> // for safe_dynamic_cast, assert, assertf 18 #include <iostream> // for operator<<, cerr, ostream, endl 19 #include <iterator> // for back_insert_iterator, back_inserter 20 #include <list> // for _List_iterator, list, _List_const_... 21 #include <map> // for _Rb_tree_iterator, map, _Rb_tree_c... 22 #include <memory> // for allocator_traits<>::value_type 23 #include <utility> // for pair 24 25 #include "Alternative.h" // for AltList, Alternative 16 #include <list> 17 #include <iterator> 18 #include <algorithm> 19 #include <functional> 20 #include <cassert> 21 #include <unordered_map> 22 #include <utility> 23 #include <vector> 24 26 25 #include "AlternativeFinder.h" 27 #include "Common/SemanticError.h" // for SemanticError 28 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 29 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 30 #include "InitTweak/InitTweak.h" // for getFunctionName 31 #include "RenameVars.h" // for RenameVars, global_renamer 32 #include "ResolveTypeof.h" // for resolveTypeof 33 #include "Resolver.h" // for resolveStmtExpr 34 #include "SymTab/Indexer.h" // for Indexer 35 #include "SymTab/Mangler.h" // for Mangler 36 #include "SymTab/Validate.h" // for validateType 37 #include "SynTree/Constant.h" // for Constant 38 #include "SynTree/Declaration.h" // for DeclarationWithType, TypeDecl, Dec... 39 #include "SynTree/Expression.h" // for Expression, CastExpr, NameExpr 40 #include "SynTree/Initializer.h" // for SingleInit, operator<<, Designation 41 #include "SynTree/SynTree.h" // for UniqueId 42 #include "SynTree/Type.h" // for Type, FunctionType, PointerType 43 #include "Tuples/Explode.h" // for explode 44 #include "Tuples/Tuples.h" // for isTtype, handleTupleAssignment 45 #include "Unify.h" // for unify 46 #include "typeops.h" // for adjustExprType, polyCost, castCost 26 #include "Alternative.h" 27 #include "Cost.h" 28 #include "typeops.h" 29 #include "Unify.h" 30 #include "RenameVars.h" 31 #include "SynTree/Type.h" 32 #include "SynTree/Declaration.h" 33 #include "SynTree/Expression.h" 34 #include "SynTree/Initializer.h" 35 #include "SynTree/Visitor.h" 36 #include "SymTab/Indexer.h" 37 #include "SymTab/Mangler.h" 38 #include "SynTree/TypeSubstitution.h" 39 #include "SymTab/Validate.h" 40 #include "Tuples/Tuples.h" 41 #include "Tuples/Explode.h" 42 #include "Common/utility.h" 43 #include "InitTweak/InitTweak.h" 44 #include "InitTweak/GenInit.h" 45 #include "ResolveTypeof.h" 46 #include "Resolver.h" 47 47 48 48 extern bool resolvep; … … 286 286 } 287 287 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 ) { 288 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 338 289 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr ); 339 290 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); … … 353 304 actualType->print( std::cerr, 8 ); 354 305 ) 306 Cost actualCost = Cost::zero; 355 307 if ( formal == formals.end() ) { 356 308 if ( function->get_isVarArgs() ) { … … 373 325 std::cerr << std::endl; 374 326 ) 375 convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env ); 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 ) ); 376 343 ++formal; // can't be in for-loop update because of the continue 377 344 } … … 381 348 382 349 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 383 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 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 ) ); 384 365 } 385 366 … … 795 776 // compute conversionsion costs 796 777 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { 797 Cost cvtCost = compute ApplicationConversionCost( *withFunc, indexer );778 Cost cvtCost = computeConversionCost( *withFunc, indexer ); 798 779 799 780 PRINT( … … 914 895 // count one safe conversion for each value that is thrown away 915 896 thisCost.incSafe( discardedValues ); 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 ) ); 897 898 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); 922 899 } // if 923 900 } // for … … 1002 979 void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) { 1003 980 if ( sizeofExpr->get_isType() ) { 1004 Type * newType = sizeofExpr->get_type()->clone();1005 alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer )), env, Cost::zero ) );981 // xxx - resolveTypeof? 982 alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) ); 1006 983 } else { 1007 984 // find all alternatives for the argument to sizeof … … 1023 1000 void AlternativeFinder::visit( AlignofExpr *alignofExpr ) { 1024 1001 if ( alignofExpr->get_isType() ) { 1025 Type * newType = alignofExpr->get_type()->clone();1026 alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer )), env, Cost::zero ) );1002 // xxx - resolveTypeof? 1003 alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) ); 1027 1004 } else { 1028 1005 // find all alternatives for the argument to sizeof … … 1162 1139 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() ); 1163 1140 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 1164 // convert both options to the conditional result type1165 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );1166 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );1167 1141 newAlt.expr = newExpr; 1168 1142 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
Note: See TracChangeset
for help on using the changeset viewer.