Changeset 05d47278 for src/GenPoly
- Timestamp:
- Jan 21, 2016, 4:35:33 PM (9 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:
- 421edab
- Parents:
- bfebb6c5
- Location:
- src/GenPoly
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rbfebb6c5 r05d47278 22 22 23 23 #include "Box.h" 24 #include "InstantiateGeneric.h" 24 25 #include "PolyMutator.h" 25 26 #include "FindFunction.h" … … 70 71 virtual void doEndScope(); 71 72 private: 73 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it 74 Expression *makeOffsetArray( StructInstType *type ); 75 /// passes extra type parameters into a polymorphic function application 72 76 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 73 77 /// wraps a function application with a new temporary for the out-parameter return value … … 88 92 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 89 93 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 94 /// Replaces intrinsic operator functions with their arithmetic desugaring 90 95 Expression *handleIntrinsics( ApplicationExpr *appExpr ); 96 /// Inserts a new temporary variable into the current scope with an auto-generated name 91 97 ObjectDecl *makeTemporary( Type *type ); 92 98 … … 117 123 }; 118 124 119 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable120 class Pass3: public PolyMutator {125 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference 126 class MemberExprFixer : public PolyMutator { 121 127 public: 122 128 template< typename DeclClass > … … 129 135 virtual Type *mutate( PointerType *pointerType ); 130 136 virtual Type *mutate( FunctionType *funcType ); 137 virtual Expression *mutate( MemberExpr *memberExpr ); 138 }; 139 140 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable 141 class Pass3 : public PolyMutator { 142 public: 143 template< typename DeclClass > 144 DeclClass *handleDecl( DeclClass *decl, Type *type ); 145 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 146 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 147 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ); 148 virtual TypeDecl *mutate( TypeDecl *objectDecl ); 149 virtual Type *mutate( PointerType *pointerType ); 150 virtual Type *mutate( FunctionType *funcType ); 131 151 private: 132 152 }; … … 143 163 } 144 164 165 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 166 template< typename MutatorType > 167 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) { 168 bool seenIntrinsic = false; 169 SemanticError errors; 170 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 171 try { 172 if ( *i ) { 173 if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) { 174 seenIntrinsic = true; 175 } else if ( seenIntrinsic ) { 176 seenIntrinsic = false; // break on this line when debugging for end of prelude 177 } 178 179 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) ); 180 assert( *i ); 181 } // if 182 } catch( SemanticError &e ) { 183 errors.append( e ); 184 } // try 185 } // for 186 if ( ! errors.isEmpty() ) { 187 throw errors; 188 } // if 189 } 190 145 191 void box( std::list< Declaration *>& translationUnit ) { 146 192 Pass1 pass1; 147 193 Pass2 pass2; 194 MemberExprFixer memberFixer; 148 195 Pass3 pass3; 149 mutateAll( translationUnit, pass1 ); 150 mutateAll( translationUnit, pass2 ); 151 mutateAll( translationUnit, pass3 ); 196 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 197 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 198 instantiateGeneric( translationUnit ); 199 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 200 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 152 201 } 153 202 … … 269 318 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 270 319 } // for 320 271 321 AdapterMap & adapters = Pass1::adapters.top(); 272 322 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { … … 319 369 } 320 370 371 Expression *Pass1::makeOffsetArray( StructInstType *ty ) { 372 // make a new temporary array 373 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 374 ObjectDecl *arrayTemp = makeTemporary( new PointerType( Type::Qualifiers(), offsetType ) ); 375 376 // build initializer list for temporary 377 std::list< Initializer* > inits; 378 StructDecl *tyBase = ty->get_baseStruct(); 379 for ( std::list< Declaration* >::const_iterator member = tyBase->get_members().begin(); member != tyBase->get_members().end(); ++member ) { 380 DeclarationWithType *memberDecl; 381 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 382 memberDecl = origMember->clone(); 383 } else { 384 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 385 } 386 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 387 } 388 arrayTemp->set_init( new ListInit( inits ) ); 389 390 // return variable pointing to temporary 391 return new VariableExpr( arrayTemp ); 392 } 393 321 394 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 322 395 // pass size/align for type variables … … 338 411 339 412 // add size/align for generic types to parameter list 340 //assert( ! appExpr->get_function()->get_results().empty() );341 413 if ( appExpr->get_function()->get_results().empty() ) return; 342 414 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); … … 358 430 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 359 431 arg++; 432 if ( dynamic_cast< StructInstType* >( parmType ) ) { 433 if ( StructInstType *argStructType = dynamic_cast< StructInstType* >( argType ) ) { 434 arg = appExpr->get_args().insert( arg, makeOffsetArray( argStructType ) ); 435 arg++; 436 } else { 437 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 438 } 439 } 360 440 361 441 seenTypes.insert( sizeName ); … … 929 1009 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 930 1010 } 931 assignDecl = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, 932 new PointerType( Type::Qualifiers(), assignIter->second->get_type()->clone() ), 0 ); 1011 DeclarationWithType *functionDecl = assignIter->second; 1012 // line below cloned from FixFunction.cc 1013 assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1014 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1015 assignDecl->set_mangleName( functionDecl->get_mangleName() ); 933 1016 } 934 1017 assert( assignDecl ); … … 1060 1143 std::list< DeclarationWithType *> inferredParams; 1061 1144 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1145 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1146 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1062 1147 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1063 1148 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { … … 1093 1178 if ( seenTypes.count( sizeName ) ) continue; 1094 1179 1095 ObjectDecl *sizeParm, *alignParm ;1180 ObjectDecl *sizeParm, *alignParm, *offsetParm; 1096 1181 sizeParm = newObj.clone(); 1097 1182 sizeParm->set_name( sizeName ); … … 1103 1188 last = funcType->get_parameters().insert( last, alignParm ); 1104 1189 ++last; 1190 1191 if ( dynamic_cast< StructInstType* >( parmType ) ) { 1192 offsetParm = newPtr.clone(); 1193 offsetParm->set_name( offsetofName( parmType ) ); 1194 last = funcType->get_parameters().insert( last, offsetParm ); 1195 ++last; 1196 } 1105 1197 1106 1198 seenTypes.insert( sizeName ); … … 1116 1208 scopeTyVars = oldtyVars; 1117 1209 return funcType; 1210 } 1211 1212 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1213 1214 template< typename DeclClass > 1215 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) { 1216 TyVarMap oldtyVars = scopeTyVars; 1217 makeTyVarMap( type, scopeTyVars ); 1218 1219 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1220 1221 scopeTyVars = oldtyVars; 1222 return ret; 1223 } 1224 1225 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) { 1226 return handleDecl( objectDecl, objectDecl->get_type() ); 1227 } 1228 1229 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) { 1230 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1231 } 1232 1233 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) { 1234 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1235 } 1236 1237 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) { 1238 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1239 return Mutator::mutate( typeDecl ); 1240 } 1241 1242 Type * MemberExprFixer::mutate( PointerType *pointerType ) { 1243 TyVarMap oldtyVars = scopeTyVars; 1244 makeTyVarMap( pointerType, scopeTyVars ); 1245 1246 Type *ret = Mutator::mutate( pointerType ); 1247 1248 scopeTyVars = oldtyVars; 1249 return ret; 1250 } 1251 1252 Type * MemberExprFixer::mutate( FunctionType *functionType ) { 1253 TyVarMap oldtyVars = scopeTyVars; 1254 makeTyVarMap( functionType, scopeTyVars ); 1255 1256 Type *ret = Mutator::mutate( functionType ); 1257 1258 scopeTyVars = oldtyVars; 1259 return ret; 1260 } 1261 1262 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) { 1263 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1264 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1265 // change initialization of a polymorphic value object 1266 // to allocate storage with alloca 1267 Type *declType = objectDecl->get_type(); 1268 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1269 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1270 1271 delete objectDecl->get_init(); 1272 1273 std::list<Expression*> designators; 1274 objectDecl->set_init( new SingleInit( alloc, designators ) ); 1275 } 1276 } 1277 return Mutator::mutate( declStmt ); 1278 } 1279 1280 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) { 1281 // mutate, exiting early if no longer MemberExpr 1282 Expression *expr = Mutator::mutate( memberExpr ); 1283 memberExpr = dynamic_cast< MemberExpr* >( expr ); 1284 if ( ! memberExpr ) return expr; 1285 1286 // get declaration for base struct, exiting early if not found 1287 VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate() ); 1288 if ( ! varExpr ) return memberExpr; 1289 ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 1290 if ( ! objectDecl ) return memberExpr; 1291 1292 // only mutate member expressions for polymorphic types 1293 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars ); 1294 if ( ! objectType ) return memberExpr; 1295 1296 // get base aggregate for type so members can be looked up 1297 AggregateDecl *memberBase = 0; 1298 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1299 memberBase = structType->get_baseStruct(); 1300 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) { 1301 memberBase = unionType->get_baseUnion(); 1302 } else return memberExpr; 1303 1304 // look up numeric index of member in base aggregate 1305 DeclarationWithType *memberDecl = memberExpr->get_member(); 1306 std::list< Declaration* > &baseDecls = memberBase->get_members(); 1307 std::list< Declaration* >::const_iterator decl = baseDecls.begin(); 1308 unsigned long i = 0; 1309 for( ; decl != baseDecls.end(); ++decl, ++i ) { 1310 if ( memberDecl->get_name() != (*decl)->get_name() ) continue; 1311 1312 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) { 1313 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break; 1314 else continue; 1315 } else break; 1316 } 1317 if ( decl == baseDecls.end() ) return memberExpr; 1318 1319 // replace member expression with dereference of pointer offset 1320 std::stringstream offset_namer; 1321 offset_namer << i; 1322 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1323 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); 1324 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) ); 1325 fieldOffset->get_args().push_back( fieldIndex ); 1326 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) ); 1327 fieldLoc->get_args().push_back( memberExpr->get_aggregate() ); 1328 fieldLoc->get_args().push_back( fieldOffset ); 1329 UntypedExpr *ret = new UntypedExpr( new NameExpr( "*?" ) ); 1330 ret->get_args().push_back( fieldLoc ); 1331 1332 memberExpr->set_aggregate( 0 ); 1333 delete memberExpr; 1334 return ret; 1118 1335 } 1119 1336 … … 1176 1393 return ret; 1177 1394 } 1178 1179 Statement *Pass3::mutate( DeclStmt *declStmt ) {1180 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {1181 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {1182 // change initialization of a polymorphic value object1183 // to allocate storage with alloca1184 Type *declType = objectDecl->get_type();1185 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );1186 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );1187 1188 delete objectDecl->get_init();1189 1190 std::list<Expression*> designators;1191 objectDecl->set_init( new SingleInit( alloc, designators ) );1192 }1193 }1194 return Mutator::mutate( declStmt );1195 }1196 1395 } // anonymous namespace 1197 1396 } // namespace GenPoly -
src/GenPoly/GenPoly.cc
rbfebb6c5 r05d47278 127 127 } 128 128 129 Type *hasPolyBase( Type *type, const TypeSubstitution *env ) { 130 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 131 return hasPolyBase( ptr->get_base(), env ); 132 } else if ( env ) { 133 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 134 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 135 return hasPolyBase( newType, env ); 136 } // if 137 } // if 138 } 139 140 return isPolyType( type, env ); 141 } 142 143 Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 144 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 145 return hasPolyBase( ptr->get_base(), tyVars, env ); 146 } else if ( env ) { 147 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 148 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 149 return hasPolyBase( newType, tyVars, env ); 150 } // if 151 } // if 152 } 153 154 return isPolyType( type, tyVars, env ); 155 } 156 129 157 FunctionType * getFunctionType( Type *ty ) { 130 158 PointerType *ptrType; … … 136 164 } 137 165 166 VariableExpr *getBaseVar( Expression *expr ) { 167 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) { 168 // found the variable directly 169 return varExpr; 170 } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) { 171 // look for compiler-inserted dereference operator 172 NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() ); 173 if ( ! fn || fn->get_name() != std::string("*?") ) return 0; 174 return getBaseVar( *untypedExpr->begin_args() ); 175 } else return 0; 176 } 177 138 178 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { 139 179 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { … … 160 200 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty ); 161 201 } 202 203 std::string offsetofName( Type* ty ) { 204 return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty ); 205 } 206 162 207 } // namespace GenPoly 163 208 -
src/GenPoly/GenPoly.h
rbfebb6c5 r05d47278 47 47 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 48 48 49 /// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type, NULL otherwise; 50 /// will look up substitution in env if provided 51 Type *hasPolyBase( Type *type, const TypeSubstitution *env = 0 ); 52 53 /// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type in tyVars, NULL otherwise; 54 /// will look up substitution in env if provided 55 Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 56 49 57 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 50 FunctionType * getFunctionType( Type *ty ); 58 FunctionType *getFunctionType( Type *ty ); 59 60 /// Returns the base variable (possibly repeatedly dereferenced) for an expression, NULL if none found 61 VariableExpr *getBaseVar( Expression *expr ); 51 62 52 63 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` … … 61 72 /// Gets the name of the alignof parameter for the type 62 73 std::string alignofName( Type *ty ); 74 75 /// Gets the name of the offsetof parameter for the type 76 std::string offsetofName( Type *ty ); 63 77 } // namespace GenPoly 64 78
Note: See TracChangeset
for help on using the changeset viewer.