Changeset cf16f94 for src/GenPoly


Ignore:
Timestamp:
Dec 15, 2015, 4:09:13 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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
Message:

create temporary return variable for return expressions, remove unnecessary code after temporary-return-variable change, fix missing lvalue qualifiers, change stream operator to |

Location:
src/GenPoly
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rb0b958a 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
     
    5353                  public:
    5454                        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 );
    6565 
    6666                        virtual void doBeginScope();
     
    190190                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    191191                                                                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
    194198                                                                } // if
    195199                                                        } // if
     
    340344
    341345                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;
    361372                }
    362373
     
    413424                        Type *newType = formal->clone();
    414425                        std::list< FunctionType *> functions;
    415                         // instead of functions needing adapters, this really ought to look for
    416                         // 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
    417428                        findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    418429                        if ( ! functions.empty() ) {
     
    852863                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    853864                        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
    854883                        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 ) {
    856885                                Expression *ret = addrExpr->get_arg();
    857886                                delete ret->get_results().front();
     
    865894                }
    866895
    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 );
    898928                        } else {
    899                                 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    900                         } // if
    901                         return retStmt;
     929                                returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     930                        } // if
     931                        return returnStmt;
    902932                }
    903933
     
    10971127                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    10981128                                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
    11011130                                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
    11021131                                        assert( typeInst );
  • src/GenPoly/GenPoly.cc

    rb0b958a 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 : Tue Nov 24 15:23:08 2015
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Dec  1 15:18:54 2015
     13// Update Count     : 12
    1414//
    1515
     
    2121
    2222namespace 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
    2524        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    2625                if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
  • src/GenPoly/Lvalue.cc

    rb0b958a rcf16f94  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 07:41:33 2015
    13 // Update Count     : 1
     12// Last Modified On : Tue Dec 15 15:33:13 2015
     13// Update Count     : 3
    1414//
    1515
     
    120120                        if ( retval && retStmt->get_expr() ) {
    121121                                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                                 } // while
    129122                                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
    130133                                        retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
    131134                                } else {
Note: See TracChangeset for help on using the changeset viewer.