Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rffad73a r69911c11  
    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
     
    6262                        virtual Expression *mutate( CommaExpr *commaExpr );
    6363                        virtual Expression *mutate( ConditionalExpr *condExpr );
    64                         virtual Statement *mutate(ReturnStmt *catchStmt);
     64                        virtual Statement * mutate( ReturnStmt *returnStmt );
    6565                        virtual Type *mutate( PointerType *pointerType );
    66                         virtual Type *mutate( FunctionType *pointerType );
     66                        virtual Type * mutate( FunctionType *functionType );
    6767 
    6868                        virtual void doBeginScope();
     
    192192                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    193193                                                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    194                                                                         name = typeInst->get_name();
    195                                                                         return true;
     194                                                                        if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
     195                                                                                if ( typeInst->get_name() == typeInst2->get_name() ) {
     196                                                                                        name = typeInst->get_name();
     197                                                                                        return true;
     198                                                                                } // if
     199                                                                        } // if
    196200                                                                } // if
    197201                                                        } // if
     
    277281
    278282                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    279 ///     std::cerr << "add " << typeDecl->get_name() << "\n";
    280283                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    281284                        return Mutator::mutate( typeDecl );
     
    303306
    304307                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     308                        // pass size/align for type variables
    305309                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    306310                                ResolvExpr::EqvClass eqvClass;
     
    318322                                } // if
    319323                        } // for
     324
     325                        // add size/align for generic types to parameter list
     326                        //assert( ! appExpr->get_function()->get_results().empty() );
     327                        if ( appExpr->get_function()->get_results().empty() ) return;
     328                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     329                        assert( funcType );
     330                       
     331                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
     332                        std::list< Expression* >::const_iterator fnArg = arg;
     333                        std::set< std::string > seenTypes; //< names for generic types we've seen
     334                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     335                                Type *parmType = (*fnParm)->get_type();
     336                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
     337                                        std::string sizeName = sizeofName( parmType );
     338                                        if ( seenTypes.count( sizeName ) ) continue;
     339
     340                                        assert( ! (*fnArg)->get_results().empty() );
     341                                        Type *argType = (*fnArg)->get_results().front();
     342                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
     343                                        arg++;
     344                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
     345                                        arg++;
     346
     347                                        seenTypes.insert( sizeName );
     348                                }
     349                        }
    320350                }
    321351
     
    327357
    328358                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
    329                         if ( useRetval ) {
    330                                 assert( retval );
    331                                 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    332                                 arg++;
    333                         } else {
    334                                 ObjectDecl *newObj = makeTemporary( retType->clone() );
    335                                 Expression *paramExpr = new VariableExpr( newObj );
    336                                 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
    337                                         paramExpr = new AddressExpr( paramExpr );
    338                                 } // if
    339                                 arg = appExpr->get_args().insert( arg, paramExpr );
    340                                 arg++;
    341 ///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
    342                                 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
    343                                 commaExpr->set_env( appExpr->get_env() );
    344                                 appExpr->set_env( 0 );
    345                                 return commaExpr;
    346                         } // if
    347                         return appExpr;
     359                        // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
     360                        // if ( useRetval ) {
     361                        //      assert( retval );
     362                        //      arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
     363                        //      arg++;
     364                        // } else {
     365
     366                        // Create temporary to hold return value of polymorphic function and produce that temporary as a result
     367                        // using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
     368                        // return values.
     369                        ObjectDecl *newObj = makeTemporary( retType->clone() );
     370                        Expression *paramExpr = new VariableExpr( newObj );
     371                        // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
     372                        // temporary is already boxed and can be used directly.
     373                        if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
     374                                paramExpr = new AddressExpr( paramExpr );
     375                        } // if
     376                        arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
     377                        arg++;
     378                        // Build a comma expression to call the function and emulate a normal return.
     379                        CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
     380                        commaExpr->set_env( appExpr->get_env() );
     381                        appExpr->set_env( 0 );
     382                        return commaExpr;
     383                        // } // if
     384                        // return appExpr;
    348385                }
    349386
     
    411448
    412449                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    413 ///   std::cout << "function is ";
    414 ///   function->print( std::cout );
    415450                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    416 ///     std::cout << "parameter is ";
    417 ///     (*param)->print( std::fcout );
    418 ///     std::cout << std::endl << "argument is ";
    419 ///     (*arg)->print( std::cout );
    420451                                assert( arg != appExpr->get_args().end() );
    421452                                addCast( *arg, (*param)->get_type(), exprTyVars );
     
    807838                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    808839                        assert( ! addrExpr->get_arg()->get_results().empty() );
     840
     841                        bool needs = false;
     842                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
     843                                if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
     844                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     845                                                if ( name->get_name() == "*?" ) {
     846                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
     847                                                                assert( ! appExpr->get_function()->get_results().empty() );
     848                                                                PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     849                                                                assert( pointer );
     850                                                                FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
     851                                                                assert( function );
     852                                                                needs = needsAdapter( function, scopeTyVars );
     853                                                        } // if
     854                                                } // if
     855                                        } // if
     856                                } // if
     857                        } // if
    809858                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    810                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) {
     859                        if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
    811860                                Expression *ret = addrExpr->get_arg();
    812861                                delete ret->get_results().front();
     
    820869                }
    821870
    822                 Statement * Pass1::mutate(ReturnStmt *retStmt) {
    823                         // a cast expr on a polymorphic return value is either redundant or invalid
    824                         while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
    825                                 retStmt->set_expr( castExpr->get_arg() );
    826                                 retStmt->get_expr()->set_env( castExpr->get_env() );
    827                                 castExpr->set_env( 0 );
    828                                 castExpr->set_arg( 0 );
    829                                 delete castExpr;
    830                         }
    831                         if ( retval && retStmt->get_expr() ) {
    832                                 assert( ! retStmt->get_expr()->get_results().empty() );
    833                                 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    834 ///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    835                                         TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
    836                                         assert( typeInst );
    837                                         std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    838                                         if ( assignIter == assignOps.end() ) {
    839                                                 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
    840                                         } // if
    841                                         ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    842                                         Expression *retParm = new NameExpr( retval->get_name() );
    843                                         retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    844                                         assignExpr->get_args().push_back( retParm );
    845                                         assignExpr->get_args().push_back( retStmt->get_expr() );
    846                                         stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    847                                 } else {
    848                                         useRetval = true;
    849                                         stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
    850                                         useRetval = false;
     871                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
     872                        if ( retval && returnStmt->get_expr() ) {
     873                                assert( ! returnStmt->get_expr()->get_results().empty() );
     874                                // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
     875                                // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     876                                // a cast expr on a polymorphic return value is either redundant or invalid
     877                                while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
     878                                        returnStmt->set_expr( castExpr->get_arg() );
     879                                        returnStmt->get_expr()->set_env( castExpr->get_env() );
     880                                        castExpr->set_env( 0 );
     881                                        castExpr->set_arg( 0 );
     882                                        delete castExpr;
     883                                } //while
     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 ", returnStmt->get_expr() );
    851889                                } // if
    852                                 retStmt->set_expr( 0 );
     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( returnStmt->get_expr() );
     895                                stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
     896                                // } else {
     897                                //      useRetval = true;
     898                                //      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
     899                                //      useRetval = false;
     900                                // } // if
     901                                returnStmt->set_expr( 0 );
    853902                        } else {
    854                                 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    855                         } // if
    856                         return retStmt;
     903                                returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     904                        } // if
     905                        return returnStmt;
    857906                }
    858907
     
    905954                                }
    906955                        }
    907 ///  deleteAll( functions );
     956//  deleteAll( functions );
    908957                }
    909958
     
    949998                        TyVarMap oldtyVars = scopeTyVars;
    950999                        makeTyVarMap( funcType, scopeTyVars );
    951  
     1000
     1001                        // move polymorphic return type to parameter list
    9521002                        std::string typeName;
    9531003                        if ( isPolyRet( funcType, typeName ) ) {
     
    9571007                                funcType->get_returnVals().pop_front();
    9581008                        }
    959  
     1009
     1010                        // add size/align and assertions for type parameters to parameter list
    9601011                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    9611012                        std::list< DeclarationWithType *> inferredParams;
     
    9851036                                (*tyParm)->get_assertions().clear();
    9861037                        }
     1038
     1039                        // add size/align for generic types to parameter list
     1040                        std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1041                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     1042                                Type *parmType = (*fnParm)->get_type();
     1043                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
     1044                                        std::string sizeName = sizeofName( parmType );
     1045                                        if ( seenTypes.count( sizeName ) ) continue;
     1046                                       
     1047                                        ObjectDecl *sizeParm, *alignParm;
     1048                                        sizeParm = newObj.clone();
     1049                                        sizeParm->set_name( sizeName );
     1050                                        last = funcType->get_parameters().insert( last, sizeParm );
     1051                                        ++last;
     1052
     1053                                        alignParm = newObj.clone();
     1054                                        alignParm->set_name( alignofName( parmType ) );
     1055                                        last = funcType->get_parameters().insert( last, alignParm );
     1056                                        ++last;
     1057
     1058                                        seenTypes.insert( sizeName );
     1059                                }
     1060                        }
     1061
     1062                        // splice assertion parameters into parameter list
    9871063                        funcType->get_parameters().splice( last, inferredParams );
    9881064                        addAdapters( funcType );
Note: See TracChangeset for help on using the changeset viewer.