Changeset 1a59641


Ignore:
Timestamp:
Jul 27, 2018, 2:41:34 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env
Children:
6fa409e
Parents:
5a3e1f1
Message:

Fix open var handling in BF assn resolution; memory usage reasonable again

Location:
src/ResolvExpr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r5a3e1f1 r1a59641  
    687687                /// as appropriate.
    688688                void bindAssertion( const DeclarationWithType* curDecl, const AssertionSetValue& assnInfo,
    689                                 AssertionResnState& resn, AssertionPack&& match ) {
    690                         addToIndexer( match.have, resn.indexer );
    691                         resn.newNeed.insert( match.need.begin(), match.need.end() );
    692                         resn.openVars = std::move(match.openVars);
    693                         resn.alt.env = std::move(match.env);
     689                                Alternative& alt, AssertionPack& match ) {
    694690
    695691                        DeclarationWithType* candidate = match.cdata.id;
     
    702698                        }
    703699
    704                         Expression* varExpr = match.cdata.combine( resn.alt.cvtCost );
     700                        Expression* varExpr = match.cdata.combine( alt.cvtCost );
    705701                        varExpr->result = match.adjType;
    706702
     
    708704                        // parameters to add the candidate o (i.e. the set of inferred parameters belonging
    709705                        // to the entity which requested the assertion parameter)
    710                         InferredParams* inferParams = &resn.alt.expr->inferParams;
     706                        InferredParams* inferParams = &alt.expr->inferParams;
    711707                        for ( UniqueId id : assnInfo.idChain ) {
    712708                                inferParams = (*inferParams)[ id ].inferParams.get();
     
    759755
    760756                        // otherwise bind current match in ongoing scope
    761                         bindAssertion( curDecl, assnInfo, resn, std::move(matches.front()) );
     757                        AssertionPack& match = matches.front();
     758                        addToIndexer( match.have, resn.indexer );
     759                        resn.newNeed.insert( match.need.begin(), match.need.end() );
     760                        resn.openVars = std::move(match.openVars);
     761                        resn.alt.env = std::move(match.env);
     762
     763                        bindAssertion( curDecl, assnInfo, resn.alt, match );
    762764                        return true;
    763765                }
     
    771773                        /// Stack of environments, to support backtracking
    772774                        std::vector<TypeEnvironment> envs;
     775                        /// Open variables for environment combination
     776                        std::vector<OpenVarSet> varSets;
    773777                        /// Indexer to use for environment merges
    774778                        const SymTab::Indexer& indexer;
    775779                public:
    776                         /// Outputs a pair consisting of the merged environment and the list of interpretations
    777                         using OutType = std::pair<TypeEnvironment, std::vector<DeferElement>>;
    778 
    779                         InterpretationEnvMerger( const TypeEnvironment& env, const SymTab::Indexer& indexer )
    780                                 : crnt{}, envs{}, indexer{indexer} { envs.push_back( env ); }
     780                        /// The merged environment/open variables and the list of interpretations
     781                        struct OutType {
     782                                TypeEnvironment env;
     783                                OpenVarSet openVars;
     784                                std::vector<DeferElement> assns;
     785
     786                                OutType( const TypeEnvironment& env, const OpenVarSet& openVars,
     787                                        const std::vector<DeferElement>& assns )
     788                                        : env(env), openVars(openVars), assns(assns) {}
     789                        };
     790
     791                        InterpretationEnvMerger( const TypeEnvironment& env, const OpenVarSet& openVars,
     792                                const SymTab::Indexer& indexer ) : crnt{}, envs{}, varSets{}, indexer{indexer} {
     793                                envs.push_back( env );
     794                                varSets.push_back( openVars );
     795                        }
    781796
    782797                        ComboResult append( DeferElement i ) {
    783798                                TypeEnvironment env = envs.back();
    784                                 if ( ! env.combine( i.match.env, indexer ) ) return ComboResult::REJECT_THIS;
     799                                OpenVarSet openVars = varSets.back();
     800                                mergeOpenVars( openVars, i.match.openVars );
     801
     802                                if ( ! env.combine( i.match.env, openVars, indexer ) )
     803                                        return ComboResult::REJECT_THIS;
     804                               
    785805                                crnt.push_back( i );
    786806                                envs.push_back( env );
     807                                varSets.push_back( openVars );
    787808                                return ComboResult::ACCEPT;
    788809                        }
     
    791812                                crnt.pop_back();
    792813                                envs.pop_back();
    793                         }
    794 
    795                         OutType finalize() { return { envs.back(), crnt }; }
     814                                varSets.pop_back();
     815                        }
     816
     817                        OutType finalize() { return { envs.back(), varSets.back(), crnt }; }
    796818                };
    797819        }
     
    833855
    834856                                        std::vector<InterpretationEnvMerger::OutType> compatible = filterCombos(
    835                                                 resn.deferred, InterpretationEnvMerger{ resn.alt.env, resn.indexer });
     857                                                resn.deferred,
     858                                                InterpretationEnvMerger{ resn.alt.env, resn.openVars, resn.indexer } );
    836859                                       
    837860                                        for ( auto& compat : compatible ) {
     
    839862
    840863                                                // add compatible assertions to new resolution state
    841                                                 for ( DeferElement el : compat.second ) {
    842                                                         bindAssertion(
    843                                                                 el.curDecl, el.assnInfo, new_resn, AssertionPack{el.match} );
     864                                                for ( DeferElement el : compat.assns ) {
     865                                                        AssertionPack match = el.match;
     866                                                        addToIndexer( match.have, new_resn.indexer );
     867                                                        resn.newNeed.insert( match.need.begin(), match.need.end() );
     868                                                       
     869                                                        bindAssertion( el.curDecl, el.assnInfo, new_resn.alt, match );
    844870                                                }
    845871
    846872                                                // set mutual environment into resolution state
    847                                                 new_resn.alt.env = std::move(compat.first);
     873                                                new_resn.alt.env = std::move(compat.env);
     874                                                new_resn.openVars = std::move(compat.openVars);
    848875
    849876                                                // add successful match or push back next state
  • src/ResolvExpr/TypeEnvironment.cc

    r5a3e1f1 r1a59641  
    3636
    3737namespace ResolvExpr {
    38         #if 0
     38        #ifdef EXPENSIVE_ENV_VALIDATION
    3939        #define PRE_POST_VALIDATE auto dbg = ValidateGuard{this, __func__};
    4040        #define PRE_POST_VALIDATE_NOM auto dbg = ValidateGuard{this};
     
    411411        }
    412412
    413         bool TypeEnvironment::combine( const TypeEnvironment& o, const SymTab::Indexer& indexer ) {
     413        bool TypeEnvironment::combine( const TypeEnvironment& o, OpenVarSet& openVars,
     414                        const SymTab::Indexer& indexer ) {
    414415                // short-circuit for empty cases
    415416                if ( o.isEmpty() ) return true;
     
    657658                                Type* common = nullptr;
    658659                                AssertionSet need, have;
    659                                 OpenVarSet openVars;
    660660                                if ( unifyInexact( ebound.type->clone(), nbound.type->clone(), *this, need, have,
    661661                                                openVars, WidenMode{ ebound.allowWidening, nbound.allowWidening },
  • src/ResolvExpr/TypeEnvironment.h

    r5a3e1f1 r1a59641  
    7878        typedef std::map< std::string, TypeDecl::Data > OpenVarSet;
    7979
     80        /// merges one set of open vars into another
     81        static inline void mergeOpenVars( OpenVarSet& dst, const OpenVarSet& src ) {
     82                for ( const auto& entry : src ) { dst[ entry.first ] = entry.second; }
     83        }
     84
    8085        void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 );
    8186        void printOpenVarSet( const OpenVarSet &, std::ostream &, int indent = 0 );
     
    138143        };
    139144
     145        //#define EXPENSIVE_ENV_VALIDATION
     146        #ifdef EXPENSIVE_ENV_VALIDATION
    140147        class ValidateGuard;
     148        #endif
    141149
    142150        class TypeEnvironment {
     
    156164                Bindings* bindings;
    157165
    158                 // for debugging
     166                #ifdef EXPENSIVE_ENV_VALIDATION
     167                /// for debugging
    159168                friend ValidateGuard;
    160169                const char* last_fn = "<none>";
     170                #endif
    161171
    162172                /// Merges the classes rooted at root1 and root2, returning a pair containing the root and
     
    225235                /// from the same initial environment.
    226236                /// Returns false if unsuccessful, but does NOT roll back partial changes
    227                 bool combine( const TypeEnvironment& o, const SymTab::Indexer& indexer );
     237                bool combine( const TypeEnvironment& o, OpenVarSet& openVars,
     238                        const SymTab::Indexer& indexer );
    228239       
    229240                void extractOpenVars( OpenVarSet &openVars ) const;
Note: See TracChangeset for help on using the changeset viewer.