Changeset 698664b
- Timestamp:
- Oct 28, 2015, 3:41:07 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- d2ded3e7
- Parents:
- f6835e5
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rf6835e5 r698664b 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() );416 assert( inferParam != appExpr->get_inferParams().end() && "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" ); 417 417 Expression *newExpr = inferParam->second.expr->clone(); 418 418 addCast( newExpr, (*assert)->get_type(), tyVars ); -
src/GenPoly/Specialize.cc
rf6835e5 r698664b 45 45 46 46 private: 47 Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams = 0 ); 47 48 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 48 49 void handleExplicitParams( ApplicationExpr *appExpr ); … … 61 62 } 62 63 64 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type. 63 65 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 64 66 if ( env ) { … … 85 87 } 86 88 89 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 90 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 otherwise 94 } else { 95 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise 96 } 97 } 98 99 /// Generates a thunk that calls `actual` with type `funType` and returns its address 100 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 the 105 // thunk's type 106 newEnv.applyFree( newType ); 107 } // if 108 // 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 go 113 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 } // for 119 appExpr->set_env( maybeClone( env ) ); 120 if ( inferParams ) { 121 appExpr->get_inferParams() = *inferParams; 122 } // if 123 124 // handle any specializations that may still be present 125 std::string oldParamPrefix = paramPrefix; 126 paramPrefix += "p"; 127 // save stmtsToAdd in oldStmts 128 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 body 133 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 134 // restore oldStmts into stmtsToAdd 135 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 136 137 // add return (or valueless expression) to the thunk 138 Statement *appStmt; 139 if ( funType->get_returnVals().empty() ) { 140 appStmt = new ExprStmt( noLabels, appExpr ); 141 } else { 142 appStmt = new ReturnStmt( noLabels, appExpr ); 143 } // if 144 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 145 146 // add thunk definition to queue of statements to add 147 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 148 // return address of thunk function as replacement expression 149 return new AddressExpr( new VariableExpr( thunkFunc ) ); 150 } 151 87 152 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 88 153 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 89 PointerType *ptrType;90 154 FunctionType *funType; 91 if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) { 92 FunctionType *newType = funType->clone(); 93 if ( env ) { 94 TypeSubstitution newEnv( *env ); 95 // it is important to replace only occurrences of type variables that occur free in the 96 // thunk's type 97 newEnv.applyFree( newType ); 98 } // if 99 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false, false ); 100 thunkFunc->fixUniqueId(); 101 102 UniqueName paramNamer( paramPrefix ); 103 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 104 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) { 105 (*param )->set_name( paramNamer.newName() ); 106 appExpr->get_args().push_back( new VariableExpr( *param ) ); 107 } // for 108 appExpr->set_env( maybeClone( env ) ); 109 if ( inferParams ) { 110 appExpr->get_inferParams() = *inferParams; 111 } // if 112 113 // handle any specializations that may still be present 114 std::string oldParamPrefix = paramPrefix; 115 paramPrefix += "p"; 116 std::list< Statement* > oldStmts; 117 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 118 handleExplicitParams( appExpr ); 119 paramPrefix = oldParamPrefix; 120 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 121 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 122 123 Statement *appStmt; 124 if ( funType->get_returnVals().empty() ) { 125 appStmt = new ExprStmt( noLabels, appExpr ); 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 ); 126 162 } else { 127 appStmt = new ReturnStmt( noLabels, appExpr ); 128 } // if 129 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 130 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 131 return new AddressExpr( new VariableExpr( thunkFunc ) ); 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 } 132 166 } else { 133 167 return actual; … … 141 175 // create thunks for the explicit parameters 142 176 assert( ! appExpr->get_function()->get_results().empty() ); 143 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 144 assert( pointer ); 145 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 177 FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() ); 178 assert( function ); 146 179 std::list< DeclarationWithType* >::iterator formal; 147 180 std::list< Expression* >::iterator actual; … … 173 206 Expression * Specialize::mutate( CastExpr *castExpr ) { 174 207 castExpr->get_arg()->acceptMutator( *this ); 175 castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) ); 176 return castExpr; 208 Expression *specialized = doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ); 209 if ( specialized != castExpr->get_arg() ) { 210 // assume here that the specialization incorporates the cast 211 return specialized; 212 } else { 213 return castExpr; 214 } 177 215 } 178 216 -
src/main.cc
rf6835e5 r698664b 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.