Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rcf16f94 r78dd0da  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 15:30:31 2015
    13 // Update Count     : 215
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Nov 26 17:01:55 2015
     13// Update Count     : 191
    1414//
    1515
     
    2828#include "Parser/ParseNode.h"
    2929
     30#include "SynTree/Constant.h"
    3031#include "SynTree/Type.h"
    3132#include "SynTree/Expression.h"
     
    5051                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5152
     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
    5254                class Pass1 : public PolyMutator {
    5355                  public:
    5456                        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 *returnStmt );
    63                         virtual Type * mutate( PointerType *pointerType );
    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 );
    6567 
    6668                        virtual void doBeginScope();
     
    8890                };
    8991
     92                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    9093                class Pass2 : public PolyMutator {
    9194                  public:
    92                         Pass2();
    9395                        template< typename DeclClass >
    9496                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    105107                };
    106108
     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
    107110                class Pass3 : public PolyMutator {
    108111                  public:
     
    178181                }
    179182
    180                 Pass1::Pass1()
    181                         : useRetval( false ), tempNamer( "_temp" ) {
     183                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    182184                        adapters.push(AdapterMap());
    183185                }
     
    190192                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    191193                                                                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;
    198196                                                                } // if
    199197                                                        } // if
     
    313311                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    314312                                                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                         // ***** 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;
    372365                }
    373366
     
    424417                        Type *newType = formal->clone();
    425418                        std::list< FunctionType *> functions;
    426                         // instead of functions needing adapters, this really ought to look for any function mentioning a
    427                         // polymorphic type
     419                        // instead of functions needing adapters, this really ought to look for
     420                        // any function mentioning a polymorphic type
    428421                        findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    429422                        if ( ! functions.empty() ) {
     
    647640                }
    648641
    649                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     642                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    650643                        NameExpr *opExpr;
    651644                        if ( isIncr ) {
     
    660653                                addAssign->get_args().push_back( appExpr->get_args().front() );
    661654                        } // if
    662                         addAssign->get_args().push_back( new NameExpr( polyName ) );
     655                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    663656                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    664657                        if ( appExpr->get_env() ) {
     
    687680                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    688681                                                        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 ) ) );
    690683                                                        ret->get_args().push_back( appExpr->get_args().front() );
    691684                                                        ret->get_args().push_back( multiply );
     
    693686                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    694687                                                        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 ) ) );
    696689                                                        ret->get_args().push_back( multiply );
    697690                                                        ret->get_args().push_back( appExpr->get_args().back() );
     
    739732                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    740733                                                        } // 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() == "?++" ) );
    742735                                                        return new CommaExpr( firstComma, tempExpr );
    743736                                                } // if
     
    746739                                                assert( appExpr->get_args().size() == 1 );
    747740                                                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() == "++?" );
    749742                                                } // if
    750743                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
     
    756749                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    757750                                                        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 ) ) );
    759752                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    760753                                                        if ( appExpr->get_env() ) {
     
    766759                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    767760                                                        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 ) ) );
    769762                                                        appExpr->get_args().back() = multiply;
    770763                                                } else if ( typeInst2 ) {
    771764                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    772765                                                        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 ) ) );
    774767                                                        appExpr->get_args().front() = multiply;
    775768                                                } // if
     
    781774                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    782775                                                        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 ) ) );
    784777                                                        appExpr->get_args().back() = multiply;
    785778                                                } // if
     
    863856                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    864857                        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
    883858                        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 ) ) {
    885860                                Expression *ret = addrExpr->get_arg();
    886861                                delete ret->get_results().front();
     
    894869                }
    895870
    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 );
    928902                        } else {
    929                                 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
    930                         } // if
    931                         return returnStmt;
     903                                retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
     904                        } // if
     905                        return retStmt;
    932906                }
    933907
     
    962936
    963937////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    964 
    965                 Pass2::Pass2() {}
    966938
    967939                void Pass2::addAdapters( FunctionType *functionType ) {
     
    10371009                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    10381010                        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 );
    10411013                        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 list
     1014                                ObjectDecl *sizeParm, *alignParm;
     1015                                // add all size and alignment parameters to parameter list
    10441016                                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 );
    10481027                                        ++last;
    10491028                                }
    10501029                                // move all assertions into parameter list
    10511030                                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 );
    10531032                                        inferredParams.push_back( *assert );
    10541033                                }
    10551034                                (*tyParm)->get_assertions().clear();
    10561035                        }
    1057                         delete newObj;
    10581036                        funcType->get_parameters().splice( last, inferredParams );
    10591037                        addAdapters( funcType );
     
    10921070
    10931071                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 );
    11011079
    11021080                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     
    11271105                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    11281106                                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
    11301109                                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
    11311110                                        assert( typeInst );
    11321111                                        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 ) ) );
    11341113
    11351114                                        delete objectDecl->get_init();
Note: See TracChangeset for help on using the changeset viewer.