Changeset 579263a for src/GenPoly
- Timestamp:
- Jun 26, 2017, 4:48:35 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:
- bb1cd95
- Parents:
- e4d829b (diff), 2a7b3ca (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. - Location:
- src/GenPoly
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
re4d829b r579263a 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 13 09:26:38201713 // Update Count : 34 112 // Last Modified On : Wed Jun 21 15:49:59 2017 13 // Update Count : 346 14 14 // 15 15 … … 108 108 Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true ); 109 109 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 110 Expression *addDynRetParam( ApplicationExpr *appExpr, FunctionType *function,Type *polyType, std::list< Expression *>::iterator &arg );110 Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg ); 111 111 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 112 112 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); … … 341 341 Statement *makeAlignTo( Expression *lhs, Expression *rhs ) { 342 342 // check that the lhs is zeroed out to the level of rhs 343 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant ( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1") ) ) );343 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 344 344 // if not aligned, increment to alignment 345 345 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) ); … … 384 384 385 385 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size) 386 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant ( sizeAlignType->clone(), "0") ) ) );387 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant ( sizeAlignType->clone(), "1") ) ) );386 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) ); 387 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 388 388 unsigned long n_members = 0; 389 389 bool firstMember = true; … … 441 441 442 442 // calculate union layout in function body 443 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant ( sizeAlignType->clone(), "1") ) ) );444 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant ( sizeAlignType->clone(), "1") ) ) );443 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 444 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 445 445 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) { 446 446 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); … … 504 504 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 505 505 if ( functionDecl->get_statements() ) { // empty routine body ? 506 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; 506 507 doBeginScope(); 507 508 scopeTyVars.beginScope(); … … 548 549 retval = oldRetval; 549 550 doEndScope(); 551 // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl; 550 552 } // if 551 553 return functionDecl; … … 726 728 } 727 729 728 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, FunctionType *function,Type *dynType, std::list< Expression *>::iterator &arg ) {730 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) { 729 731 assert( env ); 730 732 Type *concrete = replaceWithConcrete( appExpr, dynType ); … … 1116 1118 1117 1119 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 1118 // std::cerr << "mutate appExpr: " ;1120 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1119 1121 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 1120 1122 // std::cerr << i->first << " "; … … 1141 1143 ReferenceToType *dynRetType = isDynRet( function, exprTyVars ); 1142 1144 1145 // std::cerr << function << std::endl; 1146 // std::cerr << "scopeTyVars: "; 1147 // printTyVarMap( std::cerr, scopeTyVars ); 1148 // std::cerr << "exprTyVars: "; 1149 // printTyVarMap( std::cerr, exprTyVars ); 1150 // std::cerr << "env: " << *env << std::endl; 1151 // std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl; 1152 1143 1153 // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr 1144 1154 // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int)) 1145 1155 // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome. 1146 1156 if ( dynRetType ) { 1157 // std::cerr << "dynRetType: " << dynRetType << std::endl; 1147 1158 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1148 ret = addDynRetParam( appExpr, function,concRetType, arg ); // xxx - used to use dynRetType instead of concRetType1159 ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType 1149 1160 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? 1150 1161 // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed. … … 1564 1575 /// Returns an index expression into the offset array for a type 1565 1576 Expression *makeOffsetIndex( Type *objectType, long i ) { 1566 std::stringstream offset_namer; 1567 offset_namer << i; 1568 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1577 ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) ); 1569 1578 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); 1570 1579 fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) ); … … 1779 1788 // all union members are at offset zero 1780 1789 delete offsetofExpr; 1781 return new ConstantExpr( Constant ( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "0") );1790 return new ConstantExpr( Constant::from_ulong( 0 ) ); 1782 1791 } else return offsetofExpr; 1783 1792 } -
src/GenPoly/DeclMutator.cc
re4d829b r579263a 9 9 // Author : Aaron B. Moss 10 10 // Created On : Fri Nov 27 14:44:00 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Aug 4 11:16:43 201613 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Jun 22 13:49:00 2017 13 // Update Count : 4 14 14 // 15 15 … … 178 178 Statement* DeclMutator::mutate(CatchStmt *catchStmt) { 179 179 catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) ); 180 catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) ); 180 181 catchStmt->set_body( mutateStatement( catchStmt->get_body() ) ); 181 182 return catchStmt; -
src/GenPoly/InstantiateGeneric.cc
re4d829b r579263a 22 22 #include "InstantiateGeneric.h" 23 23 24 #include "DeclMutator.h"25 24 #include "GenPoly.h" 26 25 #include "ScopedSet.h" 27 26 #include "ScrubTyVars.h" 28 #include "PolyMutator.h" 27 28 #include "Common/PassVisitor.h" 29 #include "Common/ScopedMap.h" 30 #include "Common/UniqueName.h" 31 #include "Common/utility.h" 29 32 30 33 #include "ResolvExpr/typeops.h" … … 34 37 #include "SynTree/Type.h" 35 38 36 #include "Common/ScopedMap.h" 37 #include " Common/UniqueName.h"38 #include "Common/utility.h" 39 40 #include "InitTweak/InitTweak.h" 41 39 42 40 43 namespace GenPoly { … … 153 156 } 154 157 155 // collect the environments of each TypeInstType so that type variables can be replaced156 // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.157 class EnvFinder final : public GenPoly::PolyMutator {158 public:159 using GenPoly::PolyMutator::mutate;160 virtual Type * mutate( TypeInstType * inst ) override {161 if ( env ) envMap[inst] = env;162 return inst;163 }164 165 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?166 virtual Type * mutate( FunctionType * ftype ) override {167 return ftype;168 }169 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;170 };171 172 158 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 173 class GenericInstantiator final : public DeclMutator{159 struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards { 174 160 /// Map of (generic type, parameter list) pairs to concrete type instantiations 175 161 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; … … 178 164 /// Namer for concrete types 179 165 UniqueName typeNamer; 180 /// Reference to mapping of environments 181 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap; 182 public: 183 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {} 184 185 using DeclMutator::mutate; 186 virtual Type* mutate( StructInstType *inst ) override; 187 virtual Type* mutate( UnionInstType *inst ) override; 188 189 virtual void doBeginScope() override; 190 virtual void doEndScope() override; 166 /// Should not make use of type environment to replace types of function parameter and return values. 167 bool inFunctionType = false; 168 GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {} 169 170 Type* postmutate( StructInstType *inst ); 171 Type* postmutate( UnionInstType *inst ); 172 173 void premutate( FunctionType * ftype ) { 174 GuardValue( inFunctionType ); 175 inFunctionType = true; 176 } 177 178 void beginScope(); 179 void endScope(); 191 180 private: 192 181 /// Wrap instantiation lookup for structs … … 207 196 208 197 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 209 EnvFinder finder; 210 mutateAll( translationUnit, finder ); 211 GenericInstantiator instantiator( finder.envMap ); 212 instantiator.mutateDeclarationList( translationUnit ); 198 PassVisitor<GenericInstantiator> instantiator; 199 mutateAll( translationUnit, instantiator ); 213 200 } 214 201 … … 306 293 Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) { 307 294 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 308 if ( envMap.count( typeInst ) ) { 309 TypeSubstitution * env = envMap.at( typeInst ); 295 if ( env && ! inFunctionType ) { 310 296 Type *concrete = env->lookup( typeInst->get_name() ); 311 297 if ( concrete ) { … … 331 317 332 318 333 Type* GenericInstantiator::mutate( StructInstType *inst ) { 334 // mutate subtypes 335 Type *mutated = Mutator::mutate( inst ); 336 inst = dynamic_cast< StructInstType* >( mutated ); 337 if ( ! inst ) return mutated; 338 319 Type* GenericInstantiator::postmutate( StructInstType *inst ) { 339 320 // exit early if no need for further mutation 340 321 if ( inst->get_parameters().empty() ) return inst; … … 368 349 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 369 350 insert( inst, typeSubs, concDecl ); // must insert before recursion 370 concDecl->acceptMutator( * this); // recursively instantiate members371 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first351 concDecl->acceptMutator( *visitor ); // recursively instantiate members 352 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first 372 353 } 373 354 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); … … 388 369 } 389 370 390 Type* GenericInstantiator::mutate( UnionInstType *inst ) { 391 // mutate subtypes 392 Type *mutated = Mutator::mutate( inst ); 393 inst = dynamic_cast< UnionInstType* >( mutated ); 394 if ( ! inst ) return mutated; 395 371 Type* GenericInstantiator::postmutate( UnionInstType *inst ) { 396 372 // exit early if no need for further mutation 397 373 if ( inst->get_parameters().empty() ) return inst; … … 423 399 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 424 400 insert( inst, typeSubs, concDecl ); // must insert before recursion 425 concDecl->acceptMutator( * this); // recursively instantiate members426 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first401 concDecl->acceptMutator( *visitor ); // recursively instantiate members 402 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first 427 403 } 428 404 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); … … 442 418 } 443 419 444 void GenericInstantiator::doBeginScope() { 445 DeclMutator::doBeginScope(); 420 void GenericInstantiator::beginScope() { 446 421 instantiations.beginScope(); 447 422 dtypeStatics.beginScope(); 448 423 } 449 424 450 void GenericInstantiator::doEndScope() { 451 DeclMutator::doEndScope(); 425 void GenericInstantiator::endScope() { 452 426 instantiations.endScope(); 453 427 dtypeStatics.endScope(); -
src/GenPoly/PolyMutator.cc
re4d829b r579263a 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Aug 4 11:26:22 201613 // Update Count : 1 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Jun 22 13:47:00 2017 13 // Update Count : 17 14 14 // 15 15 … … 123 123 124 124 Statement * PolyMutator::mutate(TryStmt *tryStmt) { 125 tryStmt->set_block( 125 tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); 126 126 mutateAll( tryStmt->get_catchers(), *this ); 127 tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) ); 127 128 return tryStmt; 128 129 } 129 130 130 131 Statement * PolyMutator::mutate(CatchStmt *cathStmt) { 131 cathStmt->set_body( mutateStatement( cathStmt->get_body() ) ); 132 cathStmt->set_decl( maybeMutate( cathStmt->get_decl(), *this ) ); 132 cathStmt->set_body( mutateStatement( cathStmt->get_body() ) ); 133 cathStmt->set_cond( maybeMutate( cathStmt->get_cond(), *this ) ); 134 cathStmt->set_decl( maybeMutate( cathStmt->get_decl(), *this ) ); 133 135 return cathStmt; 134 136 } -
src/GenPoly/Specialize.cc
re4d829b r579263a 93 93 } 94 94 95 bool needsTupleSpecialization( Type *formalType, Type *actualType , TypeSubstitution *env) {95 bool needsTupleSpecialization( Type *formalType, Type *actualType ) { 96 96 // Needs tuple specialization if the structure of the formal type and actual type do not match. 97 97 // This is the case if the formal type has ttype polymorphism, or if the structure of tuple types … … 99 99 if ( FunctionType * fftype = getFunctionType( formalType ) ) { 100 100 if ( fftype->isTtype() ) return true; 101 // conversion of 0 (null) to function type does not require tuple specialization 102 if ( dynamic_cast< ZeroType * >( actualType ) ) return false; 101 103 FunctionType * aftype = getFunctionType( actualType ); 102 104 assertf( aftype, "formal type is a function type, but actual type is not." ); … … 112 114 113 115 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 114 return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType , env);116 return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType ); 115 117 } 116 118
Note:
See TracChangeset
for help on using the changeset viewer.