Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Specialize.cc

    rfc72845d rae4038d  
    1414//
    1515
    16 #include <cassert>                       // for assert, assertf
    17 #include <iterator>                      // for back_insert_iterator, back_i...
    18 #include <map>                           // for _Rb_tree_iterator, _Rb_tree_...
    19 #include <memory>                        // for unique_ptr
    20 #include <string>                        // for string
    21 #include <tuple>                         // for get
    22 #include <utility>                       // for pair
    23 
    24 #include "Common/PassVisitor.h"
    25 #include "Common/SemanticError.h"        // for SemanticError
    26 #include "Common/UniqueName.h"           // for UniqueName
    27 #include "Common/utility.h"              // for group_iterate
    28 #include "GenPoly.h"                     // for getFunctionType
    29 #include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    30 #include "Parser/LinkageSpec.h"          // for C
    31 #include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    32 #include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     16#include <cassert>
     17
    3318#include "Specialize.h"
    34 #include "SynTree/Attribute.h"           // for Attribute
    35 #include "SynTree/Declaration.h"         // for FunctionDecl, DeclarationWit...
    36 #include "SynTree/Expression.h"          // for ApplicationExpr, Expression
    37 #include "SynTree/Label.h"               // for Label, noLabels
    38 #include "SynTree/Mutator.h"             // for mutateAll
    39 #include "SynTree/Statement.h"           // for CompoundStmt, DeclStmt, Expr...
    40 #include "SynTree/Type.h"                // for FunctionType, TupleType, Type
    41 #include "SynTree/TypeSubstitution.h"    // for TypeSubstitution
    42 #include "SynTree/Visitor.h"             // for Visitor
     19#include "GenPoly.h"
     20#include "PolyMutator.h"
     21
     22#include "Parser/ParseNode.h"
     23
     24#include "SynTree/Expression.h"
     25#include "SynTree/Statement.h"
     26#include "SynTree/Type.h"
     27#include "SynTree/Attribute.h"
     28#include "SynTree/TypeSubstitution.h"
     29#include "SynTree/Mutator.h"
     30#include "ResolvExpr/FindOpenVars.h"
     31#include "Common/UniqueName.h"
     32#include "Common/utility.h"
     33#include "InitTweak/InitTweak.h"
     34#include "Tuples/Tuples.h"
    4335
    4436namespace GenPoly {
    45         struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
    46                 Expression * postmutate( ApplicationExpr *applicationExpr );
    47                 Expression * postmutate( AddressExpr *castExpr );
    48                 Expression * postmutate( CastExpr *castExpr );
     37        class Specialize final : public PolyMutator {
     38          public:
     39                using PolyMutator::mutate;
     40                virtual Expression * mutate( ApplicationExpr *applicationExpr ) override;
     41                virtual Expression * mutate( AddressExpr *castExpr ) override;
     42                virtual Expression * mutate( CastExpr *castExpr ) override;
     43                // virtual Expression * mutate( LogicalExpr *logicalExpr );
     44                // virtual Expression * mutate( ConditionalExpr *conditionalExpr );
     45                // virtual Expression * mutate( CommaExpr *commaExpr );
    4946
    5047                void handleExplicitParams( ApplicationExpr *appExpr );
     
    126123                        // conversion of 0 (null) to function type does not require tuple specialization
    127124                        if ( dynamic_cast< ZeroType * >( actualType ) ) return false;
    128                         FunctionType * aftype = getFunctionType( actualType->stripReferences() );
    129                         assertf( aftype, "formal type is a function type, but actual type is not: %s", toString( actualType ).c_str() );
     125                        FunctionType * aftype = getFunctionType( actualType );
     126                        assertf( aftype, "formal type is a function type, but actual type is not." );
    130127                        // Can't tuple specialize if parameter sizes deeply-differ.
    131128                        if ( functionParameterSize( fftype ) != functionParameterSize( aftype ) ) return false;
     
    199196        }
    200197
    201         struct EnvTrimmer {
     198        struct EnvTrimmer : public Visitor {
    202199                TypeSubstitution * env, * newEnv;
    203200                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    204                 void previsit( TypeDecl * tyDecl ) {
     201                virtual void visit( TypeDecl * tyDecl ) {
    205202                        // transfer known bindings for seen type variables
    206                         if ( Type * t = env->lookup( tyDecl->name ) ) {
    207                                 newEnv->add( tyDecl->name, t );
     203                        if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
     204                                newEnv->add( tyDecl->get_name(), t );
    208205                        }
    209206                }
     
    214211                if ( env ) {
    215212                        TypeSubstitution * newEnv = new TypeSubstitution();
    216                         PassVisitor<EnvTrimmer> trimmer( env, newEnv );
     213                        EnvTrimmer trimmer( env, newEnv );
    217214                        expr->accept( trimmer );
    218215                        return newEnv;
     
    272269                std::string oldParamPrefix = paramPrefix;
    273270                paramPrefix += "p";
    274                 // save stmtsToAddBefore in oldStmts
     271                // save stmtsToAdd in oldStmts
    275272                std::list< Statement* > oldStmts;
    276                 oldStmts.splice( oldStmts.end(), stmtsToAddBefore );
    277                 appExpr->acceptMutator( *visitor );
     273                oldStmts.splice( oldStmts.end(), stmtsToAdd );
     274                mutate( appExpr );
    278275                paramPrefix = oldParamPrefix;
    279276                // write any statements added for recursive specializations into the thunk body
    280                 thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore );
    281                 // restore oldStmts into stmtsToAddBefore
    282                 stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts );
     277                thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
     278                // restore oldStmts into stmtsToAdd
     279                stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
    283280
    284281                // add return (or valueless expression) to the thunk
    285282                Statement *appStmt;
    286                 if ( funType->returnVals.empty() ) {
     283                if ( funType->get_returnVals().empty() ) {
    287284                        appStmt = new ExprStmt( noLabels, appExpr );
    288285                } else {
    289286                        appStmt = new ReturnStmt( noLabels, appExpr );
    290287                } // if
    291                 thunkFunc->statements->kids.push_back( appStmt );
     288                thunkFunc->get_statements()->get_kids().push_back( appStmt );
    292289
    293290                // add thunk definition to queue of statements to add
    294                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
     291                stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
    295292                // return address of thunk function as replacement expression
    296293                return new AddressExpr( new VariableExpr( thunkFunc ) );
     
    299296        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    300297                // create thunks for the explicit parameters
    301                 assert( appExpr->function->result );
    302                 FunctionType *function = getFunctionType( appExpr->function->result );
     298                assert( appExpr->get_function()->has_result() );
     299                FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    303300                assert( function );
    304301                std::list< DeclarationWithType* >::iterator formal;
    305302                std::list< Expression* >::iterator actual;
    306303                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    307                         *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
    308                 }
    309         }
    310 
    311         Expression * Specialize::postmutate( ApplicationExpr *appExpr ) {
     304                        *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
     305                }
     306        }
     307
     308        Expression * Specialize::mutate( ApplicationExpr *appExpr ) {
     309                appExpr->get_function()->acceptMutator( *this );
     310                mutateAll( appExpr->get_args(), *this );
     311
    312312                if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
    313313                        // create thunks for the inferred parameters
     
    323323        }
    324324
    325         Expression * Specialize::postmutate( AddressExpr *addrExpr ) {
    326                 assert( addrExpr->result );
    327                 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) );
     325        Expression * Specialize::mutate( AddressExpr *addrExpr ) {
     326                addrExpr->get_arg()->acceptMutator( *this );
     327                assert( addrExpr->has_result() );
     328                addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
    328329                return addrExpr;
    329330        }
    330331
    331         Expression * Specialize::postmutate( CastExpr *castExpr ) {
    332                 if ( castExpr->result->isVoid() ) {
     332        Expression * Specialize::mutate( CastExpr *castExpr ) {
     333                castExpr->get_arg()->acceptMutator( *this );
     334                if ( castExpr->get_result()->isVoid() ) {
    333335                        // can't specialize if we don't have a return value
    334336                        return castExpr;
    335337                }
    336                 Expression *specialized = doSpecialization( castExpr->result, castExpr->arg );
    337                 if ( specialized != castExpr->arg ) {
     338                Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
     339                if ( specialized != castExpr->get_arg() ) {
    338340                        // assume here that the specialization incorporates the cast
    339341                        return specialized;
     
    343345        }
    344346
     347        // Removing these for now. Richard put these in for some reason, but it's not clear why.
     348        // In particular, copy constructors produce a comma expression, and with this code the parts
     349        // of that comma expression are not specialized, which causes problems.
     350
     351        // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
     352        //      return logicalExpr;
     353        // }
     354
     355        // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
     356        //      return condExpr;
     357        // }
     358
     359        // Expression * Specialize::mutate( CommaExpr *commaExpr ) {
     360        //      return commaExpr;
     361        // }
     362
    345363        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    346                 PassVisitor<Specialize> spec;
     364                Specialize spec;
    347365                mutateAll( translationUnit, spec );
    348366        }
Note: See TracChangeset for help on using the changeset viewer.