Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r78dd0da rcf16f94  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Nov 26 17:01:55 2015
    13 // Update Count     : 191
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Dec 15 15:30:31 2015
     13// Update Count     : 215
    1414//
    1515
     
    2828#include "Parser/ParseNode.h"
    2929
    30 #include "SynTree/Constant.h"
    3130#include "SynTree/Type.h"
    3231#include "SynTree/Expression.h"
     
    5150                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5251
    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
    5452                class Pass1 : public PolyMutator {
    5553                  public:
    5654                        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 );
    6765 
    6866                        virtual void doBeginScope();
     
    9088                };
    9189
    92                 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    9390                class Pass2 : public PolyMutator {
    9491                  public:
     92                        Pass2();
    9593                        template< typename DeclClass >
    9694                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    107105                };
    108106
    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
    110107                class Pass3 : public PolyMutator {
    111108                  public:
     
    181178                }
    182179
    183                 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
     180                Pass1::Pass1()
     181                        : useRetval( false ), tempNamer( "_temp" ) {
    184182                        adapters.push(AdapterMap());
    185183                }
     
    192190                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    193191                                                                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
    196198                                                                } // if
    197199                                                        } // if
     
    311313                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    312314                                                arg++;
    313                                                 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
    314                                                 arg++;
    315315                                        } else {
    316316                                                throw SemanticError( "unbound type variable in application ", appExpr );
     
    344344
    345345                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;
    365372                }
    366373
     
    417424                        Type *newType = formal->clone();
    418425                        std::list< FunctionType *> functions;
    419                         // instead of functions needing adapters, this really ought to look for
    420                         // any function mentioning a polymorphic type
     426                        // instead of functions needing adapters, this really ought to look for any function mentioning a
     427                        // polymorphic type
    421428                        findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    422429                        if ( ! functions.empty() ) {
     
    640647                }
    641648
    642                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
     649                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
    643650                        NameExpr *opExpr;
    644651                        if ( isIncr ) {
     
    653660                                addAssign->get_args().push_back( appExpr->get_args().front() );
    654661                        } // if
    655                         addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
     662                        addAssign->get_args().push_back( new NameExpr( polyName ) );
    656663                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    657664                        if ( appExpr->get_env() ) {
     
    680687                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    681688                                                        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() ) );
    683690                                                        ret->get_args().push_back( appExpr->get_args().front() );
    684691                                                        ret->get_args().push_back( multiply );
     
    686693                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    687694                                                        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() ) );
    689696                                                        ret->get_args().push_back( multiply );
    690697                                                        ret->get_args().push_back( appExpr->get_args().back() );
     
    732739                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    733740                                                        } // 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() == "?++" ) );
    735742                                                        return new CommaExpr( firstComma, tempExpr );
    736743                                                } // if
     
    739746                                                assert( appExpr->get_args().size() == 1 );
    740747                                                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() == "++?" );
    742749                                                } // if
    743750                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
     
    749756                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    750757                                                        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() ) );
    752759                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    753760                                                        if ( appExpr->get_env() ) {
     
    759766                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    760767                                                        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() ) );
    762769                                                        appExpr->get_args().back() = multiply;
    763770                                                } else if ( typeInst2 ) {
    764771                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    765772                                                        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() ) );
    767774                                                        appExpr->get_args().front() = multiply;
    768775                                                } // if
     
    774781                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    775782                                                        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() ) );
    777784                                                        appExpr->get_args().back() = multiply;
    778785                                                } // if
     
    856863                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    857864                        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
    858883                        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 ) {
    860885                                Expression *ret = addrExpr->get_arg();
    861886                                delete ret->get_results().front();
     
    869894                }
    870895
    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 );
    902928                        } else {
    903                                 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    904                         } // if
    905                         return retStmt;
     929                                returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     930                        } // if
     931                        return returnStmt;
    906932                }
    907933
     
    936962
    937963////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
     964
     965                Pass2::Pass2() {}
    938966
    939967                void Pass2::addAdapters( FunctionType *functionType ) {
     
    10091037                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    10101038                        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 );
    10131041                        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 alignment parameters to parameter list
     1042                                ObjectDecl *thisParm;
     1043                                // add all size parameters to parameter list
    10161044                                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 );
    10271048                                        ++last;
    10281049                                }
    10291050                                // move all assertions into parameter list
    10301051                                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 );
    10321053                                        inferredParams.push_back( *assert );
    10331054                                }
    10341055                                (*tyParm)->get_assertions().clear();
    10351056                        }
     1057                        delete newObj;
    10361058                        funcType->get_parameters().splice( last, inferredParams );
    10371059                        addAdapters( funcType );
     
    10701092
    10711093                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 );
    10791101
    10801102                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     
    11051127                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    11061128                                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
    11091130                                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
    11101131                                        assert( typeInst );
    11111132                                        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() ) );
    11131134
    11141135                                        delete objectDecl->get_init();
Note: See TracChangeset for help on using the changeset viewer.