Changes in src/GenPoly/Box.cc [78dd0da:cf16f94]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r78dd0da 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 … … 28 28 #include "Parser/ParseNode.h" 29 29 30 #include "SynTree/Constant.h"31 30 #include "SynTree/Type.h" 32 31 #include "SynTree/Expression.h" … … 51 50 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 52 51 53 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call54 52 class Pass1 : public PolyMutator { 55 53 public: 56 54 Pass1(); 57 virtual Expression * mutate( ApplicationExpr *appExpr );58 virtual Expression * mutate( AddressExpr *addrExpr );59 virtual Expression * mutate( UntypedExpr *expr );60 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );61 virtual TypeDecl * mutate( TypeDecl *typeDecl );62 virtual Expression * mutate( CommaExpr *commaExpr );63 virtual Expression * mutate( ConditionalExpr *condExpr );64 virtual Statement * mutate(ReturnStmt *catchStmt);65 virtual Type * mutate( PointerType *pointerType );66 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 ); 67 65 68 66 virtual void doBeginScope(); … … 90 88 }; 91 89 92 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well93 90 class Pass2 : public PolyMutator { 94 91 public: 92 Pass2(); 95 93 template< typename DeclClass > 96 94 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 107 105 }; 108 106 109 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable110 107 class Pass3 : public PolyMutator { 111 108 public: … … 181 178 } 182 179 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 180 Pass1::Pass1() 181 : useRetval( false ), tempNamer( "_temp" ) { 184 182 adapters.push(AdapterMap()); 185 183 } … … 192 190 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 193 191 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 194 name = typeInst->get_name(); 195 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 196 198 } // if 197 199 } // if … … 311 313 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 312 314 arg++; 313 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );314 arg++;315 315 } else { 316 316 throw SemanticError( "unbound type variable in application ", appExpr ); … … 344 344 345 345 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 346 if ( useRetval ) { 347 assert( retval ); 348 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 349 arg++; 350 } else { 351 ObjectDecl *newObj = makeTemporary( retType->clone() ); 352 Expression *paramExpr = new VariableExpr( newObj ); 353 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 354 paramExpr = new AddressExpr( paramExpr ); 355 } // if 356 arg = appExpr->get_args().insert( arg, paramExpr ); 357 arg++; 358 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 359 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 360 commaExpr->set_env( appExpr->get_env() ); 361 appExpr->set_env( 0 ); 362 return commaExpr; 363 } // if 364 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; 365 372 } 366 373 … … 417 424 Type *newType = formal->clone(); 418 425 std::list< FunctionType *> functions; 419 // instead of functions needing adapters, this really ought to look for 420 // any function mentioning apolymorphic type426 // instead of functions needing adapters, this really ought to look for any function mentioning a 427 // polymorphic type 421 428 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 422 429 if ( ! functions.empty() ) { … … 640 647 } 641 648 642 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {649 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 643 650 NameExpr *opExpr; 644 651 if ( isIncr ) { … … 653 660 addAssign->get_args().push_back( appExpr->get_args().front() ); 654 661 } // if 655 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType )) );662 addAssign->get_args().push_back( new NameExpr( polyName ) ); 656 663 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 657 664 if ( appExpr->get_env() ) { … … 680 687 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 681 688 multiply->get_args().push_back( appExpr->get_args().back() ); 682 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1) ) );689 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 683 690 ret->get_args().push_back( appExpr->get_args().front() ); 684 691 ret->get_args().push_back( multiply ); … … 686 693 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 687 694 multiply->get_args().push_back( appExpr->get_args().front() ); 688 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2) ) );695 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) ); 689 696 ret->get_args().push_back( multiply ); 690 697 ret->get_args().push_back( appExpr->get_args().back() ); … … 732 739 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 733 740 } // if 734 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst , varExpr->get_var()->get_name() == "?++" ) );741 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) ); 735 742 return new CommaExpr( firstComma, tempExpr ); 736 743 } // if … … 739 746 assert( appExpr->get_args().size() == 1 ); 740 747 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 741 return makeIncrDecrExpr( appExpr, typeInst , varExpr->get_var()->get_name() == "++?" );748 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" ); 742 749 } // if 743 750 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { … … 749 756 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 750 757 divide->get_args().push_back( appExpr ); 751 divide->get_args().push_back( new NameExpr( sizeofName( typeInst1) ) );758 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 752 759 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 753 760 if ( appExpr->get_env() ) { … … 759 766 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 760 767 multiply->get_args().push_back( appExpr->get_args().back() ); 761 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1) ) );768 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 762 769 appExpr->get_args().back() = multiply; 763 770 } else if ( typeInst2 ) { 764 771 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 765 772 multiply->get_args().push_back( appExpr->get_args().front() ); 766 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2) ) );773 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) ); 767 774 appExpr->get_args().front() = multiply; 768 775 } // if … … 774 781 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 775 782 multiply->get_args().push_back( appExpr->get_args().back() ); 776 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst) ) );783 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) ); 777 784 appExpr->get_args().back() = multiply; 778 785 } // if … … 856 863 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 857 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 858 883 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 859 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {884 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) || needs ) { 860 885 Expression *ret = addrExpr->get_arg(); 861 886 delete ret->get_results().front(); … … 869 894 } 870 895 871 Statement * Pass1::mutate(ReturnStmt *retStmt) { 872 // a cast expr on a polymorphic return value is either redundant or invalid 873 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 874 retStmt->set_expr( castExpr->get_arg() ); 875 retStmt->get_expr()->set_env( castExpr->get_env() ); 876 castExpr->set_env( 0 ); 877 castExpr->set_arg( 0 ); 878 delete castExpr; 879 } 880 if ( retval && retStmt->get_expr() ) { 881 assert( ! retStmt->get_expr()->get_results().empty() ); 882 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 883 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 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 ", retStmt->get_expr() ); 889 } // if 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( retStmt->get_expr() ); 895 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 896 } else { 897 useRetval = true; 898 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 899 useRetval = false; 900 } // if 901 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 ); 902 928 } else { 903 ret Stmt->set_expr( mutateExpression( retStmt->get_expr() ) );904 } // if 905 return ret Stmt;929 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 930 } // if 931 return returnStmt; 906 932 } 907 933 … … 936 962 937 963 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 964 965 Pass2::Pass2() {} 938 966 939 967 void Pass2::addAdapters( FunctionType *functionType ) { … … 1009 1037 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1010 1038 std::list< DeclarationWithType *> inferredParams; 1011 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );1012 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );1039 ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1040 /// ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1013 1041 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1014 ObjectDecl * sizeParm, *alignParm;1015 // add all size and alignmentparameters to parameter list1042 ObjectDecl *thisParm; 1043 // add all size parameters to parameter list 1016 1044 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1017 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1018 1019 sizeParm = newObj.clone(); 1020 sizeParm->set_name( sizeofName( &parmType ) ); 1021 last = funcType->get_parameters().insert( last, sizeParm ); 1022 ++last; 1023 1024 alignParm = newObj.clone(); 1025 alignParm->set_name( alignofName( &parmType ) ); 1026 last = funcType->get_parameters().insert( last, alignParm ); 1045 thisParm = newObj->clone(); 1046 thisParm->set_name( (*tyParm)->get_name() ); 1047 last = funcType->get_parameters().insert( last, thisParm ); 1027 1048 ++last; 1028 1049 } 1029 1050 // move all assertions into parameter list 1030 1051 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1031 // *assert = (*assert)->acceptMutator( *this );1052 /// *assert = (*assert)->acceptMutator( *this ); 1032 1053 inferredParams.push_back( *assert ); 1033 1054 } 1034 1055 (*tyParm)->get_assertions().clear(); 1035 1056 } 1057 delete newObj; 1036 1058 funcType->get_parameters().splice( last, inferredParams ); 1037 1059 addAdapters( funcType ); … … 1070 1092 1071 1093 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1072 // Initializer *init = 0;1073 // std::list< Expression *> designators;1074 // scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();1075 // if ( typeDecl->get_base() ) {1076 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );1077 // }1078 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );1094 /// Initializer *init = 0; 1095 /// std::list< Expression *> designators; 1096 /// scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1097 /// if ( typeDecl->get_base() ) { 1098 /// init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1099 /// } 1100 /// return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1079 1101 1080 1102 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); … … 1105 1127 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1106 1128 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) { 1107 // change initialization of a polymorphic value object 1108 // to allocate storage with alloca 1129 // change initialization of a polymorphic value object to allocate storage with alloca 1109 1130 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1110 1131 assert( typeInst ); 1111 1132 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1112 alloc->get_args().push_back( new NameExpr( sizeofName( typeInst) ) );1133 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) ); 1113 1134 1114 1135 delete objectDecl->get_init();
Note:
See TracChangeset
for help on using the changeset viewer.