Changeset 5c14030
- Timestamp:
- Jul 11, 2018, 4:26:22 PM (6 years ago)
- 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)
- Location:
- src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/GC.h
r184557e r5c14030 69 69 bool mark; ///< The current collection's mark bit 70 70 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 85 public: 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 } 71 94 }; 72 95 -
src/Common/PersistentDisjointSet.h
r184557e r5c14030 129 129 } 130 130 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 131 137 /// Non-initializing constructor; should call init() before use 132 138 PersistentDisjointSet( Mode m ) : data(), mode(m) {} … … 165 171 case BASE: { 166 172 for (const auto& entry : as<Base>()) { 167 gc << entry.first;173 gc.maybe_trace( entry.first ); 168 174 } 169 175 return; … … 171 177 case ADD: case REM: { 172 178 const Add& self = as<Add>(); 173 gc << self.base << self.root; 179 gc << self.base; 180 gc.maybe_trace( self.root ); 174 181 return; 175 182 } 176 183 case ADDTO: case REMFROM: { 177 184 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 ); 179 187 return; 180 188 } … … 210 218 // take map out of base 211 219 Base base_map = base->take_as<Base>(); 212 base->reset ();220 base->reset_as_base(); 213 221 214 222 // switch base to inverse of self and mutate base map … … 331 339 // transfer map to new node 332 340 Self* ret = new Self{ BASE, take_as<Base>() }; 333 reset ();341 reset_as_base(); 334 342 335 343 // set self to REM node … … 352 360 // transfer map to new node 353 361 Self* ret = new Self{ BASE, take_as<Base>() }; 354 reset ();362 reset_as_base(); 355 363 356 364 // find set nodes … … 449 457 /// `f` should take members by const reference or copy 450 458 template<typename F> 451 void apply_to_class(Elm i, F&& f) const {459 void for_class(Elm i, F&& f) const { 452 460 const Base& self = rerooted(); 453 461 -
src/Common/PersistentMap.h
r184557e r5c14030 139 139 case BASE: { 140 140 for (const auto& entry : as<Base>()) { 141 gc << entry.first << entry.second;141 gc.maybe_trace( entry.first, entry.second ); 142 142 } 143 143 return; … … 145 145 case REM: { 146 146 const Rem& self = as<Rem>(); 147 gc << self.base << self.key; 147 gc << self.base; 148 gc.maybe_trace( self.key ); 148 149 return; 149 150 } 150 151 case INS: case UPD: { 151 152 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 ); 153 155 return; 154 156 } … … 424 426 } 425 427 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 426 435 /// Applies the function `f` to all elements of the map, returning a pointer to the updated map. 427 436 /// `f` should take two parameters, `const Key&` and `Val&`, returning option<Val> filled with … … 429 438 /// NOTE: when porting to C++17, this should work fine with std::optional 430 439 template<typename F> 431 Self* apply_to_all(F&& f) {440 Self* mutate_each(F&& f) { 432 441 // reset to root and exit early if no change 433 442 if ( rerooted().empty() ) return this; … … 454 463 return next_edit; 455 464 } 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 }463 465 }; 464 466 -
src/Common/option.h
r184557e r5c14030 16 16 #pragma once 17 17 18 #include <cassert> 18 19 #include <functional> 19 20 #include <type_traits> 20 21 #include <utility> 21 22 #include "debug.h"23 22 24 23 using std::move; … … 121 120 122 121 /// Get contained value (checked) 123 T& value() & { ass ume(filled, "checked get failed"); return get(); }124 const T& value() const& { ass ume(filled, "checked get failed"); return get(); }125 T&& value() && { ass ume(filled, "checked get failed"); return move(get()); }126 const T&& value() const&& { ass ume(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()); } 127 126 128 127 /// Get contained or default value -
src/Makefile.in
r184557e r5c14030 165 165 Common/driver_cfa_cpp-GC.$(OBJEXT) \ 166 166 Common/driver_cfa_cpp-Assert.$(OBJEXT) \ 167 Common/driver_cfa_cpp-InternedString.$(OBJEXT) \ 167 168 Common/driver_cfa_cpp-Heap.$(OBJEXT) \ 168 169 ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) \ … … 489 490 Concurrency/Waitfor.cc Common/SemanticError.cc \ 490 491 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 \ 492 493 ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \ 493 494 ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \ … … 680 681 Common/driver_cfa_cpp-Assert.$(OBJEXT): Common/$(am__dirstamp) \ 681 682 Common/$(DEPDIR)/$(am__dirstamp) 683 Common/driver_cfa_cpp-InternedString.$(OBJEXT): \ 684 Common/$(am__dirstamp) Common/$(DEPDIR)/$(am__dirstamp) 682 685 Common/driver_cfa_cpp-Heap.$(OBJEXT): Common/$(am__dirstamp) \ 683 686 Common/$(DEPDIR)/$(am__dirstamp) … … 986 989 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-GC.Po@am__quote@ 987 990 @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@ 988 992 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@ 989 993 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@ … … 1336 1340 @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` 1337 1341 1342 Common/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 1349 Common/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 1338 1356 Common/driver_cfa_cpp-Heap.o: Common/Heap.cc 1339 1357 @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 454 454 } 455 455 456 #if 0// cost of assertions accounted for in function creation456 #if 1 // cost of assertions accounted for in function creation 457 457 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 458 458 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); … … 584 584 } 585 585 586 #if !1 586 587 namespace { 587 588 /// Information required to defer resolution of an expression … … 700 701 } 701 702 } 703 #endif 702 704 703 705 template< typename OutputIterator > … … 715 717 // ) 716 718 addToIndexer( have, decls ); 717 719 #if !1 718 720 AssertionResnState resn{ newAlt, openVars, indexer }; 719 721 … … 752 754 *out++ = newAlt; 753 755 754 # if 0756 #else 755 757 AssertionSet newNeed; 756 758 PRINT( … … 1093 1095 } 1094 1096 1097 #if !1 1095 1098 namespace { 1096 1099 … … 1230 1233 } 1231 1234 } 1235 #endif 1232 1236 1233 1237 template<typename OutputIterator> … … 1276 1280 1277 1281 // calculate declaration cost of function (+vars-spec) 1282 #if !1 1278 1283 Cost funcCost = declCost( funcType ); 1284 #else 1285 Cost funcCost = Cost::zero; 1286 #endif 1279 1287 1280 1288 // iteratively build matches, one parameter at a time -
src/ResolvExpr/TypeEnvironment.cc
r184557e r5c14030 27 27 #include "SynTree/Type.h" // for Type, FunctionType, Type::Fora... 28 28 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 29 #include "Tuples/Tuples.h" // for isTtype 29 30 #include "TypeEnvironment.h" 30 31 #include "typeops.h" // for occurs … … 104 105 auto tyVar = openVars.find( typeInst->get_name() ); 105 106 assert( tyVar != openVars.end() ); 106 if ( ! tyVarCompatible( tyVar->second, other) ) return false;107 if ( ! tyVarCompatible( tyVar->second, bindTo ) ) return false; 107 108 108 109 if ( occurs( bindTo, typeInst->get_name(), *this ) ) return false; … … 135 136 } else { 136 137 // 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 }; 138 140 curData.type->get_qualifiers() = Type::Qualifiers{}; 139 141 classes = classes->add( curClass.get_root() ); … … 146 148 const TypeDecl::Data& data, AssertionSet& need, AssertionSet& have, 147 149 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() ); 150 152 151 153 // exit early if variables already bound together … … 153 155 BoundType data1 = class1.get_bound(); 154 156 // narrow the binding if needed 155 if ( data1.allowWidening && widenMode. first != widenMode.second ) {157 if ( data1.allowWidening && widenMode.widenFirst != widenMode.widenSecond ) { 156 158 data1.allowWidening = false; 157 159 bindings = bindings->set( class1.get_root(), data1 ); … … 172 174 openVars, WidenMode{ widen1, widen2 }, indexer, common ) ) { 173 175 // 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; 175 178 // update bindings 176 179 data1.allowWidening = widen1 && widen2; … … 197 200 if ( data2.allowWidening != widen2 ) { 198 201 data2.allowWidening = widen2; 199 bindings = bindings->set( root, data2 );202 bindings = bindings->set( merged.first, data2 ); 200 203 } else if ( merged.first == class1.get_root() ) { 201 204 bindings = bindings->set( merged.first, data2 ); … … 249 252 // filter overlapping classes out of existing environment 250 253 // (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 ); 252 255 if ( root != not_found ) { 253 256 classes = classes->remove_class( root ); … … 262 265 // add variable to class and bindings 263 266 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 } ); 265 268 } 266 269 } 267 270 268 271 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 ) { 271 274 if ( bound.type ) { 272 275 sub.add( var, bound.type ); … … 282 285 283 286 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 ) { 285 288 os << "( "; 286 classes-> apply_to_class( root, [&os]( interned_string var ) { os << var << " "; } );289 classes->for_class( root, [&os]( interned_string var ) { os << var << " "; } ); 287 290 os << ")"; 288 291 if ( bound.type ) { 289 292 os << " -> "; 290 type->print( os, indent+1 );293 bound.type->print( os, indent+1 ); 291 294 } 292 295 if ( ! bound.allowWidening ) { … … 298 301 299 302 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 ) { 301 304 // add members of new class 302 305 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 ) { 304 307 classes = classes->add( var ); 305 308 new_root = new_root ? mergeClasses( new_root, var ).first : var; … … 311 314 312 315 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 ) { 315 318 openVars[ var ] = bound.data; 316 319 } ); … … 319 322 320 323 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 ) { 322 325 // add members of new class, setting openVars concurrently 323 326 interned_string new_root{nullptr}; 324 actualEnv.classes-> apply_to_class( root, [&]( interned_string var ) {327 actualEnv.classes->for_class( root, [&]( interned_string var ) { 325 328 classes = classes->add( var ); 326 329 new_root = new_root ? mergeClasses( new_root, var ).first : var; … … 334 337 335 338 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 ) { 337 340 if ( c.allowWidening ) { 338 341 option<BoundType> ret = c; -
src/ResolvExpr/TypeEnvironment.h
r184557e r5c14030 189 189 /// returned root variable will be valid regardless 190 190 ClassRef lookup( interned_string var ) const; 191 ClassRef lookup( const std::string &var ) const { return lookup( var ); }192 191 193 192 /// Binds a type variable to a type; returns false if fails … … 202 201 203 202 public: 203 TypeEnvironment() : classes{ new Classes{} }, bindings{ new Bindings{} } {} 204 204 205 void add( const Type::ForallList &tyDecls ); 205 206 void add( const TypeSubstitution & sub ); … … 224 225 void forbidWidening(); 225 226 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() }; } 228 229 }; 229 230 … … 234 235 T vars; 235 236 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 ) { 237 238 vars.insert( vars.end(), var ); 238 239 } );
Note: See TracChangeset
for help on using the changeset viewer.