Changes in src/GenPoly/Box.cc [69911c11:ffad73a]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r69911c11 rffad73a 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 : T ue Dec 15 15:30:31201513 // Update Count : 21511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Nov 26 17:01:55 2015 13 // Update Count : 191 14 14 // 15 15 … … 62 62 virtual Expression *mutate( CommaExpr *commaExpr ); 63 63 virtual Expression *mutate( ConditionalExpr *condExpr ); 64 virtual Statement * mutate( ReturnStmt *returnStmt);64 virtual Statement *mutate(ReturnStmt *catchStmt); 65 65 virtual Type *mutate( PointerType *pointerType ); 66 virtual Type * mutate( FunctionType *functionType );66 virtual Type *mutate( FunctionType *pointerType ); 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 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 194 name = typeInst->get_name(); 195 return true; 200 196 } // if 201 197 } // if … … 281 277 282 278 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 279 /// std::cerr << "add " << typeDecl->get_name() << "\n"; 283 280 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 284 281 return Mutator::mutate( typeDecl ); … … 306 303 307 304 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 308 // pass size/align for type variables309 305 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 310 306 ResolvExpr::EqvClass eqvClass; … … 322 318 } // if 323 319 } // for 324 325 // add size/align for generic types to parameter list326 //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 seen334 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 }350 320 } 351 321 … … 357 327 358 328 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 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; 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; 385 348 } 386 349 … … 448 411 449 412 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 ); 450 415 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 ); 451 420 assert( arg != appExpr->get_args().end() ); 452 421 addCast( *arg, (*param)->get_type(), exprTyVars ); … … 838 807 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 839 808 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 } // if854 } // if855 } // if856 } // if857 } // if858 809 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 859 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs) {810 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) { 860 811 Expression *ret = addrExpr->get_arg(); 861 812 delete ret->get_results().front(); … … 869 820 } 870 821 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 invalid877 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() );889 } // if890 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 //} // if901 ret urnStmt->set_expr( 0 );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; 851 } // if 852 retStmt->set_expr( 0 ); 902 853 } else { 903 ret urnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );904 } // if 905 return ret urnStmt;854 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 855 } // if 856 return retStmt; 906 857 } 907 858 … … 954 905 } 955 906 } 956 // deleteAll( functions );907 /// deleteAll( functions ); 957 908 } 958 909 … … 998 949 TyVarMap oldtyVars = scopeTyVars; 999 950 makeTyVarMap( funcType, scopeTyVars ); 1000 1001 // move polymorphic return type to parameter list 951 1002 952 std::string typeName; 1003 953 if ( isPolyRet( funcType, typeName ) ) { … … 1007 957 funcType->get_returnVals().pop_front(); 1008 958 } 1009 1010 // add size/align and assertions for type parameters to parameter list 959 1011 960 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1012 961 std::list< DeclarationWithType *> inferredParams; … … 1036 985 (*tyParm)->get_assertions().clear(); 1037 986 } 1038 1039 // add size/align for generic types to parameter list1040 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen1041 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 list1063 987 funcType->get_parameters().splice( last, inferredParams ); 1064 988 addAdapters( funcType );
Note:
See TracChangeset
for help on using the changeset viewer.