Changeset 96ddc62
- Timestamp:
- Jan 31, 2023, 2:06:18 PM (22 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- a8e8c67
- Parents:
- 9d0ff30
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Actors.cpp
r9d0ff30 r96ddc62 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; … … 51 53 if ( ! *actorDecl || ! *msgDecl ) return; 52 54 if ( insideStruct ) { 53 if ( node->aggr() == *actorDecl ) { 54 actorStructDecls.insert( {parentDecl, 1});55 if ( node->aggr() == *actorDecl ) { // C_TODO: see if we need to check for empty name 56 actorStructDecls.insert( parentDecl ); 55 57 } else if ( node->aggr() == *msgDecl ) { 56 messageStructDecls.insert( {parentDecl, 1});58 messageStructDecls.insert( parentDecl ); 57 59 } 58 60 } … … 60 62 61 63 public: 62 CollectactorStructDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,64 CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 63 65 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl ) 64 66 : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), … … 66 68 }; 67 69 70 // keeps track of all fwdDecls of message routines so that we can hoist them to right after the appropriate decls 71 class FwdDeclTable { 72 73 // tracks which decls we have seen so that we can hoist the FunctionDecl to the highest point possible 74 struct FwdDeclData { 75 const StructDecl * actorDecl; 76 const StructDecl * msgDecl; 77 FunctionDecl * fwdDecl; 78 bool actorFound; 79 bool msgFound; 80 81 bool readyToInsert() { return actorFound && msgFound; } 82 bool foundActor() { actorFound = true; return readyToInsert(); } 83 bool foundMsg() { msgFound = true; return readyToInsert(); } 84 85 FwdDeclData( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) : 86 actorDecl(actorDecl), msgDecl(msgDecl), fwdDecl(fwdDecl), actorFound(false), msgFound(false) {} 87 }; 88 89 // map indexed by actor struct ptr 90 // value is map of all FwdDeclData that contains said actor struct ptr 91 // inner map is indexed by the message struct ptr of FwdDeclData 92 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> actorMap; 93 94 // this map is the same except the outer map is indexed by message ptr and the inner is indexed by actor ptr 95 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> msgMap; 96 97 void insert( const StructDecl * decl, const StructDecl * otherDecl, unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map, FwdDeclData * data ) { 98 auto iter = map.find( decl ); 99 if ( iter != map.end() ) { // if decl exists in map append data to existing inner map 100 iter->second.emplace( make_pair( otherDecl, data ) ); 101 } else { // else create inner map for key 102 map.emplace( make_pair( decl, unordered_map<const StructDecl *, FwdDeclData *>( { make_pair( otherDecl, data ) } ) ) ); // C_TODO: maybe emplace? 103 } 104 } 105 106 public: 107 // insert decl into table so that we can fwd declare it later (average cost: O(1)) 108 void insertDecl( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) { 109 FwdDeclData * declToInsert = new FwdDeclData( actorDecl, msgDecl, fwdDecl ); 110 insert( actorDecl, msgDecl, actorMap, declToInsert ); 111 insert( msgDecl, actorDecl, msgMap, declToInsert ); 112 } 113 114 // returns list of decls to insert after current struct decl 115 // Over the entire pass the runtime of this routine is O(r) where r is the # of receive routines 116 list<FunctionDecl *> updateDecl( const StructDecl * decl, bool isMsg ) { 117 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map = isMsg ? msgMap : actorMap; 118 unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & otherMap = isMsg ? actorMap : msgMap; 119 auto iter = map.find( decl ); 120 121 list<FunctionDecl *> toInsertAfter; // this is populated with decls that are ready to insert 122 if ( iter == map.end() ) return toInsertAfter; 123 124 unordered_map<const StructDecl *, FwdDeclData *> & currInnerMap = iter->second; 125 126 cout << "a" << endl; 127 // iterate over inner map 128 for ( auto innerIter = currInnerMap.begin(); innerIter != currInnerMap.end(); ) { 129 cout << "b: " << decl->name << endl; 130 FwdDeclData * currentDatum = innerIter->second; 131 printf("P: %p\n", currentDatum->fwdDecl ); 132 133 bool readyToInsert = isMsg ? currentDatum->foundMsg() : currentDatum->foundActor(); 134 if ( ! readyToInsert ) { ++innerIter; continue; } 135 136 cout << "c" << endl; 137 // readyToInsert is true so we are good to insert the forward decl of the message fn 138 toInsertAfter.push_back( currentDatum->fwdDecl ); 139 140 cout << "d" << endl; 141 142 const StructDecl * otherDecl = isMsg ? currentDatum->actorDecl : currentDatum->msgDecl; 143 144 // need to remove from other map before deleting 145 // find inner map of FwdDeclData in other map ( other map is actor map if original is msg map and vice versa ) 146 auto otherMapIter = otherMap.find( otherDecl ); 147 148 unordered_map<const StructDecl *, FwdDeclData *> & otherInnerMap = otherMapIter->second; 149 150 cout << "e" << endl; 151 // find the FwdDeclData we need to remove in the other inner map 152 auto otherInnerIter = otherInnerMap.find( decl ); 153 154 cout << "f" << endl; 155 // now we are safe to delete the FwdDeclData since we are done with it 156 // have to delete before we invalidate the iterator 157 delete currentDatum; // C_TODO: move down since this no longer iterator dependant 158 159 cout << "g" << endl; 160 // remove references to deleted FwdDeclData from current inner map 161 innerIter = currInnerMap.erase( innerIter ); // this does the increment so no explicit inc needed 162 163 cout << "h" << endl; 164 // remove references to deleted FwdDeclData from other inner map 165 otherInnerMap.erase( otherInnerIter ); 166 167 // if other inner map is now empty, remove key from other outer map 168 if ( otherInnerMap.empty() ) 169 otherMap.erase( otherDecl ); 170 } 171 172 // if current inner map is now empty, remove key from outer map. 173 // Have to do this after iterating for safety 174 if ( currInnerMap.empty() ) 175 map.erase( decl ); 176 177 return toInsertAfter; 178 } 179 }; 180 68 181 struct GenReceiveDecls : public ast::WithDeclsToAdd<> { 69 std::map<const StructDecl *, int> & actorStructDecls;70 std::map<const StructDecl *, int> & messageStructDecls;182 unordered_set<const StructDecl *> & actorStructDecls; 183 unordered_set<const StructDecl *> & messageStructDecls; 71 184 const StructDecl ** requestDecl; 72 185 const EnumDecl ** allocationDecl; 73 186 const StructDecl ** actorDecl; 74 187 const StructDecl ** msgDecl; 75 std::vector<FunctionDecl *>& forwardDecls;188 FwdDeclTable & forwardDecls; 76 189 77 190 void postvisit( const FunctionDecl * decl ) { … … 90 203 91 204 // 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() ) ) { 205 auto actorIter = actorStructDecls.find( arg1InstType->aggr() ); 206 auto messageIter = messageStructDecls.find( arg2InstType->aggr() ); 207 if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) { 93 208 94 209 // check that we have found all the decls we need from <actor.hfa> … … 225 340 226 341 // forward decls to resolve use before decl problem for '|' routines 227 forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 342 forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) ); 343 // forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 228 344 229 345 sendOperatorFunction->stmts = sendBody; … … 233 349 234 350 public: 235 GenReceiveDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,351 GenReceiveDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 236 352 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 237 std::vector<FunctionDecl *>& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),353 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 238 354 requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {} 239 355 }; 240 356 241 357 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 }358 unordered_set<const StructDecl *> & actorStructDecls; 359 unordered_set<const StructDecl *> & messageStructDecls; 360 FwdDeclTable & forwardDecls; 361 362 void postvisit( const StructDecl * decl ) { 363 list<FunctionDecl *> toAddAfter; 364 auto actorIter = actorStructDecls.find( decl ); 365 if ( actorIter != actorStructDecls.end() ) { // this is a derived actor decl 366 // get list of fwd decls that we can now insert 367 toAddAfter = forwardDecls.updateDecl( decl, false ); 368 369 // get rid of decl from actorStructDecls since we no longer need it 370 actorStructDecls.erase( actorIter ); 371 } else { 372 auto messageIter = messageStructDecls.find( decl ); 373 if ( messageIter == messageStructDecls.end() ) return; 374 375 toAddAfter = forwardDecls.updateDecl( decl, true ); 376 377 // get rid of decl from messageStructDecls since we no longer need it 378 messageStructDecls.erase( messageIter ); 379 } 380 381 // add the fwd decls to declsToAddAfter 382 for ( FunctionDecl * func : toAddAfter ) { 383 declsToAddAfter.push_back( func ); 268 384 } 269 385 } 270 386 271 387 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){}388 GenFwdDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 389 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 390 forwardDecls(forwardDecls) {} 275 391 }; 276 392 277 393 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;394 // unordered_maps to collect all derived actor and message types 395 unordered_set<const StructDecl *> actorStructDecls; 396 unordered_set<const StructDecl *> messageStructDecls; 397 FwdDeclTable forwardDecls; 282 398 283 399 // for storing through the passes
Note: See TracChangeset
for help on using the changeset viewer.