Changes in src/GenPoly/Box.cc [ffad73a:69911c11]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rffad73a r69911c11 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : T hu Nov 26 17:01:55201513 // Update Count : 19111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 15 15:30:31 2015 13 // Update Count : 215 14 14 // 15 15 … … 62 62 virtual Expression *mutate( CommaExpr *commaExpr ); 63 63 virtual Expression *mutate( ConditionalExpr *condExpr ); 64 virtual Statement * mutate(ReturnStmt *catchStmt);64 virtual Statement * mutate( ReturnStmt *returnStmt ); 65 65 virtual Type *mutate( PointerType *pointerType ); 66 virtual Type * mutate( FunctionType *pointerType );66 virtual Type * mutate( FunctionType *functionType ); 67 67 68 68 virtual void doBeginScope(); … … 192 192 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 193 193 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 194 name = typeInst->get_name(); 195 return true; 194 if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 195 if ( typeInst->get_name() == typeInst2->get_name() ) { 196 name = typeInst->get_name(); 197 return true; 198 } // if 199 } // if 196 200 } // if 197 201 } // if … … 277 281 278 282 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 279 /// std::cerr << "add " << typeDecl->get_name() << "\n";280 283 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 281 284 return Mutator::mutate( typeDecl ); … … 303 306 304 307 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 308 // pass size/align for type variables 305 309 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 306 310 ResolvExpr::EqvClass eqvClass; … … 318 322 } // if 319 323 } // for 324 325 // add size/align for generic types to parameter list 326 //assert( ! appExpr->get_function()->get_results().empty() ); 327 if ( appExpr->get_function()->get_results().empty() ) return; 328 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); 329 assert( funcType ); 330 331 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 332 std::list< Expression* >::const_iterator fnArg = arg; 333 std::set< std::string > seenTypes; //< names for generic types we've seen 334 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 335 Type *parmType = (*fnParm)->get_type(); 336 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) { 337 std::string sizeName = sizeofName( parmType ); 338 if ( seenTypes.count( sizeName ) ) continue; 339 340 assert( ! (*fnArg)->get_results().empty() ); 341 Type *argType = (*fnArg)->get_results().front(); 342 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 343 arg++; 344 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 345 arg++; 346 347 seenTypes.insert( sizeName ); 348 } 349 } 320 350 } 321 351 … … 327 357 328 358 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 329 if ( useRetval ) { 330 assert( retval ); 331 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 332 arg++; 333 } else { 334 ObjectDecl *newObj = makeTemporary( retType->clone() ); 335 Expression *paramExpr = new VariableExpr( newObj ); 336 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 337 paramExpr = new AddressExpr( paramExpr ); 338 } // if 339 arg = appExpr->get_args().insert( arg, paramExpr ); 340 arg++; 341 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 342 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 343 commaExpr->set_env( appExpr->get_env() ); 344 appExpr->set_env( 0 ); 345 return commaExpr; 346 } // if 347 return appExpr; 359 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 360 // if ( useRetval ) { 361 // assert( retval ); 362 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 363 // arg++; 364 // } else { 365 366 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 367 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple 368 // return values. 369 ObjectDecl *newObj = makeTemporary( retType->clone() ); 370 Expression *paramExpr = new VariableExpr( newObj ); 371 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 372 // temporary is already boxed and can be used directly. 373 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 374 paramExpr = new AddressExpr( paramExpr ); 375 } // if 376 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call 377 arg++; 378 // Build a comma expression to call the function and emulate a normal return. 379 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 380 commaExpr->set_env( appExpr->get_env() ); 381 appExpr->set_env( 0 ); 382 return commaExpr; 383 // } // if 384 // return appExpr; 348 385 } 349 386 … … 411 448 412 449 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 413 /// std::cout << "function is ";414 /// function->print( std::cout );415 450 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 416 /// std::cout << "parameter is ";417 /// (*param)->print( std::fcout );418 /// std::cout << std::endl << "argument is ";419 /// (*arg)->print( std::cout );420 451 assert( arg != appExpr->get_args().end() ); 421 452 addCast( *arg, (*param)->get_type(), exprTyVars ); … … 807 838 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 808 839 assert( ! addrExpr->get_arg()->get_results().empty() ); 840 841 bool needs = false; 842 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 843 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 844 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 845 if ( name->get_name() == "*?" ) { 846 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 847 assert( ! appExpr->get_function()->get_results().empty() ); 848 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 849 assert( pointer ); 850 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 851 assert( function ); 852 needs = needsAdapter( function, scopeTyVars ); 853 } // if 854 } // if 855 } // if 856 } // if 857 } // if 809 858 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 810 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) {859 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) { 811 860 Expression *ret = addrExpr->get_arg(); 812 861 delete ret->get_results().front(); … … 820 869 } 821 870 822 Statement * Pass1::mutate(ReturnStmt *retStmt) { 823 // a cast expr on a polymorphic return value is either redundant or invalid 824 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 825 retStmt->set_expr( castExpr->get_arg() ); 826 retStmt->get_expr()->set_env( castExpr->get_env() ); 827 castExpr->set_env( 0 ); 828 castExpr->set_arg( 0 ); 829 delete castExpr; 830 } 831 if ( retval && retStmt->get_expr() ) { 832 assert( ! retStmt->get_expr()->get_results().empty() ); 833 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 834 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 835 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 836 assert( typeInst ); 837 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 838 if ( assignIter == assignOps.end() ) { 839 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 840 } // if 841 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 842 Expression *retParm = new NameExpr( retval->get_name() ); 843 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 844 assignExpr->get_args().push_back( retParm ); 845 assignExpr->get_args().push_back( retStmt->get_expr() ); 846 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 847 } else { 848 useRetval = true; 849 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 850 useRetval = false; 871 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 872 if ( retval && returnStmt->get_expr() ) { 873 assert( ! returnStmt->get_expr()->get_results().empty() ); 874 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 875 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { 876 // a cast expr on a polymorphic return value is either redundant or invalid 877 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) { 878 returnStmt->set_expr( castExpr->get_arg() ); 879 returnStmt->get_expr()->set_env( castExpr->get_env() ); 880 castExpr->set_env( 0 ); 881 castExpr->set_arg( 0 ); 882 delete castExpr; 883 } //while 884 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 885 assert( typeInst ); 886 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 887 if ( assignIter == assignOps.end() ) { 888 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 851 889 } // if 852 retStmt->set_expr( 0 ); 890 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 891 Expression *retParm = new NameExpr( retval->get_name() ); 892 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 893 assignExpr->get_args().push_back( retParm ); 894 assignExpr->get_args().push_back( returnStmt->get_expr() ); 895 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 896 // } else { 897 // useRetval = true; 898 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) ); 899 // useRetval = false; 900 // } // if 901 returnStmt->set_expr( 0 ); 853 902 } else { 854 ret Stmt->set_expr( mutateExpression( retStmt->get_expr() ) );855 } // if 856 return ret Stmt;903 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 904 } // if 905 return returnStmt; 857 906 } 858 907 … … 905 954 } 906 955 } 907 // /deleteAll( functions );956 // deleteAll( functions ); 908 957 } 909 958 … … 949 998 TyVarMap oldtyVars = scopeTyVars; 950 999 makeTyVarMap( funcType, scopeTyVars ); 951 1000 1001 // move polymorphic return type to parameter list 952 1002 std::string typeName; 953 1003 if ( isPolyRet( funcType, typeName ) ) { … … 957 1007 funcType->get_returnVals().pop_front(); 958 1008 } 959 1009 1010 // add size/align and assertions for type parameters to parameter list 960 1011 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 961 1012 std::list< DeclarationWithType *> inferredParams; … … 985 1036 (*tyParm)->get_assertions().clear(); 986 1037 } 1038 1039 // add size/align for generic types to parameter list 1040 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen 1041 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1042 Type *parmType = (*fnParm)->get_type(); 1043 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) { 1044 std::string sizeName = sizeofName( parmType ); 1045 if ( seenTypes.count( sizeName ) ) continue; 1046 1047 ObjectDecl *sizeParm, *alignParm; 1048 sizeParm = newObj.clone(); 1049 sizeParm->set_name( sizeName ); 1050 last = funcType->get_parameters().insert( last, sizeParm ); 1051 ++last; 1052 1053 alignParm = newObj.clone(); 1054 alignParm->set_name( alignofName( parmType ) ); 1055 last = funcType->get_parameters().insert( last, alignParm ); 1056 ++last; 1057 1058 seenTypes.insert( sizeName ); 1059 } 1060 } 1061 1062 // splice assertion parameters into parameter list 987 1063 funcType->get_parameters().splice( last, inferredParams ); 988 1064 addAdapters( funcType );
Note:
See TracChangeset
for help on using the changeset viewer.