Changes in / [a53e10a:349b2cb]


Ignore:
Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    ra53e10a r349b2cb  
    12981298                        FunctionType * ftype = functionDecl->get_functionType();
    12991299                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
    1300                                 if ( functionDecl->get_name() != "?=?" && ! isPrefix( functionDecl->get_name(), "_thunk" ) ) { // xxx - remove check for ?=? once reference types are in; remove check for prefix once thunks properly use ctor/dtors
     1300                                if ( functionDecl->get_name() != "?=?" && ! isPrefix( functionDecl->get_name(), "_thunk" ) && ! isPrefix( functionDecl->get_name(), "_adapter" ) ) { // xxx - remove check for ?=? once reference types are in; remove check for prefix once thunks properly use ctor/dtors
    13011301                                        assert( ftype->get_returnVals().size() == 1 );
    13021302                                        DeclarationWithType * retval = ftype->get_returnVals().front();
  • src/GenPoly/Specialize.cc

    ra53e10a r349b2cb  
    168168        }
    169169
     170        struct EnvTrimmer : public Visitor {
     171                TypeSubstitution * env, * newEnv;
     172                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
     173                virtual void visit( TypeDecl * tyDecl ) {
     174                        // transfer known bindings for seen type variables
     175                        if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
     176                                newEnv->add( tyDecl->get_name(), t );
     177                        }
     178                }
     179        };
     180
     181        /// reduce environment to just the parts that are referenced in a given expression
     182        TypeSubstitution * trimEnv( ApplicationExpr * expr, TypeSubstitution * env ) {
     183                if ( env ) {
     184                        TypeSubstitution * newEnv = new TypeSubstitution();
     185                        EnvTrimmer trimmer( env, newEnv );
     186                        expr->accept( trimmer );
     187                        return newEnv;
     188                }
     189                return nullptr;
     190        }
     191
    170192        /// Generates a thunk that calls `actual` with type `funType` and returns its address
    171193        Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
     
    211233                }
    212234
    213                 appExpr->set_env( maybeClone( env ) );
     235                appExpr->set_env( trimEnv( appExpr, env ) );
    214236                if ( inferParams ) {
    215237                        appExpr->get_inferParams() = *inferParams;
  • src/InitTweak/FixInit.cc

    ra53e10a r349b2cb  
    5252        namespace {
    5353                typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
     54                typedef std::unordered_map< int, int > UnqCount;
    5455
    5556                class InsertImplicitCalls final : public GenPoly::PolyMutator {
     
    7475                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    7576                        /// arguments and return value temporaries
    76                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap );
     77                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount );
    7778
    7879                        typedef SymTab::Indexer Parent;
    7980                        using Parent::visit;
    8081
    81                         ResolveCopyCtors( const EnvMap & envMap ) : envMap( envMap ) {}
     82                        ResolveCopyCtors( const EnvMap & envMap, UnqCount & unqCount ) : envMap( envMap ), unqCount( unqCount ) {}
    8283
    8384                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
     
    9495                        TypeSubstitution * env;
    9596                        const EnvMap & envMap;
     97                        UnqCount & unqCount; // count the number of times each unique expr ID appears
    9698                };
    9799
     
    202204                class FixCopyCtors final : public GenPoly::PolyMutator {
    203205                  public:
     206                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
    204207                        /// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors, call expression,
    205208                        /// and destructors
    206                         static void fixCopyCtors( std::list< Declaration * > &translationUnit );
     209                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    207210
    208211                        typedef GenPoly::PolyMutator Parent;
     
    211214                        virtual Expression * mutate( UniqueExpr * unqExpr ) override;
    212215                        virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     216
     217                        UnqCount & unqCount;
    213218                };
    214219
     
    272277
    273278                EnvMap envMap;
     279                UnqCount unqCount;
    274280
    275281                InsertImplicitCalls::insert( translationUnit, envMap );
    276                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap );
     282                ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap, unqCount );
    277283                InsertDtors::insert( translationUnit );
    278284                FixInit::fixInitializers( translationUnit );
    279285
    280286                // FixCopyCtors must happen after FixInit, so that destructors are placed correctly
    281                 FixCopyCtors::fixCopyCtors( translationUnit );
     287                FixCopyCtors::fixCopyCtors( translationUnit, unqCount );
    282288
    283289                GenStructMemberCalls::generate( translationUnit );
     
    298304                }
    299305
    300                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap ) {
    301                         ResolveCopyCtors resolver( envMap );
     306                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ) {
     307                        ResolveCopyCtors resolver( envMap, unqCount );
    302308                        acceptAll( translationUnit, resolver );
    303309                }
     
    329335                }
    330336
    331                 void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit ) {
    332                         FixCopyCtors fixer;
     337                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
     338                        FixCopyCtors fixer( unqCount );
    333339                        mutateAll( translationUnit, fixer );
    334340                }
     
    520526                void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
    521527                        static std::unordered_set< int > vars;
     528                        unqCount[ unqExpr->get_id() ]++;  // count the number of unique expressions for each ID
    522529                        if ( vars.count( unqExpr->get_id() ) ) {
    523530                                // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
     
    636643
    637644                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
     645                        unqCount[ unqExpr->get_id() ]--;
     646                        static std::unordered_map< int, std::list< Statement * > > dtors;
    638647                        static std::unordered_map< int, UniqueExpr * > unqMap;
    639648                        static std::unordered_set< int > addDeref;
     
    645654                                delete unqExpr->get_result();
    646655                                unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) );
     656                                if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
     657                                        stmtsToAdd.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
     658                                }
    647659                                if ( addDeref.count( unqExpr->get_id() ) ) {
    648660                                        // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
     
    651663                                return unqExpr;
    652664                        }
    653                         unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
     665                        FixCopyCtors fixer( unqCount );
     666                        unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
     667                        stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd );
    654668                        unqMap[unqExpr->get_id()] = unqExpr;
    655669                        if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
     
    661675                                getCallArg( deref, 0 ) = unqExpr;
    662676                                addDeref.insert( unqExpr->get_id() );
     677                                if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
     678                                        stmtsToAdd.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
     679                                } else { // remember dtors for last instance of unique expr
     680                                        dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter;
     681                                }
    663682                                return deref;
    664683                        }
Note: See TracChangeset for help on using the changeset viewer.