Changes in / [ba407ce:50eac1b]
- Location:
- src
- Files:
-
- 5 edited
-
GenPoly/Box.cc (modified) (1 diff)
-
GenPoly/Specialize.cc (modified) (5 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
SynTree/Type.h (modified) (4 diffs)
-
main.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rba407ce r50eac1b 414 414 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 415 415 InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() ); 416 assert( inferParam != appExpr->get_inferParams().end() && "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported");416 assert( inferParam != appExpr->get_inferParams().end() ); 417 417 Expression *newExpr = inferParam->second.expr->clone(); 418 418 addCast( newExpr, (*assert)->get_type(), tyVars ); -
src/GenPoly/Specialize.cc
rba407ce r50eac1b 45 45 46 46 private: 47 Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams = 0 );48 47 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 49 48 void handleExplicitParams( ApplicationExpr *appExpr ); … … 62 61 } 63 62 64 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.65 63 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 66 64 if ( env ) { … … 87 85 } 88 86 89 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise90 FunctionType * getFunctionType( Type *ty ) {91 PointerType *ptrType;92 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {93 return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise94 } else {95 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise96 }97 }98 99 /// Generates a thunk that calls `actual` with type `funType` and returns its address100 Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {101 FunctionType *newType = funType->clone();102 if ( env ) {103 TypeSubstitution newEnv( *env );104 // it is important to replace only occurrences of type variables that occur free in the105 // thunk's type106 newEnv.applyFree( newType );107 } // if108 // create new thunk with same signature as formal type (C linkage, empty body)109 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false, false );110 thunkFunc->fixUniqueId();111 112 // thread thunk parameters into call to actual function, naming thunk parameters as we go113 UniqueName paramNamer( paramPrefix );114 ApplicationExpr *appExpr = new ApplicationExpr( actual );115 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {116 (*param )->set_name( paramNamer.newName() );117 appExpr->get_args().push_back( new VariableExpr( *param ) );118 } // for119 appExpr->set_env( maybeClone( env ) );120 if ( inferParams ) {121 appExpr->get_inferParams() = *inferParams;122 } // if123 124 // handle any specializations that may still be present125 std::string oldParamPrefix = paramPrefix;126 paramPrefix += "p";127 // save stmtsToAdd in oldStmts128 std::list< Statement* > oldStmts;129 oldStmts.splice( oldStmts.end(), stmtsToAdd );130 handleExplicitParams( appExpr );131 paramPrefix = oldParamPrefix;132 // write any statements added for recursive specializations into the thunk body133 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );134 // restore oldStmts into stmtsToAdd135 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );136 137 // add return (or valueless expression) to the thunk138 Statement *appStmt;139 if ( funType->get_returnVals().empty() ) {140 appStmt = new ExprStmt( noLabels, appExpr );141 } else {142 appStmt = new ReturnStmt( noLabels, appExpr );143 } // if144 thunkFunc->get_statements()->get_kids().push_back( appStmt );145 146 // add thunk definition to queue of statements to add147 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );148 // return address of thunk function as replacement expression149 return new AddressExpr( new VariableExpr( thunkFunc ) );150 }151 152 87 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 88 assert( ! actual->get_results().empty() ); 153 89 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 90 PointerType *ptrType; 154 91 FunctionType *funType; 155 if ( ( funType = getFunctionType( formalType ) ) ) { 156 ApplicationExpr *appExpr; 157 VariableExpr *varExpr; 158 if ( ( appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) ) { 159 return createThunkFunction( funType, appExpr->get_function(), inferParams ); 160 } else if ( ( varExpr = dynamic_cast<VariableExpr*>( actual ) ) ) { 161 return createThunkFunction( funType, varExpr, inferParams ); 92 if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) { 93 FunctionType *newType = funType->clone(); 94 if ( env ) { 95 TypeSubstitution newEnv( *env ); 96 // it is important to replace only occurrences of type variables that occur free in the 97 // thunk's type 98 newEnv.applyFree( newType ); 99 } // if 100 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false, false ); 101 thunkFunc->fixUniqueId(); 102 103 UniqueName paramNamer( paramPrefix ); 104 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 105 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) { 106 (*param )->set_name( paramNamer.newName() ); 107 appExpr->get_args().push_back( new VariableExpr( *param ) ); 108 } // for 109 appExpr->set_env( maybeClone( env ) ); 110 if ( inferParams ) { 111 appExpr->get_inferParams() = *inferParams; 112 } // if 113 114 // handle any specializations that may still be present 115 std::string oldParamPrefix = paramPrefix; 116 paramPrefix += "p"; 117 std::list< Statement* > oldStmts; 118 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 119 handleExplicitParams( appExpr ); 120 paramPrefix = oldParamPrefix; 121 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 122 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 123 124 Statement *appStmt; 125 if ( funType->get_returnVals().empty() ) { 126 appStmt = new ExprStmt( noLabels, appExpr ); 162 127 } else { 163 // This likely won't work, as anything that could build an ApplicationExpr probably hit one of the previous two branches 164 return createThunkFunction( funType, actual, inferParams ); 165 } 128 appStmt = new ReturnStmt( noLabels, appExpr ); 129 } // if 130 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 131 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 132 return new AddressExpr( new VariableExpr( thunkFunc ) ); 166 133 } else { 167 134 return actual; … … 175 142 // create thunks for the explicit parameters 176 143 assert( ! appExpr->get_function()->get_results().empty() ); 177 FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() ); 178 assert( function ); 144 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 145 assert( pointer ); 146 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 179 147 std::list< DeclarationWithType* >::iterator formal; 180 148 std::list< Expression* >::iterator actual; … … 207 175 Expression * Specialize::mutate( CastExpr *castExpr ) { 208 176 castExpr->get_arg()->acceptMutator( *this ); 209 Expression *specialized = doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ); 210 if ( specialized != castExpr->get_arg() ) { 211 // assume here that the specialization incorporates the cast 212 return specialized; 213 } else { 214 return castExpr; 177 if ( ! castExpr->get_results().empty() ) { 178 // this may not be the correct condition, but previously the next statement 179 // was happening unchecked, causing a crash on a cast to void 180 castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) ); 215 181 } 182 return castExpr; 216 183 } 217 184 -
src/ResolvExpr/AlternativeFinder.cc
rba407ce r50eac1b 698 698 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 699 699 std::advance( candidate_end, castExpr->get_results().size() ); 700 // unification run for side-effects701 unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),702 (*i).expr->get_results().begin(), candidate_end,703 i->env, needAssertions, haveAssertions, openVars, indexer );704 700 Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end, 705 castExpr->get_results().begin(), castExpr->get_results().end(), 706 indexer, i->env ); 701 castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env ); 707 702 if ( thisCost != Cost::infinity ) { 708 703 // count one safe conversion for each value that is thrown away -
src/SynTree/Type.h
rba407ce r50eac1b 418 418 return isConst == other.isConst 419 419 && isVolatile == other.isVolatile 420 //&& isRestrict == other.isRestrict421 // && isLvalue == other.isLvalue420 && isRestrict == other.isRestrict 421 // && isLvalue == other.isLvalue 422 422 && isAtomic == other.isAtomic; 423 423 } … … 426 426 return isConst != other.isConst 427 427 || isVolatile != other.isVolatile 428 //|| isRestrict != other.isRestrict429 // || isLvalue != other.isLvalue428 || isRestrict != other.isRestrict 429 // || isLvalue != other.isLvalue 430 430 || isAtomic != other.isAtomic; 431 431 } … … 434 434 return isConst <= other.isConst 435 435 && isVolatile <= other.isVolatile 436 //&& isRestrict <= other.isRestrict437 // && isLvalue >= other.isLvalue436 && isRestrict <= other.isRestrict 437 // && isLvalue >= other.isLvalue 438 438 && isAtomic == other.isAtomic; 439 439 } … … 442 442 return isConst >= other.isConst 443 443 && isVolatile >= other.isVolatile 444 //&& isRestrict >= other.isRestrict445 // && isLvalue <= other.isLvalue444 && isRestrict >= other.isRestrict 445 // && isLvalue <= other.isLvalue 446 446 && isAtomic == other.isAtomic; 447 447 } -
src/main.cc
rba407ce r50eac1b 271 271 GenPoly::copyParams( translationUnit ); 272 272 OPTPRINT( "convertSpecializations" ) 273 GenPoly::convertSpecializations( translationUnit ); 273 GenPoly::convertSpecializations( translationUnit ); 274 274 OPTPRINT( "convertLvalue" ) 275 275 GenPoly::convertLvalue( translationUnit );
Note:
See TracChangeset
for help on using the changeset viewer.