Changeset 3f7e12cb for src/GenPoly/Specialize.cc
- Timestamp:
- Nov 8, 2017, 5:43:33 PM (8 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:
- 954908d
- Parents:
- 78315272 (diff), e35f30a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Specialize.cc
r78315272 r3f7e12cb 22 22 #include <utility> // for pair 23 23 24 #include "Common/PassVisitor.h" 24 25 #include "Common/SemanticError.h" // for SemanticError 25 26 #include "Common/UniqueName.h" // for UniqueName … … 28 29 #include "InitTweak/InitTweak.h" // for isIntrinsicCallExpr 29 30 #include "Parser/LinkageSpec.h" // for C 30 #include "PolyMutator.h" // for PolyMutator31 31 #include "ResolvExpr/FindOpenVars.h" // for findOpenVars 32 32 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet … … 43 43 44 44 namespace GenPoly { 45 class Specialize final : public PolyMutator { 46 public: 47 using PolyMutator::mutate; 48 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override; 49 virtual Expression * mutate( AddressExpr *castExpr ) override; 50 virtual Expression * mutate( CastExpr *castExpr ) override; 51 // virtual Expression * mutate( LogicalExpr *logicalExpr ); 52 // virtual Expression * mutate( ConditionalExpr *conditionalExpr ); 53 // virtual Expression * mutate( CommaExpr *commaExpr ); 45 struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 46 Expression * postmutate( ApplicationExpr *applicationExpr ); 47 Expression * postmutate( CastExpr *castExpr ); 54 48 55 49 void handleExplicitParams( ApplicationExpr *appExpr ); 56 50 Expression * createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ); 57 Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = nullptr);51 Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ); 58 52 59 53 std::string paramPrefix = "_p"; … … 72 66 if ( ! boundType ) continue; 73 67 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) { 68 // bound to another type variable 74 69 if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) { 70 // bound to a closed variable => must specialize 75 71 return true; 76 72 } // if 77 73 } else { 74 // variable is bound to a concrete type => must specialize 78 75 return true; 79 76 } // if 80 77 } // for 78 // none of the type variables are bound 81 79 return false; 82 80 } else { 81 // no env 83 82 return false; 84 83 } // if … … 136 135 if ( functionParameterSize( fftype ) != functionParameterSize( aftype ) ) return false; 137 136 // tuple-parameter sizes are the same, but actual parameter sizes differ - must tuple specialize 138 if ( fftype-> get_parameters().size() != aftype->get_parameters().size() ) return true;137 if ( fftype->parameters.size() != aftype->parameters.size() ) return true; 139 138 // total parameter size can be the same, while individual parameters can have different structure 140 for ( auto params : group_iterate( fftype-> get_parameters(), aftype->get_parameters()) ) {139 for ( auto params : group_iterate( fftype->parameters, aftype->parameters ) ) { 141 140 DeclarationWithType * formal = std::get<0>(params); 142 141 DeclarationWithType * actual = std::get<1>(params); … … 152 151 153 152 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 154 assertf( actual-> has_result(), "attempting to specialize an untyped expression" );153 assertf( actual->result, "attempting to specialize an untyped expression" ); 155 154 if ( needsSpecialization( formalType, actual->get_result(), env ) ) { 156 155 if ( FunctionType *funType = getFunctionType( formalType ) ) { 157 ApplicationExpr *appExpr; 158 VariableExpr *varExpr; 159 if ( ( appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) ) { 156 if ( ApplicationExpr * appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) { 160 157 return createThunkFunction( funType, appExpr->get_function(), inferParams ); 161 } else if ( ( varExpr = dynamic_cast<VariableExpr*>( actual )) ) {158 } else if ( VariableExpr * varExpr = dynamic_cast<VariableExpr*>( actual ) ) { 162 159 return createThunkFunction( funType, varExpr, inferParams ); 163 160 } else { … … 204 201 } 205 202 206 struct EnvTrimmer : public Visitor{203 struct EnvTrimmer { 207 204 TypeSubstitution * env, * newEnv; 208 205 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 209 v irtual voidvisit( TypeDecl * tyDecl ) {206 void previsit( TypeDecl * tyDecl ) { 210 207 // transfer known bindings for seen type variables 211 if ( Type * t = env->lookup( tyDecl-> get_name()) ) {212 newEnv->add( tyDecl-> get_name(), t );208 if ( Type * t = env->lookup( tyDecl->name ) ) { 209 newEnv->add( tyDecl->name, t ); 213 210 } 214 211 } … … 219 216 if ( env ) { 220 217 TypeSubstitution * newEnv = new TypeSubstitution(); 221 EnvTrimmertrimmer( env, newEnv );218 PassVisitor<EnvTrimmer> trimmer( env, newEnv ); 222 219 expr->accept( trimmer ); 223 220 return newEnv; … … 277 274 std::string oldParamPrefix = paramPrefix; 278 275 paramPrefix += "p"; 279 // save stmtsToAdd in oldStmts276 // save stmtsToAddBefore in oldStmts 280 277 std::list< Statement* > oldStmts; 281 oldStmts.splice( oldStmts.end(), stmtsToAdd );282 mutate( appExpr );278 oldStmts.splice( oldStmts.end(), stmtsToAddBefore ); 279 appExpr->acceptMutator( *visitor ); 283 280 paramPrefix = oldParamPrefix; 284 281 // write any statements added for recursive specializations into the thunk body 285 thunkFunc-> get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd);286 // restore oldStmts into stmtsToAdd 287 stmtsToAdd .splice( stmtsToAdd.end(), oldStmts );282 thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore ); 283 // restore oldStmts into stmtsToAddBefore 284 stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts ); 288 285 289 286 // add return (or valueless expression) to the thunk 290 287 Statement *appStmt; 291 if ( funType-> get_returnVals().empty() ) {288 if ( funType->returnVals.empty() ) { 292 289 appStmt = new ExprStmt( noLabels, appExpr ); 293 290 } else { 294 291 appStmt = new ReturnStmt( noLabels, appExpr ); 295 292 } // if 296 thunkFunc-> get_statements()->get_kids().push_back( appStmt );293 thunkFunc->statements->kids.push_back( appStmt ); 297 294 298 295 // add thunk definition to queue of statements to add 299 stmtsToAdd .push_back( new DeclStmt( noLabels, thunkFunc ) );296 stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) ); 300 297 // return address of thunk function as replacement expression 301 298 return new AddressExpr( new VariableExpr( thunkFunc ) ); … … 304 301 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 305 302 // create thunks for the explicit parameters 306 assert( appExpr-> get_function()->has_result());307 FunctionType *function = getFunctionType( appExpr-> get_function()->get_result());303 assert( appExpr->function->result ); 304 FunctionType *function = getFunctionType( appExpr->function->result ); 308 305 assert( function ); 309 306 std::list< DeclarationWithType* >::iterator formal; 310 307 std::list< Expression* >::iterator actual; 311 308 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 312 *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() ); 313 } 314 } 315 316 Expression * Specialize::mutate( ApplicationExpr *appExpr ) { 317 appExpr->get_function()->acceptMutator( *this ); 318 mutateAll( appExpr->get_args(), *this ); 319 309 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() ); 310 } 311 } 312 313 Expression * Specialize::postmutate( ApplicationExpr *appExpr ) { 320 314 if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) { 321 315 // create thunks for the inferred parameters … … 331 325 } 332 326 333 Expression * Specialize::mutate( AddressExpr *addrExpr ) { 334 addrExpr->get_arg()->acceptMutator( *this ); 335 assert( addrExpr->has_result() ); 336 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) ); 337 return addrExpr; 338 } 339 340 Expression * Specialize::mutate( CastExpr *castExpr ) { 341 castExpr->get_arg()->acceptMutator( *this ); 342 if ( castExpr->get_result()->isVoid() ) { 327 Expression * Specialize::postmutate( CastExpr *castExpr ) { 328 if ( castExpr->result->isVoid() ) { 343 329 // can't specialize if we don't have a return value 344 330 return castExpr; 345 331 } 346 Expression *specialized = doSpecialization( castExpr-> get_result(), castExpr->get_arg());347 if ( specialized != castExpr-> get_arg()) {332 Expression *specialized = doSpecialization( castExpr->result, castExpr->arg, &castExpr->inferParams ); 333 if ( specialized != castExpr->arg ) { 348 334 // assume here that the specialization incorporates the cast 349 335 return specialized; … … 353 339 } 354 340 355 // Removing these for now. Richard put these in for some reason, but it's not clear why.356 // In particular, copy constructors produce a comma expression, and with this code the parts357 // of that comma expression are not specialized, which causes problems.358 359 // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {360 // return logicalExpr;361 // }362 363 // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {364 // return condExpr;365 // }366 367 // Expression * Specialize::mutate( CommaExpr *commaExpr ) {368 // return commaExpr;369 // }370 371 341 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 372 Specializespec;342 PassVisitor<Specialize> spec; 373 343 mutateAll( translationUnit, spec ); 374 344 }
Note:
See TracChangeset
for help on using the changeset viewer.