Changes in src/GenPoly/Box.cc [cf16f94:78dd0da]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rcf16f94 r78dd0da 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 … … 28 28 #include "Parser/ParseNode.h" 29 29 30 #include "SynTree/Constant.h" 30 31 #include "SynTree/Type.h" 31 32 #include "SynTree/Expression.h" … … 50 51 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 51 52 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 call 52 54 class Pass1 : public PolyMutator { 53 55 public: 54 56 Pass1(); 55 virtual Expression * 56 virtual Expression * 57 virtual Expression * 58 virtual DeclarationWithType 59 virtual TypeDecl * 60 virtual Expression * 61 virtual Expression * 62 virtual Statement * mutate( ReturnStmt *returnStmt);63 virtual Type * 64 virtual Type * mutate( FunctionType *functionType );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 ); 65 67 66 68 virtual void doBeginScope(); … … 88 90 }; 89 91 92 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 90 93 class Pass2 : public PolyMutator { 91 94 public: 92 Pass2();93 95 template< typename DeclClass > 94 96 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 105 107 }; 106 108 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 variable 107 110 class Pass3 : public PolyMutator { 108 111 public: … … 178 181 } 179 182 180 Pass1::Pass1() 181 : useRetval( false ), tempNamer( "_temp" ) { 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 182 184 adapters.push(AdapterMap()); 183 185 } … … 190 192 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 191 193 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 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 name = typeInst->get_name(); 195 return true; 198 196 } // if 199 197 } // if … … 313 311 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 314 312 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 // ***** 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; 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; 372 365 } 373 366 … … 424 417 Type *newType = formal->clone(); 425 418 std::list< FunctionType *> functions; 426 // instead of functions needing adapters, this really ought to look for any function mentioning a427 // polymorphic type419 // instead of functions needing adapters, this really ought to look for 420 // any function mentioning a polymorphic type 428 421 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 429 422 if ( ! functions.empty() ) { … … 647 640 } 648 641 649 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {642 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 650 643 NameExpr *opExpr; 651 644 if ( isIncr ) { … … 660 653 addAssign->get_args().push_back( appExpr->get_args().front() ); 661 654 } // if 662 addAssign->get_args().push_back( new NameExpr( polyName) );655 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 663 656 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 664 657 if ( appExpr->get_env() ) { … … 687 680 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 688 681 multiply->get_args().push_back( appExpr->get_args().back() ); 689 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );682 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) ); 690 683 ret->get_args().push_back( appExpr->get_args().front() ); 691 684 ret->get_args().push_back( multiply ); … … 693 686 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 694 687 multiply->get_args().push_back( appExpr->get_args().front() ); 695 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );688 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) ); 696 689 ret->get_args().push_back( multiply ); 697 690 ret->get_args().push_back( appExpr->get_args().back() ); … … 739 732 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 740 733 } // if 741 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst ->get_name(), varExpr->get_var()->get_name() == "?++" ) );734 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "?++" ) ); 742 735 return new CommaExpr( firstComma, tempExpr ); 743 736 } // if … … 746 739 assert( appExpr->get_args().size() == 1 ); 747 740 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 748 return makeIncrDecrExpr( appExpr, typeInst ->get_name(), varExpr->get_var()->get_name() == "++?" );741 return makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "++?" ); 749 742 } // if 750 743 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { … … 756 749 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 757 750 divide->get_args().push_back( appExpr ); 758 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );751 divide->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) ); 759 752 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 760 753 if ( appExpr->get_env() ) { … … 766 759 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 767 760 multiply->get_args().push_back( appExpr->get_args().back() ); 768 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );761 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) ); 769 762 appExpr->get_args().back() = multiply; 770 763 } else if ( typeInst2 ) { 771 764 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 772 765 multiply->get_args().push_back( appExpr->get_args().front() ); 773 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );766 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) ); 774 767 appExpr->get_args().front() = multiply; 775 768 } // if … … 781 774 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 782 775 multiply->get_args().push_back( appExpr->get_args().back() ); 783 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );776 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) ); 784 777 appExpr->get_args().back() = multiply; 785 778 } // if … … 863 856 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 864 857 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 } // if879 } // if880 } // if881 } // if882 } // if883 858 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 884 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) || needs) {859 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) { 885 860 Expression *ret = addrExpr->get_arg(); 886 861 delete ret->get_results().front(); … … 894 869 } 895 870 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 ); 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 ); 928 902 } else { 929 ret urnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );930 } // if 931 return ret urnStmt;903 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 904 } // if 905 return retStmt; 932 906 } 933 907 … … 962 936 963 937 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 964 965 Pass2::Pass2() {}966 938 967 939 void Pass2::addAdapters( FunctionType *functionType ) { … … 1037 1009 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1038 1010 std::list< DeclarationWithType *> inferredParams; 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 );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 ); 1041 1013 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1042 ObjectDecl * thisParm;1043 // add all size parameters to parameter list1014 ObjectDecl *sizeParm, *alignParm; 1015 // add all size and alignment parameters to parameter list 1044 1016 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1045 thisParm = newObj->clone(); 1046 thisParm->set_name( (*tyParm)->get_name() ); 1047 last = funcType->get_parameters().insert( last, thisParm ); 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 ); 1048 1027 ++last; 1049 1028 } 1050 1029 // move all assertions into parameter list 1051 1030 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1052 // /*assert = (*assert)->acceptMutator( *this );1031 // *assert = (*assert)->acceptMutator( *this ); 1053 1032 inferredParams.push_back( *assert ); 1054 1033 } 1055 1034 (*tyParm)->get_assertions().clear(); 1056 1035 } 1057 delete newObj;1058 1036 funcType->get_parameters().splice( last, inferredParams ); 1059 1037 addAdapters( funcType ); … … 1092 1070 1093 1071 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 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 );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 ); 1101 1079 1102 1080 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); … … 1127 1105 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1128 1106 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) { 1129 // change initialization of a polymorphic value object to allocate storage with alloca 1107 // change initialization of a polymorphic value object 1108 // to allocate storage with alloca 1130 1109 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1131 1110 assert( typeInst ); 1132 1111 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1133 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );1112 alloc->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) ); 1134 1113 1135 1114 delete objectDecl->get_init();
Note:
See TracChangeset
for help on using the changeset viewer.