Changeset cf16f94 for src/GenPoly
- Timestamp:
- Dec 15, 2015, 4:09:13 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:
- 4389966
- Parents:
- b0b958a
- Location:
- src/GenPoly
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rb0b958a rcf16f94 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 … … 53 53 public: 54 54 Pass1(); 55 virtual Expression * mutate( ApplicationExpr *appExpr );56 virtual Expression * mutate( AddressExpr *addrExpr );57 virtual Expression * mutate( UntypedExpr *expr );58 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );59 virtual TypeDecl * mutate( TypeDecl *typeDecl );60 virtual Expression * mutate( CommaExpr *commaExpr );61 virtual Expression * mutate( ConditionalExpr *condExpr );62 virtual Statement * mutate(ReturnStmt *catchStmt);63 virtual Type * mutate( PointerType *pointerType );64 virtual Type * mutate( FunctionType *pointerType );55 virtual Expression * mutate( ApplicationExpr *appExpr ); 56 virtual Expression * mutate( AddressExpr *addrExpr ); 57 virtual Expression * mutate( UntypedExpr *expr ); 58 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 59 virtual TypeDecl * mutate( TypeDecl *typeDecl ); 60 virtual Expression * mutate( CommaExpr *commaExpr ); 61 virtual Expression * mutate( ConditionalExpr *condExpr ); 62 virtual Statement * mutate( ReturnStmt *returnStmt ); 63 virtual Type * mutate( PointerType *pointerType ); 64 virtual Type * mutate( FunctionType *functionType ); 65 65 66 66 virtual void doBeginScope(); … … 190 190 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 191 191 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 192 name = typeInst->get_name(); 193 return true; 192 if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 193 if ( typeInst->get_name() == typeInst2->get_name() ) { 194 name = typeInst->get_name(); 195 return true; 196 } // if 197 } // if 194 198 } // if 195 199 } // if … … 340 344 341 345 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 342 if ( useRetval ) { 343 assert( retval ); 344 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 345 arg++; 346 } else { 347 ObjectDecl *newObj = makeTemporary( retType->clone() ); 348 Expression *paramExpr = new VariableExpr( newObj ); 349 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 350 paramExpr = new AddressExpr( paramExpr ); 351 } // if 352 arg = appExpr->get_args().insert( arg, paramExpr ); 353 arg++; 354 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 355 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 356 commaExpr->set_env( appExpr->get_env() ); 357 appExpr->set_env( 0 ); 358 return commaExpr; 359 } // if 360 return appExpr; 346 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 347 // if ( useRetval ) { 348 // assert( retval ); 349 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 350 // arg++; 351 // } else { 352 353 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 354 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple 355 // return values. 356 ObjectDecl *newObj = makeTemporary( retType->clone() ); 357 Expression *paramExpr = new VariableExpr( newObj ); 358 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 359 // temporary is already boxed and can be used directly. 360 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 361 paramExpr = new AddressExpr( paramExpr ); 362 } // if 363 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call 364 arg++; 365 // Build a comma expression to call the function and emulate a normal return. 366 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 367 commaExpr->set_env( appExpr->get_env() ); 368 appExpr->set_env( 0 ); 369 return commaExpr; 370 // } // if 371 // return appExpr; 361 372 } 362 373 … … 413 424 Type *newType = formal->clone(); 414 425 std::list< FunctionType *> functions; 415 // instead of functions needing adapters, this really ought to look for 416 // any function mentioning apolymorphic type426 // instead of functions needing adapters, this really ought to look for any function mentioning a 427 // polymorphic type 417 428 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 418 429 if ( ! functions.empty() ) { … … 852 863 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 853 864 assert( ! addrExpr->get_arg()->get_results().empty() ); 865 866 bool needs = false; 867 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 868 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) { 869 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 870 if ( name->get_name() == "*?" ) { 871 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 872 assert( ! appExpr->get_function()->get_results().empty() ); 873 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 874 assert( pointer ); 875 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 876 assert( function ); 877 needs = needsAdapter( function, scopeTyVars ); 878 } // if 879 } // if 880 } // if 881 } // if 882 } // if 854 883 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 855 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {884 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) || needs ) { 856 885 Expression *ret = addrExpr->get_arg(); 857 886 delete ret->get_results().front(); … … 865 894 } 866 895 867 Statement * Pass1::mutate(ReturnStmt *retStmt) { 868 // a cast expr on a polymorphic return value is either redundant or invalid 869 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 870 retStmt->set_expr( castExpr->get_arg() ); 871 retStmt->get_expr()->set_env( castExpr->get_env() ); 872 castExpr->set_env( 0 ); 873 castExpr->set_arg( 0 ); 874 delete castExpr; 875 } 876 if ( retval && retStmt->get_expr() ) { 877 assert( ! retStmt->get_expr()->get_results().empty() ); 878 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 879 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 880 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 881 assert( typeInst ); 882 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 883 if ( assignIter == assignOps.end() ) { 884 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 885 } // if 886 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 887 Expression *retParm = new NameExpr( retval->get_name() ); 888 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 889 assignExpr->get_args().push_back( retParm ); 890 assignExpr->get_args().push_back( retStmt->get_expr() ); 891 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 892 } else { 893 useRetval = true; 894 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 895 useRetval = false; 896 } // if 897 retStmt->set_expr( 0 ); 896 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 897 if ( retval && returnStmt->get_expr() ) { 898 assert( ! returnStmt->get_expr()->get_results().empty() ); 899 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 900 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { 901 // a cast expr on a polymorphic return value is either redundant or invalid 902 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) { 903 returnStmt->set_expr( castExpr->get_arg() ); 904 returnStmt->get_expr()->set_env( castExpr->get_env() ); 905 castExpr->set_env( 0 ); 906 castExpr->set_arg( 0 ); 907 delete castExpr; 908 } // while 909 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 910 assert( typeInst ); 911 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 912 if ( assignIter == assignOps.end() ) { 913 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 914 } // if 915 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 916 Expression *retParm = new NameExpr( retval->get_name() ); 917 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 918 assignExpr->get_args().push_back( retParm ); 919 assignExpr->get_args().push_back( returnStmt->get_expr() ); 920 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 921 // } else { 922 // std::cerr << "THOMAS " << std::endl; 923 // useRetval = true; 924 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) ); 925 // useRetval = false; 926 // } // if 927 returnStmt->set_expr( 0 ); 898 928 } else { 899 ret Stmt->set_expr( mutateExpression( retStmt->get_expr() ) );900 } // if 901 return ret Stmt;929 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 930 } // if 931 return returnStmt; 902 932 } 903 933 … … 1097 1127 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1098 1128 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) { 1099 // change initialization of a polymorphic value object 1100 // to allocate storage with alloca 1129 // change initialization of a polymorphic value object to allocate storage with alloca 1101 1130 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1102 1131 assert( typeInst ); -
src/GenPoly/GenPoly.cc
rb0b958a rcf16f94 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 : Tue Nov 24 15:23:08201513 // Update Count : 1 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 1 15:18:54 2015 13 // Update Count : 12 14 14 // 15 15 … … 21 21 22 22 namespace GenPoly { 23 // A function needs an adapter if it returns a polymorphic value or if any of its 24 // parameters have polymorphic type 23 // A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type 25 24 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 26 25 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { -
src/GenPoly/Lvalue.cc
rb0b958a rcf16f94 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:41:33 201513 // Update Count : 112 // Last Modified On : Tue Dec 15 15:33:13 2015 13 // Update Count : 3 14 14 // 15 15 … … 120 120 if ( retval && retStmt->get_expr() ) { 121 121 assert( ! retStmt->get_expr()->get_results().empty() ); 122 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {123 retStmt->set_expr( castExpr->get_arg() );124 retStmt->get_expr()->set_env( castExpr->get_env() );125 castExpr->set_env( 0 );126 castExpr->set_arg( 0 );127 delete castExpr;128 } // while129 122 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 123 // ***** Code Removal ***** because casts may be stripped already 124 125 // strip casts because not allowed to take address of cast 126 // while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) { 127 // retStmt->set_expr( castExpr->get_arg() ); 128 // retStmt->get_expr()->set_env( castExpr->get_env() ); 129 // castExpr->set_env( 0 ); 130 // castExpr->set_arg( 0 ); 131 // delete castExpr; 132 // } // while 130 133 retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) ); 131 134 } else {
Note: See TracChangeset
for help on using the changeset viewer.