Ignore:
Timestamp:
Nov 8, 2017, 5:43:33 PM (8 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
954908d
Parents:
78315272 (diff), e35f30a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Specialize.cc

    r78315272 r3f7e12cb  
    2222#include <utility>                       // for pair
    2323
     24#include "Common/PassVisitor.h"
    2425#include "Common/SemanticError.h"        // for SemanticError
    2526#include "Common/UniqueName.h"           // for UniqueName
     
    2829#include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    2930#include "Parser/LinkageSpec.h"          // for C
    30 #include "PolyMutator.h"                 // for PolyMutator
    3131#include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    3232#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     
    4343
    4444namespace GenPoly {
    45         class Specialize final : public PolyMutator {
    46           public:
    47                 using PolyMutator::mutate;
    48                 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override;
    49                 virtual Expression * mutate( AddressExpr *castExpr ) override;
    50                 virtual Expression * mutate( CastExpr *castExpr ) override;
    51                 // virtual Expression * mutate( LogicalExpr *logicalExpr );
    52                 // virtual Expression * mutate( ConditionalExpr *conditionalExpr );
    53                 // virtual Expression * mutate( CommaExpr *commaExpr );
     45        struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
     46                Expression * postmutate( ApplicationExpr *applicationExpr );
     47                Expression * postmutate( CastExpr *castExpr );
    5448
    5549                void handleExplicitParams( ApplicationExpr *appExpr );
    5650                Expression * createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams );
    57                 Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = nullptr );
     51                Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams );
    5852
    5953                std::string paramPrefix = "_p";
     
    7266                                if ( ! boundType ) continue;
    7367                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) {
     68                                        // bound to another type variable
    7469                                        if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) {
     70                                                // bound to a closed variable => must specialize
    7571                                                return true;
    7672                                        } // if
    7773                                } else {
     74                                        // variable is bound to a concrete type => must specialize
    7875                                        return true;
    7976                                } // if
    8077                        } // for
     78                        // none of the type variables are bound
    8179                        return false;
    8280                } else {
     81                        // no env
    8382                        return false;
    8483                } // if
     
    136135                        if ( functionParameterSize( fftype ) != functionParameterSize( aftype ) ) return false;
    137136                        // tuple-parameter sizes are the same, but actual parameter sizes differ - must tuple specialize
    138                         if ( fftype->get_parameters().size() != aftype->get_parameters().size() ) return true;
     137                        if ( fftype->parameters.size() != aftype->parameters.size() ) return true;
    139138                        // total parameter size can be the same, while individual parameters can have different structure
    140                         for ( auto params : group_iterate( fftype->get_parameters(), aftype->get_parameters() ) ) {
     139                        for ( auto params : group_iterate( fftype->parameters, aftype->parameters ) ) {
    141140                                DeclarationWithType * formal = std::get<0>(params);
    142141                                DeclarationWithType * actual = std::get<1>(params);
     
    152151
    153152        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    154                 assertf( actual->has_result(), "attempting to specialize an untyped expression" );
     153                assertf( actual->result, "attempting to specialize an untyped expression" );
    155154                if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
    156155                        if ( FunctionType *funType = getFunctionType( formalType ) ) {
    157                                 ApplicationExpr *appExpr;
    158                                 VariableExpr *varExpr;
    159                                 if ( ( appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) ) {
     156                                if ( ApplicationExpr * appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) {
    160157                                        return createThunkFunction( funType, appExpr->get_function(), inferParams );
    161                                 } else if ( ( varExpr = dynamic_cast<VariableExpr*>( actual ) ) ) {
     158                                } else if ( VariableExpr * varExpr = dynamic_cast<VariableExpr*>( actual ) ) {
    162159                                        return createThunkFunction( funType, varExpr, inferParams );
    163160                                } else {
     
    204201        }
    205202
    206         struct EnvTrimmer : public Visitor {
     203        struct EnvTrimmer {
    207204                TypeSubstitution * env, * newEnv;
    208205                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    209                 virtual void visit( TypeDecl * tyDecl ) {
     206                void previsit( TypeDecl * tyDecl ) {
    210207                        // transfer known bindings for seen type variables
    211                         if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
    212                                 newEnv->add( tyDecl->get_name(), t );
     208                        if ( Type * t = env->lookup( tyDecl->name ) ) {
     209                                newEnv->add( tyDecl->name, t );
    213210                        }
    214211                }
     
    219216                if ( env ) {
    220217                        TypeSubstitution * newEnv = new TypeSubstitution();
    221                         EnvTrimmer trimmer( env, newEnv );
     218                        PassVisitor<EnvTrimmer> trimmer( env, newEnv );
    222219                        expr->accept( trimmer );
    223220                        return newEnv;
     
    277274                std::string oldParamPrefix = paramPrefix;
    278275                paramPrefix += "p";
    279                 // save stmtsToAdd in oldStmts
     276                // save stmtsToAddBefore in oldStmts
    280277                std::list< Statement* > oldStmts;
    281                 oldStmts.splice( oldStmts.end(), stmtsToAdd );
    282                 mutate( appExpr );
     278                oldStmts.splice( oldStmts.end(), stmtsToAddBefore );
     279                appExpr->acceptMutator( *visitor );
    283280                paramPrefix = oldParamPrefix;
    284281                // write any statements added for recursive specializations into the thunk body
    285                 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
    286                 // restore oldStmts into stmtsToAdd
    287                 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
     282                thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore );
     283                // restore oldStmts into stmtsToAddBefore
     284                stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts );
    288285
    289286                // add return (or valueless expression) to the thunk
    290287                Statement *appStmt;
    291                 if ( funType->get_returnVals().empty() ) {
     288                if ( funType->returnVals.empty() ) {
    292289                        appStmt = new ExprStmt( noLabels, appExpr );
    293290                } else {
    294291                        appStmt = new ReturnStmt( noLabels, appExpr );
    295292                } // if
    296                 thunkFunc->get_statements()->get_kids().push_back( appStmt );
     293                thunkFunc->statements->kids.push_back( appStmt );
    297294
    298295                // add thunk definition to queue of statements to add
    299                 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
     296                stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
    300297                // return address of thunk function as replacement expression
    301298                return new AddressExpr( new VariableExpr( thunkFunc ) );
     
    304301        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    305302                // create thunks for the explicit parameters
    306                 assert( appExpr->get_function()->has_result() );
    307                 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
     303                assert( appExpr->function->result );
     304                FunctionType *function = getFunctionType( appExpr->function->result );
    308305                assert( function );
    309306                std::list< DeclarationWithType* >::iterator formal;
    310307                std::list< Expression* >::iterator actual;
    311308                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    312                         *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
    313                 }
    314         }
    315 
    316         Expression * Specialize::mutate( ApplicationExpr *appExpr ) {
    317                 appExpr->get_function()->acceptMutator( *this );
    318                 mutateAll( appExpr->get_args(), *this );
    319 
     309                        *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
     310                }
     311        }
     312
     313        Expression * Specialize::postmutate( ApplicationExpr *appExpr ) {
    320314                if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
    321315                        // create thunks for the inferred parameters
     
    331325        }
    332326
    333         Expression * Specialize::mutate( AddressExpr *addrExpr ) {
    334                 addrExpr->get_arg()->acceptMutator( *this );
    335                 assert( addrExpr->has_result() );
    336                 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
    337                 return addrExpr;
    338         }
    339 
    340         Expression * Specialize::mutate( CastExpr *castExpr ) {
    341                 castExpr->get_arg()->acceptMutator( *this );
    342                 if ( castExpr->get_result()->isVoid() ) {
     327        Expression * Specialize::postmutate( CastExpr *castExpr ) {
     328                if ( castExpr->result->isVoid() ) {
    343329                        // can't specialize if we don't have a return value
    344330                        return castExpr;
    345331                }
    346                 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
    347                 if ( specialized != castExpr->get_arg() ) {
     332                Expression *specialized = doSpecialization( castExpr->result, castExpr->arg, &castExpr->inferParams );
     333                if ( specialized != castExpr->arg ) {
    348334                        // assume here that the specialization incorporates the cast
    349335                        return specialized;
     
    353339        }
    354340
    355         // Removing these for now. Richard put these in for some reason, but it's not clear why.
    356         // In particular, copy constructors produce a comma expression, and with this code the parts
    357         // of that comma expression are not specialized, which causes problems.
    358 
    359         // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
    360         //      return logicalExpr;
    361         // }
    362 
    363         // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
    364         //      return condExpr;
    365         // }
    366 
    367         // Expression * Specialize::mutate( CommaExpr *commaExpr ) {
    368         //      return commaExpr;
    369         // }
    370 
    371341        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    372                 Specialize spec;
     342                PassVisitor<Specialize> spec;
    373343                mutateAll( translationUnit, spec );
    374344        }
Note: See TracChangeset for help on using the changeset viewer.