Changeset d67cdb7 for src/GenPoly
- Timestamp:
- Sep 26, 2017, 11:27:38 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:
- 5dc26f5
- Parents:
- 201aeb9
- Location:
- src/GenPoly
- Files:
-
- 4 deleted
- 3 edited
-
Box.cc (modified) (28 diffs)
-
DeclMutator.cc (deleted)
-
DeclMutator.h (deleted)
-
PolyMutator.cc (deleted)
-
PolyMutator.h (deleted)
-
Specialize.cc (modified) (9 diffs)
-
module.mk (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r201aeb9 rd67cdb7 32 32 #include "Common/UniqueName.h" // for UniqueName 33 33 #include "Common/utility.h" // for toString 34 #include "DeclMutator.h" // for DeclMutator35 34 #include "FindFunction.h" // for findFunction, findAndReplace... 36 35 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_i... … … 39 38 #include "Lvalue.h" // for generalizedLvalue 40 39 #include "Parser/LinkageSpec.h" // for C, Spec, Cforall, Intrinsic 41 #include "PolyMutator.h" // for PolyMutator42 40 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass 43 41 #include "ResolvExpr/typeops.h" // for typesCompatible … … 62 60 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 61 62 class BoxPass { 63 protected: 64 BoxPass() : scopeTyVars( TypeDecl::Data{} ) {} 65 TyVarMap scopeTyVars; 66 }; 67 64 68 /// Adds layout-generation functions to polymorphic types 65 class LayoutFunctionBuilder final : public DeclMutator{66 unsigned int functionNesting ; // current level of nested functions69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting { 70 unsigned int functionNesting = 0; // current level of nested functions 67 71 public: 68 LayoutFunctionBuilder() : functionNesting( 0 ) {} 69 70 using DeclMutator::mutate; 71 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 72 virtual Declaration *mutate( StructDecl *structDecl ) override; 73 virtual Declaration *mutate( UnionDecl *unionDecl ) override; 72 void previsit( FunctionDecl *functionDecl ); 73 void previsit( StructDecl *structDecl ); 74 void previsit( UnionDecl *unionDecl ); 74 75 }; 75 76 76 77 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 77 class Pass1 final : public PolyMutator{78 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting { 78 79 public: 79 80 Pass1(); 80 81 81 using PolyMutator::mutate; 82 virtual Expression *mutate( ApplicationExpr *appExpr ) override; 83 virtual Expression *mutate( AddressExpr *addrExpr ) override; 84 virtual Expression *mutate( UntypedExpr *expr ) override; 85 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override; 86 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 87 virtual Expression *mutate( CommaExpr *commaExpr ) override; 88 virtual Expression *mutate( ConditionalExpr *condExpr ) override; 89 virtual Statement * mutate( ReturnStmt *returnStmt ) override; 90 virtual Type *mutate( PointerType *pointerType ) override; 91 virtual Type * mutate( FunctionType *functionType ) override; 92 93 virtual void doBeginScope() override; 94 virtual void doEndScope() override; 82 void premutate( FunctionDecl * functionDecl ); 83 void premutate( TypeDecl * typeDecl ); 84 void premutate( CommaExpr * commaExpr ); 85 Expression * postmutate( ApplicationExpr * appExpr ); 86 Expression * postmutate( UntypedExpr *expr ); 87 void premutate( AddressExpr * addrExpr ); 88 Expression * postmutate( AddressExpr * addrExpr ); 89 void premutate( ReturnStmt * returnStmt ); 90 void premutate( PointerType * pointerType ); 91 void premutate( FunctionType * functionType ); 92 93 void beginScope(); 94 void endScope(); 95 95 private: 96 96 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application … … 129 129 /// * Moves polymorphic returns in function types to pointer-type parameters 130 130 /// * adds type size and assertion parameters to parameter lists 131 class Pass2 final : public PolyMutator { 132 public: 133 template< typename DeclClass > 134 DeclClass *handleDecl( DeclClass *decl ); 135 template< typename AggDecl > 136 AggDecl * handleAggDecl( AggDecl * aggDecl ); 137 138 typedef PolyMutator Parent; 139 using Parent::mutate; 140 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 141 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 142 virtual StructDecl *mutate( StructDecl *structDecl ) override; 143 virtual UnionDecl *mutate( UnionDecl *unionDecl ) override; 144 virtual TraitDecl *mutate( TraitDecl *unionDecl ) override; 145 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 146 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override; 147 virtual Type *mutate( PointerType *pointerType ) override; 148 virtual Type *mutate( FunctionType *funcType ) override; 131 struct Pass2 final : public BoxPass, public WithGuards { 132 void handleAggDecl(); 133 134 DeclarationWithType * postmutate( FunctionDecl *functionDecl ); 135 void premutate( StructDecl *structDecl ); 136 void premutate( UnionDecl *unionDecl ); 137 void premutate( TraitDecl *unionDecl ); 138 void premutate( TypeDecl *typeDecl ); 139 void premutate( PointerType *pointerType ); 140 void premutate( FunctionType *funcType ); 149 141 150 142 private: … … 158 150 /// * Calculates polymorphic offsetof expressions from offset array 159 151 /// * Inserts dynamic calculation of polymorphic type layouts where needed 160 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution { 161 153 public: 162 154 PolyGenericCalculator(); … … 197 189 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 198 190 UniqueName bufNamer; ///< Namer for VLA buffers 199 TyVarMap scopeTyVars;200 191 }; 201 192 202 193 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations. 203 class Pass3 final : public PolyMutator { 204 public: 194 struct Pass3 final : public BoxPass, public WithGuards { 205 195 template< typename DeclClass > 206 DeclClass *handleDecl( DeclClass *decl, Type *type ); 207 208 using PolyMutator::mutate; 209 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 210 virtual Declaration *mutate( StructDecl *structDecl ) override; 211 virtual Declaration *mutate( UnionDecl *unionDecl ) override; 212 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 213 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override; 214 virtual TypeDecl *mutate( TypeDecl *objectDecl ) override; 215 virtual Type *mutate( PointerType *pointerType ) override; 216 virtual Type *mutate( FunctionType *funcType ) override; 217 private: 196 void handleDecl( DeclClass * decl, Type * type ); 197 198 void premutate( ObjectDecl * objectDecl ); 199 void premutate( FunctionDecl * functionDecl ); 200 void premutate( TypedefDecl * typedefDecl ); 201 void premutate( StructDecl * structDecl ); 202 void premutate( UnionDecl * unionDecl ); 203 void premutate( TypeDecl * typeDecl ); 204 void premutate( PointerType * pointerType ); 205 void premutate( FunctionType * funcType ); 218 206 }; 219 207 } // anonymous namespace … … 247 235 248 236 void box( std::list< Declaration *>& translationUnit ) { 249 LayoutFunctionBuilderlayoutBuilder;250 Pass 1pass1;251 Pass 2pass2;237 PassVisitor<LayoutFunctionBuilder> layoutBuilder; 238 PassVisitor<Pass1> pass1; 239 PassVisitor<Pass2> pass2; 252 240 PassVisitor<PolyGenericCalculator> polyCalculator; 253 Pass 3pass3;254 255 layoutBuilder.mutateDeclarationList( translationUnit);256 mutate TranslationUnit/*All*/( translationUnit, pass1 );257 mutate TranslationUnit/*All*/( translationUnit, pass2 );241 PassVisitor<Pass3> pass3; 242 243 acceptAll( translationUnit, layoutBuilder ); 244 mutateAll( translationUnit, pass1 ); 245 mutateAll( translationUnit, pass2 ); 258 246 mutateAll( translationUnit, polyCalculator ); 259 mutate TranslationUnit/*All*/( translationUnit, pass3 );247 mutateAll( translationUnit, pass3 ); 260 248 } 261 249 262 250 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 263 251 264 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) { 265 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 252 void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) { 253 visit_children = false; 254 maybeAccept( functionDecl->get_functionType(), *visitor ); 266 255 ++functionNesting; 267 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ));256 maybeAccept( functionDecl->get_statements(), *visitor ); 268 257 --functionNesting; 269 return functionDecl;270 258 } 271 259 … … 356 344 } 357 345 358 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {346 void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) { 359 347 // do not generate layout function for "empty" tag structs 360 if ( structDecl->get_members().empty() ) return structDecl; 348 visit_children = false; 349 if ( structDecl->get_members().empty() ) return; 361 350 362 351 // get parameters that can change layout, exiting early if none 363 352 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() ); 364 if ( otypeParams.empty() ) return structDecl;353 if ( otypeParams.empty() ) return; 365 354 366 355 // build layout function signature … … 413 402 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 414 403 415 addDeclarationAfter( layoutDecl ); 416 return structDecl; 404 declsToAddAfter.push_back( layoutDecl ); 417 405 } 418 406 419 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {407 void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) { 420 408 // do not generate layout function for "empty" tag unions 421 if ( unionDecl->get_members().empty() ) return unionDecl; 409 visit_children = false; 410 if ( unionDecl->get_members().empty() ) return; 422 411 423 412 // get parameters that can change layout, exiting early if none 424 413 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); 425 if ( otypeParams.empty() ) return unionDecl;414 if ( otypeParams.empty() ) return; 426 415 427 416 // build layout function signature … … 456 445 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 457 446 458 addDeclarationAfter( layoutDecl ); 459 return unionDecl; 447 declsToAddAfter.push_back( layoutDecl ); 460 448 } 461 449 … … 501 489 Pass1::Pass1() : tempNamer( "_temp" ) {} 502 490 503 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {491 void Pass1::premutate( FunctionDecl *functionDecl ) { 504 492 if ( functionDecl->get_statements() ) { // empty routine body ? 505 493 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; 506 doBeginScope(); 507 scopeTyVars.beginScope(); 508 509 DeclarationWithType *oldRetval = retval; 494 GuardScope( scopeTyVars ); 495 GuardValue( retval ); 510 496 511 497 // process polymorphic return value 512 498 retval = nullptr; 513 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) { 514 retval = functionDecl->get_functionType()->get_returnVals().front(); 499 FunctionType *functionType = functionDecl->type; 500 if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) { 501 retval = functionType->returnVals.front(); 515 502 516 503 // give names to unnamed return values 517 if ( retval-> get_name()== "" ) {518 retval-> set_name( "_retparm" );519 retval-> set_linkage( LinkageSpec::C );504 if ( retval->name == "" ) { 505 retval->name = "_retparm"; 506 retval->linkage = LinkageSpec::C; 520 507 } // if 521 508 } // if 522 509 523 FunctionType *functionType = functionDecl->get_functionType(); 524 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 525 526 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 510 makeTyVarMap( functionType, scopeTyVars ); 511 512 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 527 513 std::list< FunctionType *> functions; 528 for ( Type::ForallList::iterator tyVar = functionType-> get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {529 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)-> get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {514 for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) { 515 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) { 530 516 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter ); 531 517 } // for … … 542 528 } // if 543 529 } // for 544 545 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );546 547 scopeTyVars.endScope();548 retval = oldRetval;549 doEndScope();550 530 // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl; 551 531 } // if 552 return functionDecl; 553 } 554 555 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 532 } 533 534 void Pass1::premutate( TypeDecl *typeDecl ) { 556 535 addToTyVarMap( typeDecl, scopeTyVars ); 557 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 558 } 559 560 Expression *Pass1::mutate( CommaExpr *commaExpr ) { 536 } 537 538 void Pass1::premutate( CommaExpr *commaExpr ) { 561 539 // Attempting to find application expressions that were mutated by the copy constructor passes 562 540 // to use an explicit return variable, so that the variable can be reused as a parameter to the … … 574 552 } 575 553 } 576 577 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );578 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );579 return commaExpr;580 }581 582 Expression *Pass1::mutate( ConditionalExpr *condExpr ) {583 condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );584 condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );585 condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );586 return condExpr;587 588 554 } 589 555 … … 659 625 ObjectDecl *Pass1::makeTemporary( Type *type ) { 660 626 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 ); 661 stmtsToAdd .push_back( new DeclStmt( noLabels, newObj ) );627 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 662 628 return newObj; 663 629 } … … 775 741 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 776 742 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 777 stmtsToAdd .push_back( new DeclStmt( noLabels, newObj ) );743 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 778 744 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 779 745 assign->get_args().push_back( new VariableExpr( newObj ) ); 780 746 assign->get_args().push_back( arg ); 781 stmtsToAdd .push_back( new ExprStmt( noLabels, assign ) );747 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 782 748 arg = new AddressExpr( new VariableExpr( newObj ) ); 783 749 } // if … … 961 927 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 962 928 adapter = answer.first; 963 stmtsToAdd .push_back( new DeclStmt( noLabels, newAdapter ) );929 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) ); 964 930 } // if 965 931 assert( adapter != adapters.end() ); … … 1118 1084 } 1119 1085 1120 Expression *Pass1:: mutate( ApplicationExpr *appExpr ) {1086 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) { 1121 1087 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1122 1088 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { … … 1124 1090 // } 1125 1091 // std::cerr << "\n"; 1126 appExpr->get_function()->acceptMutator( *this ); 1127 mutateAll( appExpr->get_args(), *this ); 1128 1129 assert( appExpr->get_function()->has_result() ); 1130 FunctionType * function = getFunctionType( appExpr->get_function()->get_result() ); 1131 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() ); 1092 1093 assert( appExpr->function->result ); 1094 FunctionType * function = getFunctionType( appExpr->function->result ); 1095 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); 1132 1096 1133 1097 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { … … 1182 1146 } 1183 1147 1184 Expression * Pass1::mutate( UntypedExpr *expr ) {1185 if ( expr-> has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {1186 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr-> get_function()) ) {1148 Expression * Pass1::postmutate( UntypedExpr *expr ) { 1149 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1150 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1187 1151 if ( name->get_name() == "*?" ) { 1188 Expression *ret = expr-> get_args().front();1189 expr-> get_args().clear();1152 Expression *ret = expr->args.front(); 1153 expr->args.clear(); 1190 1154 delete expr; 1191 return ret ->acceptMutator( *this );1155 return ret; 1192 1156 } // if 1193 1157 } // if 1194 1158 } // if 1195 return PolyMutator::mutate( expr ); 1196 } 1197 1198 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 1159 return expr; 1160 } 1161 1162 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1163 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1199 1164 assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() ); 1200 1165 … … 1216 1181 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1217 1182 // out of the if condition. 1218 addrExpr-> set_arg( mutateExpression( addrExpr->get_arg() ));1183 addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor ); 1219 1184 // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment 1220 1185 bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env ); … … 1231 1196 } 1232 1197 1233 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1234 if ( retval && returnStmt->get_expr() ) { 1235 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() ); 1236 delete returnStmt->get_expr(); 1237 returnStmt->set_expr( 0 ); 1238 } else { 1239 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 1198 void Pass1::premutate( ReturnStmt *returnStmt ) { 1199 if ( retval && returnStmt->expr ) { 1200 assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() ); 1201 delete returnStmt->expr; 1202 returnStmt->expr = nullptr; 1240 1203 } // if 1241 return returnStmt; 1242 } 1243 1244 Type * Pass1::mutate( PointerType *pointerType ) { 1245 scopeTyVars.beginScope(); 1204 } 1205 1206 void Pass1::premutate( PointerType *pointerType ) { 1207 GuardScope( scopeTyVars ); 1246 1208 makeTyVarMap( pointerType, scopeTyVars ); 1247 1248 Type *ret = Mutator::mutate( pointerType ); 1249 1250 scopeTyVars.endScope(); 1251 return ret; 1252 } 1253 1254 Type * Pass1::mutate( FunctionType *functionType ) { 1255 scopeTyVars.beginScope(); 1209 } 1210 1211 void Pass1::premutate( FunctionType *functionType ) { 1212 GuardScope( scopeTyVars ); 1256 1213 makeTyVarMap( functionType, scopeTyVars ); 1257 1258 Type *ret = Mutator::mutate( functionType ); 1259 1260 scopeTyVars.endScope(); 1261 return ret; 1262 } 1263 1264 void Pass1::doBeginScope() { 1214 } 1215 1216 void Pass1::beginScope() { 1265 1217 adapters.beginScope(); 1266 1218 } 1267 1219 1268 void Pass1:: doEndScope() {1220 void Pass1::endScope() { 1269 1221 adapters.endScope(); 1270 1222 } … … 1293 1245 } 1294 1246 1295 template< typename DeclClass > 1296 DeclClass * Pass2::handleDecl( DeclClass *decl ) { 1297 DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) ); 1298 1299 return ret; 1300 } 1301 1302 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) { 1303 functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) ); 1247 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) { 1304 1248 FunctionType * ftype = functionDecl->get_functionType(); 1305 1249 if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) { … … 1325 1269 } 1326 1270 1327 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) { 1328 return handleDecl( objectDecl ); 1329 } 1330 1331 template< typename AggDecl > 1332 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) { 1271 void Pass2::premutate( StructDecl * ) { 1333 1272 // prevent tyVars from leaking into containing scope 1334 scopeTyVars.beginScope(); 1335 Parent::mutate( aggDecl ); 1336 scopeTyVars.endScope(); 1337 return aggDecl; 1338 } 1339 1340 StructDecl * Pass2::mutate( StructDecl *aggDecl ) { 1341 return handleAggDecl( aggDecl ); 1342 } 1343 1344 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) { 1345 return handleAggDecl( aggDecl ); 1346 } 1347 1348 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) { 1349 return handleAggDecl( aggDecl ); 1350 } 1351 1352 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) { 1273 GuardScope( scopeTyVars ); 1274 } 1275 1276 void Pass2::premutate( UnionDecl * ) { 1277 // prevent tyVars from leaking into containing scope 1278 GuardScope( scopeTyVars ); 1279 } 1280 1281 void Pass2::premutate( TraitDecl * ) { 1282 // prevent tyVars from leaking into containing scope 1283 GuardScope( scopeTyVars ); 1284 } 1285 1286 void Pass2::premutate( TypeDecl *typeDecl ) { 1353 1287 addToTyVarMap( typeDecl, scopeTyVars ); 1354 if ( typeDecl->get_base() ) { 1355 return handleDecl( typeDecl ); 1356 } else { 1357 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) ); 1358 } 1359 } 1360 1361 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) { 1362 return handleDecl( typedefDecl ); 1363 } 1364 1365 Type * Pass2::mutate( PointerType *pointerType ) { 1366 scopeTyVars.beginScope(); 1288 } 1289 1290 void Pass2::premutate( PointerType *pointerType ) { 1291 GuardScope( scopeTyVars ); 1367 1292 makeTyVarMap( pointerType, scopeTyVars ); 1368 1369 Type *ret = Parent::mutate( pointerType ); 1370 1371 scopeTyVars.endScope(); 1372 return ret; 1373 } 1374 1375 Type *Pass2::mutate( FunctionType *funcType ) { 1376 scopeTyVars.beginScope(); 1377 1293 } 1294 1295 void Pass2::premutate( FunctionType *funcType ) { 1296 GuardScope( scopeTyVars ); 1378 1297 makeTyVarMap( funcType, scopeTyVars ); 1379 1298 … … 1414 1333 // move all assertions into parameter list 1415 1334 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1416 // *assert = (*assert)->acceptMutator( *this );1417 1335 // assertion parameters may not be used in body, pass along with unused attribute. 1418 1336 (*assert)->get_attributes().push_back( new Attribute( "unused" ) ); … … 1450 1368 } 1451 1369 } 1452 1453 1370 seenTypes.insert( typeName ); 1454 1371 } … … 1458 1375 funcType->get_parameters().splice( last, inferredParams ); 1459 1376 addAdapters( funcType ); 1460 mutateAll( funcType->get_returnVals(), *this );1461 mutateAll( funcType->get_parameters(), *this );1462 1463 scopeTyVars.endScope();1464 return funcType;1465 1377 } 1466 1378 … … 1468 1380 1469 1381 PolyGenericCalculator::PolyGenericCalculator() 1470 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) , scopeTyVars( TypeDecl::Data{} ){}1382 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {} 1471 1383 1472 1384 void PolyGenericCalculator::beginTypeScope( Type *ty ) { … … 1829 1741 1830 1742 template< typename DeclClass > 1831 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {1832 scopeTyVars.beginScope();1743 void Pass3::handleDecl( DeclClass * decl, Type * type ) { 1744 GuardScope( scopeTyVars ); 1833 1745 makeTyVarMap( type, scopeTyVars ); 1834 1835 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );1836 // ScrubTyVars::scrub( decl, scopeTyVars );1837 1746 ScrubTyVars::scrubAll( decl ); 1838 1839 scopeTyVars.endScope(); 1840 return ret; 1841 } 1842 1843 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) { 1844 return handleDecl( objectDecl, objectDecl->get_type() ); 1845 } 1846 1847 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) { 1848 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1849 } 1850 1851 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) { 1852 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1747 } 1748 1749 void Pass3::premutate( ObjectDecl * objectDecl ) { 1750 handleDecl( objectDecl, objectDecl->type ); 1751 } 1752 1753 void Pass3::premutate( FunctionDecl * functionDecl ) { 1754 handleDecl( functionDecl, functionDecl->type ); 1755 } 1756 1757 void Pass3::premutate( TypedefDecl * typedefDecl ) { 1758 handleDecl( typedefDecl, typedefDecl->base ); 1853 1759 } 1854 1760 1855 1761 /// Strips the members from a generic aggregate 1856 void stripGenericMembers(AggregateDecl * decl) {1857 if ( ! decl-> get_parameters().empty() ) decl->get_members().clear();1858 } 1859 1860 Declaration *Pass3::mutate( StructDecl *structDecl ) {1762 void stripGenericMembers(AggregateDecl * decl) { 1763 if ( ! decl->parameters.empty() ) decl->members.clear(); 1764 } 1765 1766 void Pass3::premutate( StructDecl * structDecl ) { 1861 1767 stripGenericMembers( structDecl ); 1862 return structDecl; 1863 } 1864 1865 Declaration *Pass3::mutate( UnionDecl *unionDecl ) { 1768 } 1769 1770 void Pass3::premutate( UnionDecl * unionDecl ) { 1866 1771 stripGenericMembers( unionDecl ); 1867 return unionDecl; 1868 } 1869 1870 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1871 // Initializer *init = 0; 1872 // std::list< Expression *> designators; 1873 // addToTyVarMap( typeDecl, scopeTyVars ); 1874 // if ( typeDecl->get_base() ) { 1875 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1876 // } 1877 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1878 1772 } 1773 1774 void Pass3::premutate( TypeDecl * typeDecl ) { 1879 1775 addToTyVarMap( typeDecl, scopeTyVars ); 1880 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 1881 } 1882 1883 Type * Pass3::mutate( PointerType *pointerType ) { 1884 scopeTyVars.beginScope(); 1776 } 1777 1778 void Pass3::premutate( PointerType * pointerType ) { 1779 GuardScope( scopeTyVars ); 1885 1780 makeTyVarMap( pointerType, scopeTyVars ); 1886 1887 Type *ret = Mutator::mutate( pointerType ); 1888 1889 scopeTyVars.endScope(); 1890 return ret; 1891 } 1892 1893 Type * Pass3::mutate( FunctionType *functionType ) { 1894 scopeTyVars.beginScope(); 1781 } 1782 1783 void Pass3::premutate( FunctionType * functionType ) { 1784 GuardScope( scopeTyVars ); 1895 1785 makeTyVarMap( functionType, scopeTyVars ); 1896 1897 Type *ret = Mutator::mutate( functionType );1898 1899 scopeTyVars.endScope();1900 return ret;1901 1786 } 1902 1787 } // anonymous namespace -
src/GenPoly/Specialize.cc
r201aeb9 rd67cdb7 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( AddressExpr *castExpr ); 48 Expression * postmutate( CastExpr *castExpr ); 54 49 55 50 void handleExplicitParams( ApplicationExpr *appExpr ); … … 204 199 } 205 200 206 struct EnvTrimmer : public Visitor{201 struct EnvTrimmer { 207 202 TypeSubstitution * env, * newEnv; 208 203 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 209 v irtual voidvisit( TypeDecl * tyDecl ) {204 void previsit( TypeDecl * tyDecl ) { 210 205 // transfer known bindings for seen type variables 211 if ( Type * t = env->lookup( tyDecl-> get_name()) ) {212 newEnv->add( tyDecl-> get_name(), t );206 if ( Type * t = env->lookup( tyDecl->name ) ) { 207 newEnv->add( tyDecl->name, t ); 213 208 } 214 209 } … … 219 214 if ( env ) { 220 215 TypeSubstitution * newEnv = new TypeSubstitution(); 221 EnvTrimmertrimmer( env, newEnv );216 PassVisitor<EnvTrimmer> trimmer( env, newEnv ); 222 217 expr->accept( trimmer ); 223 218 return newEnv; … … 277 272 std::string oldParamPrefix = paramPrefix; 278 273 paramPrefix += "p"; 279 // save stmtsToAdd in oldStmts274 // save stmtsToAddBefore in oldStmts 280 275 std::list< Statement* > oldStmts; 281 oldStmts.splice( oldStmts.end(), stmtsToAdd );282 mutate( appExpr );276 oldStmts.splice( oldStmts.end(), stmtsToAddBefore ); 277 appExpr->acceptMutator( *visitor ); 283 278 paramPrefix = oldParamPrefix; 284 279 // 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 );280 thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore ); 281 // restore oldStmts into stmtsToAddBefore 282 stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts ); 288 283 289 284 // add return (or valueless expression) to the thunk 290 285 Statement *appStmt; 291 if ( funType-> get_returnVals().empty() ) {286 if ( funType->returnVals.empty() ) { 292 287 appStmt = new ExprStmt( noLabels, appExpr ); 293 288 } else { 294 289 appStmt = new ReturnStmt( noLabels, appExpr ); 295 290 } // if 296 thunkFunc-> get_statements()->get_kids().push_back( appStmt );291 thunkFunc->statements->kids.push_back( appStmt ); 297 292 298 293 // add thunk definition to queue of statements to add 299 stmtsToAdd .push_back( new DeclStmt( noLabels, thunkFunc ) );294 stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) ); 300 295 // return address of thunk function as replacement expression 301 296 return new AddressExpr( new VariableExpr( thunkFunc ) ); … … 304 299 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 305 300 // create thunks for the explicit parameters 306 assert( appExpr-> get_function()->has_result());307 FunctionType *function = getFunctionType( appExpr-> get_function()->get_result());301 assert( appExpr->function->result ); 302 FunctionType *function = getFunctionType( appExpr->function->result ); 308 303 assert( function ); 309 304 std::list< DeclarationWithType* >::iterator formal; 310 305 std::list< Expression* >::iterator actual; 311 306 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 307 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() ); 308 } 309 } 310 311 Expression * Specialize::postmutate( ApplicationExpr *appExpr ) { 320 312 if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) { 321 313 // create thunks for the inferred parameters … … 331 323 } 332 324 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() ) ); 325 Expression * Specialize::postmutate( AddressExpr *addrExpr ) { 326 assert( addrExpr->result ); 327 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) ); 337 328 return addrExpr; 338 329 } 339 330 340 Expression * Specialize::mutate( CastExpr *castExpr ) { 341 castExpr->get_arg()->acceptMutator( *this ); 342 if ( castExpr->get_result()->isVoid() ) { 331 Expression * Specialize::postmutate( CastExpr *castExpr ) { 332 if ( castExpr->result->isVoid() ) { 343 333 // can't specialize if we don't have a return value 344 334 return castExpr; 345 335 } 346 Expression *specialized = doSpecialization( castExpr-> get_result(), castExpr->get_arg());347 if ( specialized != castExpr-> get_arg()) {336 Expression *specialized = doSpecialization( castExpr->result, castExpr->arg ); 337 if ( specialized != castExpr->arg ) { 348 338 // assume here that the specialization incorporates the cast 349 339 return specialized; … … 353 343 } 354 344 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 345 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 372 Specializespec;346 PassVisitor<Specialize> spec; 373 347 mutateAll( translationUnit, spec ); 374 348 } -
src/GenPoly/module.mk
r201aeb9 rd67cdb7 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 17 17 SRC += GenPoly/Box.cc \ 18 18 GenPoly/GenPoly.cc \ 19 GenPoly/PolyMutator.cc \20 19 GenPoly/ScrubTyVars.cc \ 21 20 GenPoly/Lvalue.cc \ … … 23 22 GenPoly/CopyParams.cc \ 24 23 GenPoly/FindFunction.cc \ 25 GenPoly/DeclMutator.cc \26 24 GenPoly/InstantiateGeneric.cc
Note:
See TracChangeset
for help on using the changeset viewer.