Changeset 5c14030


Ignore:
Timestamp:
Jul 11, 2018, 4:26:22 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env
Children:
d318a18
Parents:
184557e
git-author:
Aaron Moss <a3moss@…> (07/11/18 16:10:36)
git-committer:
Aaron Moss <a3moss@…> (07/11/18 16:26:22)
Message:

Persistent-array environment compiles

Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/Common/GC.h

    r184557e r5c14030  
    6969        bool mark;                     ///< The current collection's mark bit
    7070        unsigned g;                    ///< The current number generation in use
     71
     72        /// Trace a traceable object (enabled by SFINAE)
     73        template<typename T>
     74        static inline auto do_trace(const GC& gc, T& obj, int) -> decltype(gc << obj, void()) {
     75                gc << obj;
     76        }
     77
     78        /// Do not trace an untraceable object
     79        template<typename T>
     80        static inline auto do_trace(const GC&, T&, long) -> void {}
     81
     82        /// Base case for maybe_trace
     83        void maybe_trace() const {}
     84
     85public:
     86        /// Trace any objects that are traceable
     87        template<typename T, typename... Args>
     88        void maybe_trace(T& obj, Args&... args) const {
     89                // uses SFINAE trick to select proper overload; prefers actually tracing version
     90                // (because of int->long conversion), but will fall back to non-tracing
     91                do_trace(*this, obj, 0);
     92                maybe_trace(args...);
     93        }
    7194};
    7295
  • src/Common/PersistentDisjointSet.h

    r184557e r5c14030  
    129129        }
    130130
     131        /// reset as base
     132        void reset_as_base() {
     133                assertf( mode == BASE, "can only reset_as_base() on BASE" );
     134                as<Base>().~Base();
     135        }
     136
    131137        /// Non-initializing constructor; should call init() before use
    132138        PersistentDisjointSet( Mode m ) : data(), mode(m) {}
     
    165171                        case BASE: {
    166172                                for (const auto& entry : as<Base>()) {
    167                                         gc << entry.first;
     173                                        gc.maybe_trace( entry.first );
    168174                                }
    169175                                return;
     
    171177                        case ADD: case REM: {
    172178                                const Add& self = as<Add>();
    173                                 gc << self.base << self.root;
     179                                gc << self.base;
     180                                gc.maybe_trace( self.root );
    174181                                return;
    175182                        }
    176183                        case ADDTO: case REMFROM: {
    177184                                const AddTo& self = as<AddTo>();
    178                                 gc << self.base << self.root << self.child;
     185                                gc << self.base;
     186                                gc.maybe_trace( self.root, self.child );
    179187                                return;
    180188                        }
     
    210218                // take map out of base
    211219                Base base_map = base->take_as<Base>();
    212                 base->reset();
     220                base->reset_as_base();
    213221
    214222                // switch base to inverse of self and mutate base map
     
    331339                // transfer map to new node
    332340                Self* ret = new Self{ BASE, take_as<Base>() };
    333                 reset();
     341                reset_as_base();
    334342
    335343                // set self to REM node
     
    352360                // transfer map to new node
    353361                Self* ret = new Self{ BASE, take_as<Base>() };
    354                 reset();
     362                reset_as_base();
    355363
    356364                // find set nodes
     
    449457        /// `f` should take members by const reference or copy
    450458        template<typename F>
    451         void apply_to_class(Elm i, F&& f) const {
     459        void for_class(Elm i, F&& f) const {
    452460                const Base& self = rerooted();
    453461
  • src/Common/PersistentMap.h

    r184557e r5c14030  
    139139                        case BASE: {
    140140                                for (const auto& entry : as<Base>()) {
    141                                         gc << entry.first << entry.second;
     141                                        gc.maybe_trace( entry.first, entry.second );
    142142                                }
    143143                                return;
     
    145145                        case REM: {
    146146                                const Rem& self = as<Rem>();
    147                                 gc << self.base << self.key;
     147                                gc << self.base;
     148                                gc.maybe_trace( self.key );
    148149                                return;
    149150                        }
    150151                        case INS: case UPD: {
    151152                                const Ins& self = as<Ins>();
    152                                 gc << self.base << self.key << self.val;
     153                                gc << self.base;
     154                                gc.maybe_trace( self.key, self.val );
    153155                                return;
    154156                        }
     
    424426        }
    425427
     428        /// Applies the function `f` to all elements of the map.
     429        /// `f` should take two parameters, `const Key&` and `const Val&`.
     430        template<typename F>
     431        void for_each(F&& f) const {
     432                for ( const auto& entry : rerooted() ) { f( entry.first, entry.second ); }
     433        }
     434
    426435        /// Applies the function `f` to all elements of the map, returning a pointer to the updated map.
    427436        /// `f` should take two parameters, `const Key&` and `Val&`, returning option<Val> filled with
     
    429438        /// NOTE: when porting to C++17, this should work fine with std::optional
    430439        template<typename F>
    431         Self* apply_to_all(F&& f) {
     440        Self* mutate_each(F&& f) {
    432441                // reset to root and exit early if no change
    433442                if ( rerooted().empty() ) return this;
     
    454463                return next_edit;
    455464        }
    456 
    457         /// Applies the function `f` to all elements of the map.
    458         /// `f` should take two parameters, `const Key&` and `const Val&`.
    459         template<typename F>
    460         void apply_to_all(F&& f) const {
    461                 for ( const auto& entry : rerooted() ) { f( entry.first, entry.second ); }
    462         }
    463465};
    464466
  • src/Common/option.h

    r184557e r5c14030  
    1616#pragma once
    1717
     18#include <cassert>
    1819#include <functional>
    1920#include <type_traits>
    2021#include <utility>
    21 
    22 #include "debug.h"
    2322
    2423using std::move;
     
    121120
    122121    /// Get contained value (checked)
    123     T& value() & { assume(filled, "checked get failed"); return get(); }
    124     const T& value() const& { assume(filled, "checked get failed"); return get(); }
    125     T&& value() && { assume(filled, "checked get failed"); return move(get()); }
    126     const T&& value() const&& { assume(filled, "checked get failed"); return move(get()); }
     122    T& value() & { assertf(filled, "checked get failed"); return get(); }
     123    const T& value() const& { assertf(filled, "checked get failed"); return get(); }
     124    T&& value() && { assertf(filled, "checked get failed"); return move(get()); }
     125    const T&& value() const&& { assertf(filled, "checked get failed"); return move(get()); }
    127126
    128127    /// Get contained or default value
  • src/Makefile.in

    r184557e r5c14030  
    165165        Common/driver_cfa_cpp-GC.$(OBJEXT) \
    166166        Common/driver_cfa_cpp-Assert.$(OBJEXT) \
     167        Common/driver_cfa_cpp-InternedString.$(OBJEXT) \
    167168        Common/driver_cfa_cpp-Heap.$(OBJEXT) \
    168169        ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) \
     
    489490        Concurrency/Waitfor.cc Common/SemanticError.cc \
    490491        Common/UniqueName.cc Common/DebugMalloc.cc Common/GC.cc \
    491         Common/Assert.cc Common/Heap.cc \
     492        Common/Assert.cc Common/InternedString.cc Common/Heap.cc \
    492493        ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
    493494        ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
     
    680681Common/driver_cfa_cpp-Assert.$(OBJEXT): Common/$(am__dirstamp) \
    681682        Common/$(DEPDIR)/$(am__dirstamp)
     683Common/driver_cfa_cpp-InternedString.$(OBJEXT):  \
     684        Common/$(am__dirstamp) Common/$(DEPDIR)/$(am__dirstamp)
    682685Common/driver_cfa_cpp-Heap.$(OBJEXT): Common/$(am__dirstamp) \
    683686        Common/$(DEPDIR)/$(am__dirstamp)
     
    986989@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-GC.Po@am__quote@
    987990@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po@am__quote@
     991@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Po@am__quote@
    988992@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@
    989993@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@
     
    13361340@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Assert.obj `if test -f 'Common/Assert.cc'; then $(CYGPATH_W) 'Common/Assert.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Assert.cc'; fi`
    13371341
     1342Common/driver_cfa_cpp-InternedString.o: Common/InternedString.cc
     1343@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-InternedString.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Tpo -c -o Common/driver_cfa_cpp-InternedString.o `test -f 'Common/InternedString.cc' || echo '$(srcdir)/'`Common/InternedString.cc
     1344@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Tpo Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Po
     1345@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/InternedString.cc' object='Common/driver_cfa_cpp-InternedString.o' libtool=no @AMDEPBACKSLASH@
     1346@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1347@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-InternedString.o `test -f 'Common/InternedString.cc' || echo '$(srcdir)/'`Common/InternedString.cc
     1348
     1349Common/driver_cfa_cpp-InternedString.obj: Common/InternedString.cc
     1350@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-InternedString.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Tpo -c -o Common/driver_cfa_cpp-InternedString.obj `if test -f 'Common/InternedString.cc'; then $(CYGPATH_W) 'Common/InternedString.cc'; else $(CYGPATH_W) '$(srcdir)/Common/InternedString.cc'; fi`
     1351@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Tpo Common/$(DEPDIR)/driver_cfa_cpp-InternedString.Po
     1352@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/InternedString.cc' object='Common/driver_cfa_cpp-InternedString.obj' libtool=no @AMDEPBACKSLASH@
     1353@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1354@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-InternedString.obj `if test -f 'Common/InternedString.cc'; then $(CYGPATH_W) 'Common/InternedString.cc'; else $(CYGPATH_W) '$(srcdir)/Common/InternedString.cc'; fi`
     1355
    13381356Common/driver_cfa_cpp-Heap.o: Common/Heap.cc
    13391357@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Heap.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo -c -o Common/driver_cfa_cpp-Heap.o `test -f 'Common/Heap.cc' || echo '$(srcdir)/'`Common/Heap.cc
  • src/ResolvExpr/AlternativeFinder.cc

    r184557e r5c14030  
    454454                }
    455455
    456                 #if 0 // cost of assertions accounted for in function creation
     456                #if 1 // cost of assertions accounted for in function creation
    457457                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    458458                        convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     
    584584        }
    585585
     586#if !1
    586587        namespace {
    587588                /// Information required to defer resolution of an expression
     
    700701                }
    701702        }
     703#endif
    702704
    703705        template< typename OutputIterator >
     
    715717                // )
    716718                addToIndexer( have, decls );
    717 
     719#if !1
    718720                AssertionResnState resn{ newAlt, openVars, indexer };
    719721
     
    752754                *out++ = newAlt;
    753755
    754 #if 0           
     756#else           
    755757                AssertionSet newNeed;
    756758                PRINT(
     
    10931095        }
    10941096
     1097#if !1
    10951098        namespace {
    10961099
     
    12301233                }
    12311234        }
     1235#endif
    12321236
    12331237        template<typename OutputIterator>
     
    12761280
    12771281                // calculate declaration cost of function (+vars-spec)
     1282#if !1
    12781283                Cost funcCost = declCost( funcType );
     1284#else
     1285                Cost funcCost = Cost::zero;
     1286#endif
    12791287
    12801288                // iteratively build matches, one parameter at a time
  • src/ResolvExpr/TypeEnvironment.cc

    r184557e r5c14030  
    2727#include "SynTree/Type.h"              // for Type, FunctionType, Type::Fora...
    2828#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
     29#include "Tuples/Tuples.h"             // for isTtype
    2930#include "TypeEnvironment.h"
    3031#include "typeops.h"                   // for occurs
     
    104105                auto tyVar = openVars.find( typeInst->get_name() );
    105106                assert( tyVar != openVars.end() );
    106                 if ( ! tyVarCompatible( tyVar->second, other ) ) return false;
     107                if ( ! tyVarCompatible( tyVar->second, bindTo ) ) return false;
    107108
    108109                if ( occurs( bindTo, typeInst->get_name(), *this ) ) return false;
     
    135136                } else {
    136137                        // make new class consisting entirely of this variable
    137                         BoundType curData{ bindTo->clone(), widenMode.first && widenMode.second, data };
     138                        BoundType curData{
     139                                bindTo->clone(), widenMode.widenFirst && widenMode.widenSecond, data };
    138140                        curData.type->get_qualifiers() = Type::Qualifiers{};
    139141                        classes = classes->add( curClass.get_root() );
     
    146148                        const TypeDecl::Data& data, AssertionSet& need, AssertionSet& have,
    147149                        const OpenVarSet& openVars, WidenMode widenMode, const SymTab::Indexer& indexer ) {
    148                 ClassRef class1 = env.lookup( var1->get_name() );
    149                 ClassRef class2 = env.lookup( var2->get_name() );
     150                ClassRef class1 = lookup( var1->get_name() );
     151                ClassRef class2 = lookup( var2->get_name() );
    150152               
    151153                // exit early if variables already bound together
     
    153155                        BoundType data1 = class1.get_bound();
    154156                        // narrow the binding if needed
    155                         if ( data1.allowWidening && widenMode.first != widenMode.second ) {
     157                        if ( data1.allowWidening && widenMode.widenFirst != widenMode.widenSecond ) {
    156158                                data1.allowWidening = false;
    157159                                bindings = bindings->set( class1.get_root(), data1 );
     
    172174                                        openVars, WidenMode{ widen1, widen2 }, indexer, common ) ) {
    173175                                // merge type variables
    174                                 interned_string root = mergeClasses( class1.update_root(), class2.update_root() );
     176                                interned_string root =
     177                                        mergeClasses( class1.update_root(), class2.update_root() ).first;
    175178                                // update bindings
    176179                                data1.allowWidening = widen1 && widen2;
     
    197200                                if ( data2.allowWidening != widen2 ) {
    198201                                        data2.allowWidening = widen2;
    199                                         bindings = bindings->set( root, data2 );
     202                                        bindings = bindings->set( merged.first, data2 );
    200203                                } else if ( merged.first == class1.get_root() ) {
    201204                                        bindings = bindings->set( merged.first, data2 );
     
    249252                        // filter overlapping classes out of existing environment
    250253                        // (this is a very shady assumption, but has worked for a long time...)
    251                         interned_string root = classes->find_or_default( v, not_found );
     254                        interned_string root = classes->find_or_default( var, not_found );
    252255                        if ( root != not_found ) {
    253256                                classes = classes->remove_class( root );
     
    262265                        // add variable to class and bindings
    263266                        classes = classes->add( var );
    264                         bindings = bindings->set( var, BoundType{ p.second->clone, false, data } );
     267                        bindings = bindings->set( var, BoundType{ p.second->clone(), false, data } );
    265268                }
    266269        }
    267270
    268271        void TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const {
    269                 bindings->apply_to_all([classes, &sub]( interned_string root, const BoundType& bound ){
    270                         classes->apply_to_class(root, [&]( interned_string var ) {
     272                bindings->for_each([&]( interned_string root, const BoundType& bound ){
     273                        classes->for_class(root, [&]( interned_string var ) {
    271274                                if ( bound.type ) {
    272275                                        sub.add( var, bound.type );
     
    282285
    283286        void TypeEnvironment::print( std::ostream &os, Indenter indent ) const {
    284                 bindings->apply_to_all([classes,&]( interned_string root, const BoundType& bound ) {
     287                bindings->for_each([&]( interned_string root, const BoundType& bound ) {
    285288                        os << "( ";
    286                         classes->apply_to_class( root, [&os]( interned_string var ) { os << var << " "; } );
     289                        classes->for_class( root, [&os]( interned_string var ) { os << var << " "; } );
    287290                        os << ")";
    288291                        if ( bound.type ) {
    289292                                os << " -> ";
    290                                 type->print( os, indent+1 );
     293                                bound.type->print( os, indent+1 );
    291294                        }
    292295                        if ( ! bound.allowWidening ) {
     
    298301
    299302        void TypeEnvironment::simpleCombine( const TypeEnvironment &o ) {
    300                 o.bindings->apply_to_all( [&]( interned_string root, const BoundType& bound ) {
     303                o.bindings->for_each( [&]( interned_string root, const BoundType& bound ) {
    301304                        // add members of new class
    302305                        interned_string new_root{nullptr};
    303                         o.classes->apply_to_class( root, [this,&new_root]( interned_string var ) {
     306                        o.classes->for_class( root, [this,&new_root]( interned_string var ) {
    304307                                classes = classes->add( var );
    305308                                new_root = new_root ? mergeClasses( new_root, var ).first : var;
     
    311314
    312315        void TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const {
    313                 bindings->apply_to_all( [classes,&openVars]( interned_string root, const BoundType& bound ) {
    314                         classes->apply_to_class( root, [&openVars,&bound]( interned_string var ) {
     316                bindings->for_each( [&]( interned_string root, const BoundType& bound ) {
     317                        classes->for_class( root, [&openVars,&bound]( interned_string var ) {
    315318                                openVars[ var ] = bound.data;
    316319                        } );
     
    319322
    320323        void TypeEnvironment::addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ) {
    321                 actualEnv.bindings->apply_to_all( [&]( interned_string root, const BoundType& bound ) {
     324                actualEnv.bindings->for_each( [&]( interned_string root, const BoundType& bound ) {
    322325                        // add members of new class, setting openVars concurrently
    323326                        interned_string new_root{nullptr};
    324                         actualEnv.classes->apply_to_class( root, [&]( interned_string var ) {
     327                        actualEnv.classes->for_class( root, [&]( interned_string var ) {
    325328                                classes = classes->add( var );
    326329                                new_root = new_root ? mergeClasses( new_root, var ).first : var;
     
    334337
    335338        void TypeEnvironment::forbidWidening() {
    336                 bindings = bindings->apply_to_all([]( const interned_string& k, BoundType& c ) {
     339                bindings = bindings->mutate_each([]( const interned_string&, BoundType& c ) {
    337340                        if ( c.allowWidening ) {
    338341                                option<BoundType> ret = c;
  • src/ResolvExpr/TypeEnvironment.h

    r184557e r5c14030  
    189189                /// returned root variable will be valid regardless
    190190                ClassRef lookup( interned_string var ) const;
    191                 ClassRef lookup( const std::string &var ) const { return lookup( var ); }
    192191
    193192                /// Binds a type variable to a type; returns false if fails
     
    202201
    203202        public:
     203                TypeEnvironment() : classes{ new Classes{} }, bindings{ new Bindings{} } {}
     204
    204205                void add( const Type::ForallList &tyDecls );
    205206                void add( const TypeSubstitution & sub );
     
    224225                void forbidWidening();
    225226
    226                 iterator begin() { return { this, bindings->begin() }; }
    227                 iterator end() { return { this, bindings->end() }; }
     227                iterator begin() const { return { this, bindings->begin() }; }
     228                iterator end() const { return { this, bindings->end() }; }
    228229        };
    229230
     
    234235                T vars;
    235236                if ( ! env->classes->count( root ) ) return vars;
    236                 env->classes->apply_to_class( root, [&vars]( interned_string var ) {
     237                env->classes->for_class( root, [&vars]( interned_string var ) {
    237238                        vars.insert( vars.end(), var );
    238239                } );
Note: See TracChangeset for help on using the changeset viewer.