Changes in src/GenPoly/Box.cc [4318107:bd85400]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r4318107 rbd85400 73 73 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it 74 74 Expression *makeOffsetArray( StructInstType *type ); 75 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application76 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );77 75 /// passes extra type parameters into a polymorphic function application 78 void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType,std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );76 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 79 77 /// wraps a function application with a new temporary for the out-parameter return value 80 78 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ); … … 400 398 } 401 399 402 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 403 Type *polyBase = hasPolyBase( parmType, exprTyVars ); 404 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 405 std::string sizeName = sizeofName( polyBase ); 406 if ( seenTypes.count( sizeName ) ) return; 407 408 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 409 arg++; 410 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 411 arg++; 412 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 413 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 414 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 415 arg++; 416 } else { 417 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 418 } 419 } 420 421 seenTypes.insert( sizeName ); 422 } 423 } 424 425 void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 400 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 426 401 // pass size/align for type variables 427 402 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { … … 449 424 std::list< Expression* >::const_iterator fnArg = arg; 450 425 std::set< std::string > seenTypes; //< names for generic types we've seen 451 452 // a polymorphic return type may need to be added to the argument list453 if ( polyRetType ) {454 Type *concRetType = replaceWithConcrete( appExpr, polyRetType );455 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );456 }457 458 // add type information args for presently unseen types in parameter list459 426 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 460 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 461 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue; 462 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes ); 427 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars ); 428 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 429 std::string sizeName = sizeofName( polyBase ); 430 if ( seenTypes.count( sizeName ) ) continue; 431 432 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 433 assert( fnArgBase && ! fnArgBase->get_results().empty() ); 434 Type *argBaseType = fnArgBase->get_results().front(); 435 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 436 arg++; 437 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 438 arg++; 439 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 440 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 441 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 442 arg++; 443 } else { 444 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 445 } 446 } 447 448 seenTypes.insert( sizeName ); 449 } 463 450 } 464 451 } … … 483 470 ObjectDecl *newObj = makeTemporary( retType->clone() ); 484 471 Expression *paramExpr = new VariableExpr( newObj ); 485 486 // If the type of the temporary is not polymorphic, box temporary by taking its address; 487 // otherwise the temporary is already boxed and can be used directly. 472 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 473 // temporary is already boxed and can be used directly. 488 474 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 489 475 paramExpr = new AddressExpr( paramExpr ); … … 534 520 assert( env ); 535 521 Type *concrete = replaceWithConcrete( appExpr, polyType ); 536 // add out-parameter for return value537 522 return addRetParam( appExpr, function, concrete, arg ); 538 523 } … … 557 542 assert( ! arg->get_results().empty() ); 558 543 if ( isPolyType( param, exprTyVars ) ) { 559 if ( isPolyType( arg->get_results().front() ) ) {560 // if the argument's type is polymorphic, we don't need to box again!544 if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) { 545 // if the argument's type is a type parameter, we don't need to box again! 561 546 return; 562 547 } else if ( arg->get_results().front()->get_isLvalue() ) { … … 637 622 assert( arg ); 638 623 if ( isPolyType( realParam->get_type(), tyVars ) ) { 639 if ( ! isPolyType( arg->get_type() )) {624 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 640 625 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 641 626 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); … … 932 917 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 933 918 934 TyVarMap exprTyVars; 935 makeTyVarMap( function, exprTyVars ); 936 ReferenceToType *polyRetType = 0; 937 938 if ( polyRetType = isPolyRet( function ) ) { 939 ret = addPolyRetParam( appExpr, function, polyRetType, arg ); 919 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 920 ret = addPolyRetParam( appExpr, function, polyType, arg ); 940 921 } else if ( needsAdapter( function, scopeTyVars ) ) { 941 922 // std::cerr << "needs adapter: "; … … 949 930 arg = appExpr->get_args().begin(); 950 931 951 passTypeVars( appExpr, polyRetType, arg, exprTyVars ); 932 TyVarMap exprTyVars; 933 makeTyVarMap( function, exprTyVars ); 934 935 passTypeVars( appExpr, arg, exprTyVars ); 952 936 addInferredParams( appExpr, function, arg, exprTyVars ); 953 937 … … 1008 992 } 1009 993 1010 /// Wraps a function declaration in a new pointer-to-function variable expression1011 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {1012 // line below cloned from FixFunction.cc1013 ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,1014 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );1015 functionObj->set_mangleName( functionDecl->get_mangleName() );1016 return new VariableExpr( functionObj );1017 }1018 1019 994 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1020 995 if ( retval && returnStmt->get_expr() ) { … … 1032 1007 1033 1008 // find assignment operator for (polymorphic) return type 1034 ApplicationExpr *assignExpr= 0;1009 DeclarationWithType *assignDecl = 0; 1035 1010 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1036 // find assignment operator for type variable1037 1011 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1038 1012 if ( assignIter == assignOps.end() ) { 1039 1013 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 1040 1014 } // if 1041 assign Expr = new ApplicationExpr( new VariableExpr( assignIter->second ) );1015 assignDecl = assignIter->second; 1042 1016 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) { 1043 // find assignment operator for generic type1044 1017 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() ); 1045 1018 if ( assignIter == scopedAssignOps.end() ) { 1046 1019 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 1047 1020 } 1048 1049 // wrap it up in an application expression1050 1021 DeclarationWithType *functionDecl = assignIter->second; 1051 assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) ); 1052 assignExpr->set_env( env->clone() ); 1053 1054 // find each of its needed secondary assignment operators 1055 std::list< Expression* > &tyParams = refType->get_parameters(); 1056 std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall(); 1057 std::list< Expression* >::const_iterator tyIt = tyParams.begin(); 1058 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1059 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1060 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype) 1061 1062 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1063 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1064 DeclarationWithType *actualDecl = asserts.front(); 1065 ReferenceToType *actualType = isAssignment( actualDecl ); 1066 assert( actualType && "First assertion of type with assertions should be assignment operator" ); 1067 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1068 assert( formalTypeExpr && "type parameters must be type expressions" ); 1069 Type *formalType = formalTypeExpr->get_type(); 1070 assignExpr->get_env()->add( actualType->get_name(), formalType ); 1071 1072 DeclarationWithType *assertAssign = 0; 1073 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { 1074 std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() ); 1075 if ( assertAssignIt == assignOps.end() ) { 1076 throw SemanticError( "No assignment operation found for ", formalTypeInstType ); 1077 } 1078 assertAssign = assertAssignIt->second; 1079 //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType ); 1080 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) ) { 1081 ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() ); 1082 if ( assertAssignIt == scopedAssignOps.end() ) { 1083 throw SemanticError( "No assignment operation found for ", formalReferenceType ); 1084 } 1085 assertAssign = assertAssignIt->second; 1086 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" ); 1087 1088 1089 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1090 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); 1091 } 1022 // line below cloned from FixFunction.cc 1023 assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1024 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1025 assignDecl->set_mangleName( functionDecl->get_mangleName() ); 1092 1026 } 1093 assert( assign Expr);1027 assert( assignDecl ); 1094 1028 1095 1029 // replace return statement with appropriate assignment to out parameter 1030 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) ); 1096 1031 Expression *retParm = new NameExpr( retval->get_name() ); 1097 1032 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); … … 1245 1180 } 1246 1181 1247 // add size/align for generic parametertypes to parameter list1182 // add size/align for generic types to parameter list 1248 1183 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1249 1184 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { … … 1360 1295 1361 1296 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) { 1362 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() 1363 || memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i; 1297 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i; 1364 1298 else continue; 1365 1299 } else return i; … … 1407 1341 if ( ! objectType ) return memberExpr; 1408 1342 1409 Expression *newMemberExpr = 0;1410 1343 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1411 1344 // look up offset index … … 1417 1350 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) ); 1418 1351 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) ); 1419 newMemberExpr = fieldLoc; 1420 } else if ( dynamic_cast< UnionInstType* >( objectType ) ) { 1352 1353 delete memberExpr; 1354 return fieldLoc; 1355 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) { 1421 1356 // union members are all at offset zero, so build appropriately-dereferenced variable 1422 newMemberExpr = makeDerefdVar( varExpr->clone(), varDepth ); 1357 Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth ); 1358 delete memberExpr; 1359 return derefdVar; 1423 1360 } else return memberExpr; 1424 assert( newMemberExpr );1425 1426 // wrap pointer members in appropriate cast1427 if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) {1428 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) );1429 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );1430 derefExpr->get_args().push_back( ptrCastExpr );1431 newMemberExpr = derefExpr;1432 }1433 1434 delete memberExpr;1435 return newMemberExpr;1436 1361 } 1437 1362 … … 1454 1379 delete offsetofExpr; 1455 1380 return offsetInd; 1456 } else if ( dynamic_cast< UnionInstType* >( ty ) ) {1381 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) { 1457 1382 // all union members are at offset zero 1458 1383 delete offsetofExpr;
Note:
See TracChangeset
for help on using the changeset viewer.