- Timestamp:
- Feb 3, 2023, 1:28:43 PM (15 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 2f61765
- Parents:
- 8a97248 (diff), db9d7a9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/ScopedMap.h
r8a97248 r2125443a 37 37 template<typename N> 38 38 Scope(N && n) : map(), note(std::forward<N>(n)) {} 39 39 40 40 Scope() = default; 41 41 Scope(const Scope &) = default; … … 46 46 typedef std::vector< Scope > ScopeList; 47 47 48 ScopeList scopes; ///< scoped list of maps 48 /// Scoped list of maps. 49 ScopeList scopes; 49 50 public: 50 51 typedef typename MapType::key_type key_type; … … 58 59 typedef typename MapType::const_pointer const_pointer; 59 60 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > { 61 friend class ScopedMap; 62 friend class const_iterator; 63 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 64 typedef typename ScopedMap::ScopeList scope_list; 65 typedef typename scope_list::size_type size_type; 66 67 /// Checks if this iterator points to a valid item 68 bool is_valid() const { 69 return it != (*scopes)[level].map.end(); 70 } 71 72 /// Increments on invalid 73 iterator & next_valid() { 74 if ( ! is_valid() ) { ++(*this); } 75 return *this; 76 } 77 78 /// Decrements on invalid 79 iterator & prev_valid() { 80 if ( ! is_valid() ) { --(*this); } 81 return *this; 82 } 83 84 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 85 : scopes(&_scopes), it(_it), level(inLevel) {} 86 public: 87 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 88 iterator & operator= (const iterator & that) { 89 scopes = that.scopes; level = that.level; it = that.it; 90 return *this; 91 } 92 93 reference operator* () { return *it; } 94 pointer operator-> () const { return it.operator->(); } 95 96 iterator & operator++ () { 97 if ( it == (*scopes)[level].map.end() ) { 98 if ( level == 0 ) return *this; 99 --level; 100 it = (*scopes)[level].map.begin(); 101 } else { 102 ++it; 103 } 104 return next_valid(); 105 } 106 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 107 108 iterator & operator-- () { 109 // may fail if this is the begin iterator; allowed by STL spec 110 if ( it == (*scopes)[level].map.begin() ) { 111 ++level; 112 it = (*scopes)[level].map.end(); 113 } 114 --it; 115 return prev_valid(); 116 } 117 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 118 119 bool operator== (const iterator & that) const { 120 return scopes == that.scopes && level == that.level && it == that.it; 121 } 122 bool operator!= (const iterator & that) const { return !( *this == that ); } 123 124 size_type get_level() const { return level; } 125 126 Note & get_note() { return (*scopes)[level].note; } 127 const Note & get_note() const { return (*scopes)[level].note; } 128 129 private: 130 scope_list *scopes; 131 wrapped_iterator it; 132 size_type level; 133 }; 134 135 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 136 value_type > { 137 friend class ScopedMap; 138 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 139 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator; 140 typedef typename ScopedMap::ScopeList scope_list; 141 typedef typename scope_list::size_type size_type; 142 143 /// Checks if this iterator points to a valid item 144 bool is_valid() const { 145 return it != (*scopes)[level].map.end(); 146 } 147 148 /// Increments on invalid 149 const_iterator & next_valid() { 150 if ( ! is_valid() ) { ++(*this); } 151 return *this; 152 } 153 154 /// Decrements on invalid 155 const_iterator & prev_valid() { 156 if ( ! is_valid() ) { --(*this); } 157 return *this; 158 } 159 160 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 161 : scopes(&_scopes), it(_it), level(inLevel) {} 162 public: 163 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 164 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 165 const_iterator & operator= (const iterator & that) { 166 scopes = that.scopes; level = that.level; it = that.it; 167 return *this; 168 } 169 const_iterator & operator= (const const_iterator & that) { 170 scopes = that.scopes; level = that.level; it = that.it; 171 return *this; 172 } 173 174 const_reference operator* () { return *it; } 175 const_pointer operator-> () { return it.operator->(); } 176 177 const_iterator & operator++ () { 178 if ( it == (*scopes)[level].map.end() ) { 179 if ( level == 0 ) return *this; 180 --level; 181 it = (*scopes)[level].map.begin(); 182 } else { 183 ++it; 184 } 185 return next_valid(); 186 } 187 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 188 189 const_iterator & operator-- () { 190 // may fail if this is the begin iterator; allowed by STL spec 191 if ( it == (*scopes)[level].map.begin() ) { 192 ++level; 193 it = (*scopes)[level].map.end(); 194 } 195 --it; 196 return prev_valid(); 197 } 198 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 199 200 bool operator== (const const_iterator & that) const { 201 return scopes == that.scopes && level == that.level && it == that.it; 202 } 203 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 204 205 size_type get_level() const { return level; } 206 207 const Note & get_note() const { return (*scopes)[level].note; } 208 209 private: 210 scope_list const *scopes; 211 wrapped_const_iterator it; 212 size_type level; 213 }; 61 // Both iterator types are complete bidrectional iterators, see below. 62 class iterator; 63 class const_iterator; 214 64 215 65 /// Starts a new scope … … 297 147 } 298 148 299 template< typename value_type_t >300 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {301 MapType & scope = (*at.scopes)[ at.level ].map;302 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );303 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );304 }305 306 149 template< typename value_t > 307 150 std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); } … … 324 167 } 325 168 326 iterator erase( iterator pos ) { 327 MapType & scope = (*pos.scopes)[ pos.level ].map; 328 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it ); 329 iterator it( *pos.scopes, new_it, pos.level ); 330 return it.next_valid(); 331 } 169 iterator erase( iterator pos ); 332 170 333 171 size_type count( const Key & key ) const { … … 344 182 } 345 183 }; 184 185 template<typename Key, typename Value, typename Note> 186 class ScopedMap<Key, Value, Note>::iterator : 187 public std::iterator< std::bidirectional_iterator_tag, value_type > { 188 friend class ScopedMap; 189 friend class const_iterator; 190 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 191 typedef typename ScopedMap::ScopeList scope_list; 192 typedef typename scope_list::size_type size_type; 193 194 /// Checks if this iterator points to a valid item 195 bool is_valid() const { 196 return it != (*scopes)[level].map.end(); 197 } 198 199 /// Increments on invalid 200 iterator & next_valid() { 201 if ( ! is_valid() ) { ++(*this); } 202 return *this; 203 } 204 205 /// Decrements on invalid 206 iterator & prev_valid() { 207 if ( ! is_valid() ) { --(*this); } 208 return *this; 209 } 210 211 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 212 : scopes(&_scopes), it(_it), level(inLevel) {} 213 public: 214 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 215 iterator & operator= (const iterator & that) { 216 scopes = that.scopes; level = that.level; it = that.it; 217 return *this; 218 } 219 220 reference operator* () { return *it; } 221 pointer operator-> () const { return it.operator->(); } 222 223 iterator & operator++ () { 224 if ( it == (*scopes)[level].map.end() ) { 225 if ( level == 0 ) return *this; 226 --level; 227 it = (*scopes)[level].map.begin(); 228 } else { 229 ++it; 230 } 231 return next_valid(); 232 } 233 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 234 235 iterator & operator-- () { 236 // may fail if this is the begin iterator; allowed by STL spec 237 if ( it == (*scopes)[level].map.begin() ) { 238 ++level; 239 it = (*scopes)[level].map.end(); 240 } 241 --it; 242 return prev_valid(); 243 } 244 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 245 246 bool operator== (const iterator & that) const { 247 return scopes == that.scopes && level == that.level && it == that.it; 248 } 249 bool operator!= (const iterator & that) const { return !( *this == that ); } 250 251 size_type get_level() const { return level; } 252 253 Note & get_note() { return (*scopes)[level].note; } 254 const Note & get_note() const { return (*scopes)[level].note; } 255 256 private: 257 scope_list *scopes; 258 wrapped_iterator it; 259 size_type level; 260 }; 261 262 template<typename Key, typename Value, typename Note> 263 class ScopedMap<Key, Value, Note>::const_iterator : 264 public std::iterator< std::bidirectional_iterator_tag, value_type > { 265 friend class ScopedMap; 266 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 267 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator; 268 typedef typename ScopedMap::ScopeList scope_list; 269 typedef typename scope_list::size_type size_type; 270 271 /// Checks if this iterator points to a valid item 272 bool is_valid() const { 273 return it != (*scopes)[level].map.end(); 274 } 275 276 /// Increments on invalid 277 const_iterator & next_valid() { 278 if ( ! is_valid() ) { ++(*this); } 279 return *this; 280 } 281 282 /// Decrements on invalid 283 const_iterator & prev_valid() { 284 if ( ! is_valid() ) { --(*this); } 285 return *this; 286 } 287 288 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 289 : scopes(&_scopes), it(_it), level(inLevel) {} 290 public: 291 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 292 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 293 const_iterator & operator= (const iterator & that) { 294 scopes = that.scopes; level = that.level; it = that.it; 295 return *this; 296 } 297 const_iterator & operator= (const const_iterator & that) { 298 scopes = that.scopes; level = that.level; it = that.it; 299 return *this; 300 } 301 302 const_reference operator* () { return *it; } 303 const_pointer operator-> () { return it.operator->(); } 304 305 const_iterator & operator++ () { 306 if ( it == (*scopes)[level].map.end() ) { 307 if ( level == 0 ) return *this; 308 --level; 309 it = (*scopes)[level].map.begin(); 310 } else { 311 ++it; 312 } 313 return next_valid(); 314 } 315 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 316 317 const_iterator & operator-- () { 318 // may fail if this is the begin iterator; allowed by STL spec 319 if ( it == (*scopes)[level].map.begin() ) { 320 ++level; 321 it = (*scopes)[level].map.end(); 322 } 323 --it; 324 return prev_valid(); 325 } 326 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 327 328 bool operator== (const const_iterator & that) const { 329 return scopes == that.scopes && level == that.level && it == that.it; 330 } 331 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 332 333 size_type get_level() const { return level; } 334 335 const Note & get_note() const { return (*scopes)[level].note; } 336 337 private: 338 scope_list const *scopes; 339 wrapped_const_iterator it; 340 size_type level; 341 }; 342 343 template<typename Key, typename Value, typename Note> 344 typename ScopedMap<Key, Value, Note>::iterator 345 ScopedMap<Key, Value, Note>::erase( iterator pos ) { 346 MapType & scope = (*pos.scopes)[ pos.level ].map; 347 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it ); 348 iterator it( *pos.scopes, new_it, pos.level ); 349 return it.next_valid(); 350 } 346 351 347 352 // Local Variables: // -
src/Concurrency/Actors.cpp
r8a97248 r2125443a 21 21 #include "AST/TranslationUnit.hpp" 22 22 #include "AST/Expr.hpp" 23 #include <algorithm> 23 24 using namespace ast; 25 using namespace std; 24 26 25 27 namespace Concurrency { 26 28 27 29 struct CollectactorStructDecls : public ast::WithGuards { 28 std::map<const StructDecl *, int> & actorStructDecls;29 std::map<const StructDecl *, int> & messageStructDecls;30 unordered_set<const StructDecl *> & actorStructDecls; 31 unordered_set<const StructDecl *> & messageStructDecls; 30 32 const StructDecl ** requestDecl; 31 33 const EnumDecl ** allocationDecl; … … 34 36 StructDecl * parentDecl; 35 37 bool insideStruct = false; 36 38 bool namedDecl = false; 39 40 // finds and sets a ptr to the Allocation enum, which is needed in the next pass 37 41 void previsit( const EnumDecl * decl ) { 38 42 if( decl->name == "Allocation" ) *allocationDecl = decl; 39 43 } 40 44 45 // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass 41 46 void previsit( const StructDecl * decl ) { 42 47 GuardValue(insideStruct); … … 45 50 if( decl->name == "actor" ) *actorDecl = decl; 46 51 if( decl->name == "message" ) *msgDecl = decl; 47 if( decl->name == "request" ) *requestDecl = decl; 52 if( decl->name == "request" ) *requestDecl = decl; 48 53 } 49 54 55 // this catches structs of the form: 56 // struct dummy_actor { actor a; }; 57 // since they should be: 58 // struct dummy_actor { inline actor; }; 59 void previsit ( const ObjectDecl * decl ) { 60 if ( insideStruct && ! decl->name.empty() ) { 61 GuardValue(namedDecl); 62 namedDecl = true; 63 } 64 } 65 66 // this collects the valid actor and message struct decl pts 50 67 void postvisit( const StructInstType * node ) { 51 68 if ( ! *actorDecl || ! *msgDecl ) return; 52 if ( insideStruct ) {69 if ( insideStruct && !namedDecl ) { 53 70 if ( node->aggr() == *actorDecl ) { 54 actorStructDecls.insert( {parentDecl, 1});71 actorStructDecls.insert( parentDecl ); 55 72 } else if ( node->aggr() == *msgDecl ) { 56 messageStructDecls.insert( {parentDecl, 1});73 messageStructDecls.insert( parentDecl ); 57 74 } 58 75 } … … 60 77 61 78 public: 62 CollectactorStructDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,79 CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 63 80 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl ) 64 81 : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), … … 66 83 }; 67 84 85 // keeps track of all fwdDecls of message routines so that we can hoist them to right after the appropriate decls 86 class FwdDeclTable { 87 88 // tracks which decls we have seen so that we can hoist the FunctionDecl to the highest point possible 89 struct FwdDeclData { 90 const StructDecl * actorDecl; 91 const StructDecl * msgDecl; 92 FunctionDecl * fwdDecl; 93 bool actorFound; 94 bool msgFound; 95 96 bool readyToInsert() { return actorFound && msgFound; } 97 bool foundActor() { actorFound = true; return readyToInsert(); } 98 bool foundMsg() { msgFound = true; return readyToInsert(); } 99 100 FwdDeclData( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) : 101 actorDecl(actorDecl), msgDecl(msgDecl), fwdDecl(fwdDecl), actorFound(false), msgFound(false) {} 102 }; 103 104 // map indexed by actor struct ptr 105 // value is map of all FwdDeclData that contains said actor struct ptr 106 // inner map is indexed by the message struct ptr of FwdDeclData 107 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> actorMap; 108 109 // this map is the same except the outer map is indexed by message ptr and the inner is indexed by actor ptr 110 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> msgMap; 111 112 void insert( const StructDecl * decl, const StructDecl * otherDecl, unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map, FwdDeclData * data ) { 113 auto iter = map.find( decl ); 114 if ( iter != map.end() ) { // if decl exists in map append data to existing inner map 115 iter->second.emplace( make_pair( otherDecl, data ) ); 116 } else { // else create inner map for key 117 map.emplace( make_pair( decl, unordered_map<const StructDecl *, FwdDeclData *>( { make_pair( otherDecl, data ) } ) ) ); 118 } 119 } 120 121 public: 122 // insert decl into table so that we can fwd declare it later (average cost: O(1)) 123 void insertDecl( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) { 124 FwdDeclData * declToInsert = new FwdDeclData( actorDecl, msgDecl, fwdDecl ); 125 insert( actorDecl, msgDecl, actorMap, declToInsert ); 126 insert( msgDecl, actorDecl, msgMap, declToInsert ); 127 } 128 129 // returns list of decls to insert after current struct decl 130 // Over the entire pass the runtime of this routine is O(r) where r is the # of receive routines 131 list<FunctionDecl *> updateDecl( const StructDecl * decl, bool isMsg ) { 132 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map = isMsg ? msgMap : actorMap; 133 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & otherMap = isMsg ? actorMap : msgMap; 134 auto iter = map.find( decl ); 135 list<FunctionDecl *> toInsertAfter; // this is populated with decls that are ready to insert 136 if ( iter == map.end() ) return toInsertAfter; 137 138 // iterate over inner map 139 unordered_map<const StructDecl *, FwdDeclData *> & currInnerMap = iter->second; 140 for ( auto innerIter = currInnerMap.begin(); innerIter != currInnerMap.end(); ) { 141 FwdDeclData * currentDatum = innerIter->second; 142 bool readyToInsert = isMsg ? currentDatum->foundMsg() : currentDatum->foundActor(); 143 if ( ! readyToInsert ) { ++innerIter; continue; } 144 145 // readyToInsert is true so we are good to insert the forward decl of the message fn 146 toInsertAfter.push_back( currentDatum->fwdDecl ); 147 148 // need to remove from other map before deleting 149 // find inner map in other map ( other map is actor map if original is msg map and vice versa ) 150 const StructDecl * otherDecl = isMsg ? currentDatum->actorDecl : currentDatum->msgDecl; 151 auto otherMapIter = otherMap.find( otherDecl ); 152 153 unordered_map<const StructDecl *, FwdDeclData *> & otherInnerMap = otherMapIter->second; 154 155 // find the FwdDeclData we need to remove in the other inner map 156 auto otherInnerIter = otherInnerMap.find( decl ); 157 158 // remove references to deleted FwdDeclData from current inner map 159 innerIter = currInnerMap.erase( innerIter ); // this does the increment so no explicit inc needed 160 161 // remove references to deleted FwdDeclData from other inner map 162 otherInnerMap.erase( otherInnerIter ); 163 164 // if other inner map is now empty, remove key from other outer map 165 if ( otherInnerMap.empty() ) 166 otherMap.erase( otherDecl ); 167 168 // now we are safe to delete the FwdDeclData since we are done with it 169 // and we have removed all references to it from our data structures 170 delete currentDatum; 171 } 172 173 // if current inner map is now empty, remove key from outer map. 174 // Have to do this after iterating for safety 175 if ( currInnerMap.empty() ) 176 map.erase( decl ); 177 178 return toInsertAfter; 179 } 180 }; 181 182 #define __ALLOC 0 // C_TODO: complete swap to no-alloc version 183 68 184 struct GenReceiveDecls : public ast::WithDeclsToAdd<> { 69 std::map<const StructDecl *, int> & actorStructDecls;70 std::map<const StructDecl *, int> & messageStructDecls;185 unordered_set<const StructDecl *> & actorStructDecls; 186 unordered_set<const StructDecl *> & messageStructDecls; 71 187 const StructDecl ** requestDecl; 72 188 const EnumDecl ** allocationDecl; 73 189 const StructDecl ** actorDecl; 74 190 const StructDecl ** msgDecl; 75 std::vector<FunctionDecl *>& forwardDecls;191 FwdDeclTable & forwardDecls; 76 192 77 193 void postvisit( const FunctionDecl * decl ) { … … 90 206 91 207 // If the struct instances are derived actor and message types then generate the message send routine 92 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) { 208 auto actorIter = actorStructDecls.find( arg1InstType->aggr() ); 209 auto messageIter = messageStructDecls.find( arg2InstType->aggr() ); 210 if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) { 93 211 94 212 // check that we have found all the decls we need from <actor.hfa> … … 107 225 return receiver; 108 226 } 109 */ 227 */ // C_TODO: update this with new no alloc version 110 228 CompoundStmt * sendBody = new CompoundStmt( decl->location ); 111 229 230 #if __ALLOC 112 231 // Generates: request * new_req = alloc(); 113 232 sendBody->push_back( new DeclStmt( … … 120 239 ) 121 240 )); 241 #else 242 // Generates: request new_req; 243 sendBody->push_back( new DeclStmt( 244 decl->location, 245 new ObjectDecl( 246 decl->location, 247 "new_req", 248 new StructInstType( *requestDecl ) 249 ) 250 )); 251 #endif 122 252 123 253 // Function type is: Allocation (*)( derived_actor &, derived_msg & ) … … 160 290 )); 161 291 292 #if __ALLOC 162 293 // Generates: (*new_req){ &receiver, &msg, fn }; 163 294 sendBody->push_back( new ExprStmt( … … 189 320 ) 190 321 )); 322 #else 323 // Generates: new_req{ &receiver, &msg, fn }; 324 sendBody->push_back( new ExprStmt( 325 decl->location, 326 new UntypedExpr ( 327 decl->location, 328 new NameExpr( decl->location, "?{}" ), 329 { 330 new NameExpr( decl->location, "new_req" ), 331 new AddressExpr( new NameExpr( decl->location, "receiver" ) ), 332 new AddressExpr( new NameExpr( decl->location, "msg" ) ), 333 new NameExpr( decl->location, "fn" ) 334 } 335 ) 336 )); 337 338 // Generates: send( receiver, new_req ); 339 sendBody->push_back( new ExprStmt( 340 decl->location, 341 new UntypedExpr ( 342 decl->location, 343 new NameExpr( decl->location, "send" ), 344 { 345 { 346 new NameExpr( decl->location, "receiver" ), 347 new NameExpr( decl->location, "new_req" ) 348 } 349 } 350 ) 351 )); 352 #endif 191 353 192 354 // Generates: return receiver; … … 225 387 226 388 // forward decls to resolve use before decl problem for '|' routines 227 forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 389 forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) ); 390 // forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 228 391 229 392 sendOperatorFunction->stmts = sendBody; … … 233 396 234 397 public: 235 GenReceiveDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,398 GenReceiveDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 236 399 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 237 std::vector<FunctionDecl *>& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),400 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 238 401 requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {} 239 402 }; 240 403 241 404 struct GenFwdDecls : public ast::WithDeclsToAdd<> { 242 std::map<const StructDecl *, int> & actorStructDecls;243 std::map<const StructDecl *, int> & messageStructDecls;244 std::vector<FunctionDecl *>& forwardDecls;245 bool done; 246 247 void postvisit( const FunctionDecl * decl ) {248 if ( done ) return;249 // return if not of the form receive( param1, param2 ) or if it is a forwarddecl250 if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;251 252 // the params should be references 253 const ReferenceType * derivedActorRef = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());254 const ReferenceType * derivedMsgRef = dynamic_cast<const ReferenceType *>(decl->params.at(1)->get_type());255 if ( !derivedActorRef || !derivedMsgRef ) return;256 257 // the references should be to struct instances258 const StructInstType * arg1InstType = dynamic_cast<const StructInstType *>(derivedActorRef->base.get()); 259 const StructInstType * arg2InstType = dynamic_cast<const StructInstType *>(derivedMsgRef->base.get());260 if ( !arg1InstType || !arg2InstType ) return; 261 262 // If the struct instances are derived actor and message types then generate the message send routine263 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) {264 done = true; 265 for ( const auto & func : forwardDecls ) {266 declsToAddBefore.push_back( func );267 }405 unordered_set<const StructDecl *> & actorStructDecls; 406 unordered_set<const StructDecl *> & messageStructDecls; 407 FwdDeclTable & forwardDecls; 408 409 void postvisit( const StructDecl * decl ) { 410 list<FunctionDecl *> toAddAfter; 411 auto actorIter = actorStructDecls.find( decl ); 412 if ( actorIter != actorStructDecls.end() ) { // this is a derived actor decl 413 // get list of fwd decls that we can now insert 414 toAddAfter = forwardDecls.updateDecl( decl, false ); 415 416 // get rid of decl from actorStructDecls since we no longer need it 417 actorStructDecls.erase( actorIter ); 418 } else { 419 auto messageIter = messageStructDecls.find( decl ); 420 if ( messageIter == messageStructDecls.end() ) return; 421 422 toAddAfter = forwardDecls.updateDecl( decl, true ); 423 424 // get rid of decl from messageStructDecls since we no longer need it 425 messageStructDecls.erase( messageIter ); 426 } 427 428 // add the fwd decls to declsToAddAfter 429 for ( FunctionDecl * func : toAddAfter ) { 430 declsToAddAfter.push_back( func ); 268 431 } 269 432 } 270 433 271 434 public: 272 GenFwdDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,273 std::vector<FunctionDecl *>& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),274 forwardDecls(forwardDecls) , done(false){}435 GenFwdDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 436 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 437 forwardDecls(forwardDecls) {} 275 438 }; 276 439 277 440 void implementActors( TranslationUnit & translationUnit ) { 278 // maps to collect all derived actor and message types279 std::map<const StructDecl *, int> actorStructDecls;280 std::map<const StructDecl *, int> messageStructDecls;281 std::vector<FunctionDecl *>forwardDecls;441 // unordered_maps to collect all derived actor and message types 442 unordered_set<const StructDecl *> actorStructDecls; 443 unordered_set<const StructDecl *> messageStructDecls; 444 FwdDeclTable forwardDecls; 282 445 283 446 // for storing through the passes -
src/GenPoly/ErasableScopedMap.h
r8a97248 r2125443a 51 51 typedef typename Scope::const_pointer const_pointer; 52 52 53 // Both iterator types are complete bidirection iterators, definedbelow.53 // Both iterator types are complete bidirectional iterators, see below. 54 54 class iterator; 55 55 class const_iterator; -
src/GenPoly/ScopedSet.h
r8a97248 r2125443a 21 21 22 22 namespace GenPoly { 23 /// A set where the items are placed into nested scopes; 24 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 25 template<typename Value> 26 class ScopedSet { 27 typedef std::set< Value > Scope; 28 typedef std::vector< Scope > ScopeList; 29 30 ScopeList scopes; ///< scoped list of sets 31 public: 32 typedef typename Scope::key_type key_type; 33 typedef typename Scope::value_type value_type; 34 typedef typename ScopeList::size_type size_type; 35 typedef typename ScopeList::difference_type difference_type; 36 typedef typename Scope::reference reference; 37 typedef typename Scope::const_reference const_reference; 38 typedef typename Scope::pointer pointer; 39 typedef typename Scope::const_pointer const_pointer; 40 41 class iterator : public std::iterator< std::bidirectional_iterator_tag, 42 value_type > { 43 friend class ScopedSet; 44 friend class const_iterator; 45 typedef typename std::set< Value >::iterator wrapped_iterator; 46 typedef typename std::vector< std::set< Value > > scope_list; 47 typedef typename scope_list::size_type size_type; 48 49 /// Checks if this iterator points to a valid item 50 bool is_valid() const { 51 return it != (*scopes)[i].end(); 52 } 53 54 /// Increments on invalid 55 iterator& next_valid() { 56 if ( ! is_valid() ) { ++(*this); } 57 return *this; 58 } 59 60 /// Decrements on invalid 61 iterator& prev_valid() { 62 if ( ! is_valid() ) { --(*this); } 63 return *this; 64 } 65 66 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 67 : scopes(&_scopes), it(_it), i(_i) {} 68 public: 69 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 70 iterator& operator= (const iterator &that) { 71 scopes = that.scopes; i = that.i; it = that.it; 72 return *this; 73 } 74 75 reference operator* () { return *it; } 76 pointer operator-> () { return it.operator->(); } 77 78 iterator& operator++ () { 79 if ( it == (*scopes)[i].end() ) { 80 if ( i == 0 ) return *this; 81 --i; 82 it = (*scopes)[i].begin(); 83 } else { 84 ++it; 85 } 86 return next_valid(); 87 } 88 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 89 90 iterator& operator-- () { 91 // may fail if this is the begin iterator; allowed by STL spec 92 if ( it == (*scopes)[i].begin() ) { 93 ++i; 94 it = (*scopes)[i].end(); 95 } 96 --it; 97 return prev_valid(); 98 } 99 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 100 101 bool operator== (const iterator &that) { 102 return scopes == that.scopes && i == that.i && it == that.it; 103 } 104 bool operator!= (const iterator &that) { return !( *this == that ); } 105 106 size_type get_level() const { return i; } 107 108 private: 109 scope_list const *scopes; 110 wrapped_iterator it; 111 size_type i; 112 }; 113 114 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 115 value_type > { 116 friend class ScopedSet; 117 typedef typename std::set< Value >::iterator wrapped_iterator; 118 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 119 typedef typename std::vector< std::set< Value > > scope_list; 120 typedef typename scope_list::size_type size_type; 121 122 /// Checks if this iterator points to a valid item 123 bool is_valid() const { 124 return it != (*scopes)[i].end(); 125 } 126 127 /// Increments on invalid 128 const_iterator& next_valid() { 129 if ( ! is_valid() ) { ++(*this); } 130 return *this; 131 } 132 133 /// Decrements on invalid 134 const_iterator& prev_valid() { 135 if ( ! is_valid() ) { --(*this); } 136 return *this; 137 } 138 139 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 140 : scopes(&_scopes), it(_it), i(_i) {} 141 public: 142 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 143 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 144 const_iterator& operator= (const iterator &that) { 145 scopes = that.scopes; i = that.i; it = that.it; 146 return *this; 147 } 148 const_iterator& operator= (const const_iterator &that) { 149 scopes = that.scopes; i = that.i; it = that.it; 150 return *this; 151 } 152 153 const_reference operator* () { return *it; } 154 const_pointer operator-> () { return it.operator->(); } 155 156 const_iterator& operator++ () { 157 if ( it == (*scopes)[i].end() ) { 158 if ( i == 0 ) return *this; 159 --i; 160 it = (*scopes)[i].begin(); 161 } else { 162 ++it; 163 } 164 return next_valid(); 165 } 166 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 167 168 const_iterator& operator-- () { 169 // may fail if this is the begin iterator; allowed by STL spec 170 if ( it == (*scopes)[i].begin() ) { 171 ++i; 172 it = (*scopes)[i].end(); 173 } 174 --it; 175 return prev_valid(); 176 } 177 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 178 179 bool operator== (const const_iterator &that) { 180 return scopes == that.scopes && i == that.i && it == that.it; 181 } 182 bool operator!= (const const_iterator &that) { return !( *this == that ); } 183 184 size_type get_level() const { return i; } 185 186 private: 187 scope_list const *scopes; 188 wrapped_const_iterator it; 189 size_type i; 190 }; 191 192 /// Starts a new scope 193 void beginScope() { 194 Scope scope; 195 scopes.push_back(scope); 196 } 197 198 /// Ends a scope; invalidates any iterators pointing to elements of that scope 199 void endScope() { 200 scopes.pop_back(); 201 } 202 203 /// Default constructor initializes with one scope 204 ScopedSet() { beginScope(); } 205 206 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 207 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 208 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 209 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 210 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 211 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 212 213 /// Gets the index of the current scope (counted from 1) 214 size_type currentScope() const { return scopes.size(); } 215 216 /// Finds the given key in the outermost scope it occurs; returns end() for none such 217 iterator find( const Value &key ) { 218 for ( size_type i = scopes.size() - 1; ; --i ) { 219 typename Scope::iterator val = scopes[i].find( key ); 220 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 221 if ( i == 0 ) break; 222 } 223 return end(); 224 } 225 const_iterator find( const Value &key ) const { 226 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 227 } 228 229 /// Finds the given key in the outermost scope inside the given scope where it occurs 230 iterator findNext( const_iterator &it, const Value &key ) { 231 if ( it.i == 0 ) return end(); 23 24 /// A set where the items are placed into nested scopes; 25 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 26 template<typename Value> 27 class ScopedSet { 28 typedef std::set< Value > Scope; 29 typedef std::vector< Scope > ScopeList; 30 31 ScopeList scopes; ///< scoped list of sets 32 public: 33 typedef typename Scope::key_type key_type; 34 typedef typename Scope::value_type value_type; 35 typedef typename ScopeList::size_type size_type; 36 typedef typename ScopeList::difference_type difference_type; 37 typedef typename Scope::reference reference; 38 typedef typename Scope::const_reference const_reference; 39 typedef typename Scope::pointer pointer; 40 typedef typename Scope::const_pointer const_pointer; 41 42 // Both iterator types are complete bidirectional iterators, see below. 43 class iterator; 44 class const_iterator; 45 46 /// Starts a new scope 47 void beginScope() { 48 Scope scope; 49 scopes.push_back(scope); 50 } 51 52 /// Ends a scope; invalidates any iterators pointing to elements of that scope 53 void endScope() { 54 scopes.pop_back(); 55 } 56 57 /// Default constructor initializes with one scope 58 ScopedSet() { beginScope(); } 59 60 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 61 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 62 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 63 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 64 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 65 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 66 67 /// Gets the index of the current scope (counted from 1) 68 size_type currentScope() const { return scopes.size(); } 69 70 /// Finds the given key in the outermost scope it occurs; returns end() for none such 71 iterator find( const Value &key ) { 72 for ( size_type i = scopes.size() - 1; ; --i ) { 73 typename Scope::iterator val = scopes[i].find( key ); 74 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 75 if ( i == 0 ) break; 76 } 77 return end(); 78 } 79 const_iterator find( const Value &key ) const { 80 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 81 } 82 83 /// Finds the given key in the outermost scope inside the given scope where it occurs 84 iterator findNext( const_iterator &it, const Value &key ) { 85 if ( it.i == 0 ) return end(); 232 86 for ( size_type i = it.i - 1; ; --i ) { 233 typename Scope::iterator val = scopes[i].find( key ); 234 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 235 if ( i == 0 ) break; 236 } 237 return end(); 238 } 239 const_iterator findNext( const_iterator &it, const Value &key ) const { 240 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 241 } 242 243 /// Inserts the given value into the outermost scope 244 std::pair< iterator, bool > insert( const value_type &value ) { 245 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 246 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 247 } 248 249 }; 87 typename Scope::iterator val = scopes[i].find( key ); 88 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 89 if ( i == 0 ) break; 90 } 91 return end(); 92 } 93 const_iterator findNext( const_iterator &it, const Value &key ) const { 94 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 95 } 96 97 /// Inserts the given value into the outermost scope 98 std::pair< iterator, bool > insert( const value_type &value ) { 99 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 100 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 101 } 102 }; 103 104 template<typename Value> 105 class ScopedSet<Value>::iterator : 106 public std::iterator< std::bidirectional_iterator_tag, value_type > { 107 friend class ScopedSet; 108 friend class const_iterator; 109 typedef typename std::set< Value >::iterator wrapped_iterator; 110 typedef typename std::vector< std::set< Value > > scope_list; 111 typedef typename scope_list::size_type size_type; 112 113 /// Checks if this iterator points to a valid item 114 bool is_valid() const { 115 return it != (*scopes)[i].end(); 116 } 117 118 /// Increments on invalid 119 iterator& next_valid() { 120 if ( ! is_valid() ) { ++(*this); } 121 return *this; 122 } 123 124 /// Decrements on invalid 125 iterator& prev_valid() { 126 if ( ! is_valid() ) { --(*this); } 127 return *this; 128 } 129 130 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 131 : scopes(&_scopes), it(_it), i(_i) {} 132 public: 133 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 134 iterator& operator= (const iterator &that) { 135 scopes = that.scopes; i = that.i; it = that.it; 136 return *this; 137 } 138 139 reference operator* () { return *it; } 140 pointer operator-> () { return it.operator->(); } 141 142 iterator& operator++ () { 143 if ( it == (*scopes)[i].end() ) { 144 if ( i == 0 ) return *this; 145 --i; 146 it = (*scopes)[i].begin(); 147 } else { 148 ++it; 149 } 150 return next_valid(); 151 } 152 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 153 154 iterator& operator-- () { 155 // may fail if this is the begin iterator; allowed by STL spec 156 if ( it == (*scopes)[i].begin() ) { 157 ++i; 158 it = (*scopes)[i].end(); 159 } 160 --it; 161 return prev_valid(); 162 } 163 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 164 165 bool operator== (const iterator &that) { 166 return scopes == that.scopes && i == that.i && it == that.it; 167 } 168 bool operator!= (const iterator &that) { return !( *this == that ); } 169 170 size_type get_level() const { return i; } 171 172 private: 173 scope_list const *scopes; 174 wrapped_iterator it; 175 size_type i; 176 }; 177 178 template<typename Value> 179 class ScopedSet<Value>::const_iterator : 180 public std::iterator< std::bidirectional_iterator_tag, value_type > { 181 friend class ScopedSet; 182 typedef typename std::set< Value >::iterator wrapped_iterator; 183 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 184 typedef typename std::vector< std::set< Value > > scope_list; 185 typedef typename scope_list::size_type size_type; 186 187 /// Checks if this iterator points to a valid item 188 bool is_valid() const { 189 return it != (*scopes)[i].end(); 190 } 191 192 /// Increments on invalid 193 const_iterator& next_valid() { 194 if ( ! is_valid() ) { ++(*this); } 195 return *this; 196 } 197 198 /// Decrements on invalid 199 const_iterator& prev_valid() { 200 if ( ! is_valid() ) { --(*this); } 201 return *this; 202 } 203 204 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 205 : scopes(&_scopes), it(_it), i(_i) {} 206 public: 207 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 208 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 209 const_iterator& operator= (const iterator &that) { 210 scopes = that.scopes; i = that.i; it = that.it; 211 return *this; 212 } 213 const_iterator& operator= (const const_iterator &that) { 214 scopes = that.scopes; i = that.i; it = that.it; 215 return *this; 216 } 217 218 const_reference operator* () { return *it; } 219 const_pointer operator-> () { return it.operator->(); } 220 221 const_iterator& operator++ () { 222 if ( it == (*scopes)[i].end() ) { 223 if ( i == 0 ) return *this; 224 --i; 225 it = (*scopes)[i].begin(); 226 } else { 227 ++it; 228 } 229 return next_valid(); 230 } 231 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 232 233 const_iterator& operator-- () { 234 // may fail if this is the begin iterator; allowed by STL spec 235 if ( it == (*scopes)[i].begin() ) { 236 ++i; 237 it = (*scopes)[i].end(); 238 } 239 --it; 240 return prev_valid(); 241 } 242 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 243 244 bool operator== (const const_iterator &that) { 245 return scopes == that.scopes && i == that.i && it == that.it; 246 } 247 bool operator!= (const const_iterator &that) { return !( *this == that ); } 248 249 size_type get_level() const { return i; } 250 251 private: 252 scope_list const *scopes; 253 wrapped_const_iterator it; 254 size_type i; 255 }; 256 250 257 } // namespace GenPoly 251 258
Note: See TracChangeset
for help on using the changeset viewer.