Changes in src/Concurrency/Actors.cpp [a8e8c67:34ed17b]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Actors.cpp
ra8e8c67 r34ed17b 21 21 #include "AST/TranslationUnit.hpp" 22 22 #include "AST/Expr.hpp" 23 #include <algorithm>24 23 using namespace ast; 25 using namespace std;26 24 27 25 namespace Concurrency { 28 26 29 27 struct CollectactorStructDecls : public ast::WithGuards { 30 unordered_set<const StructDecl *> & actorStructDecls;31 unordered_set<const StructDecl *> & messageStructDecls;28 std::map<const StructDecl *, int> & actorStructDecls; 29 std::map<const StructDecl *, int> & messageStructDecls; 32 30 const StructDecl ** requestDecl; 33 31 const EnumDecl ** allocationDecl; … … 36 34 StructDecl * parentDecl; 37 35 bool insideStruct = false; 38 bool namedDecl = false; 39 40 // finds and sets a ptr to the Allocation enum, which is needed in the next pass 36 41 37 void previsit( const EnumDecl * decl ) { 42 38 if( decl->name == "Allocation" ) *allocationDecl = decl; 43 39 } 44 40 45 // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass46 41 void previsit( const StructDecl * decl ) { 47 42 GuardValue(insideStruct); … … 50 45 if( decl->name == "actor" ) *actorDecl = decl; 51 46 if( decl->name == "message" ) *msgDecl = decl; 52 if( decl->name == "request" ) *requestDecl = decl; 47 if( decl->name == "request" ) *requestDecl = decl; 53 48 } 54 49 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 pts67 50 void postvisit( const StructInstType * node ) { 68 51 if ( ! *actorDecl || ! *msgDecl ) return; 69 if ( insideStruct && !namedDecl) {52 if ( insideStruct ) { 70 53 if ( node->aggr() == *actorDecl ) { 71 actorStructDecls.insert( parentDecl);54 actorStructDecls.insert({parentDecl, 1}); 72 55 } else if ( node->aggr() == *msgDecl ) { 73 messageStructDecls.insert( parentDecl);56 messageStructDecls.insert({parentDecl, 1}); 74 57 } 75 58 } … … 77 60 78 61 public: 79 CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,62 CollectactorStructDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls, 80 63 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl ) 81 64 : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), … … 83 66 }; 84 67 85 // keeps track of all fwdDecls of message routines so that we can hoist them to right after the appropriate decls86 class FwdDeclTable {87 88 // tracks which decls we have seen so that we can hoist the FunctionDecl to the highest point possible89 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 ptr105 // value is map of all FwdDeclData that contains said actor struct ptr106 // inner map is indexed by the message struct ptr of FwdDeclData107 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 ptr110 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 map115 iter->second.emplace( make_pair( otherDecl, data ) );116 } else { // else create inner map for key117 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 decl130 // Over the entire pass the runtime of this routine is O(r) where r is the # of receive routines131 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 insert136 if ( iter == map.end() ) return toInsertAfter;137 138 // iterate over inner map139 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 fn146 toInsertAfter.push_back( currentDatum->fwdDecl );147 148 // need to remove from other map before deleting149 // 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 map156 auto otherInnerIter = otherInnerMap.find( decl );157 158 // remove references to deleted FwdDeclData from current inner map159 innerIter = currInnerMap.erase( innerIter ); // this does the increment so no explicit inc needed160 161 // remove references to deleted FwdDeclData from other inner map162 otherInnerMap.erase( otherInnerIter );163 164 // if other inner map is now empty, remove key from other outer map165 if ( otherInnerMap.empty() )166 otherMap.erase( otherDecl );167 168 // now we are safe to delete the FwdDeclData since we are done with it169 // and we have removed all references to it from our data structures170 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 safety175 if ( currInnerMap.empty() )176 map.erase( decl );177 178 return toInsertAfter;179 }180 };181 182 68 struct GenReceiveDecls : public ast::WithDeclsToAdd<> { 183 unordered_set<const StructDecl *> & actorStructDecls;184 unordered_set<const StructDecl *> & messageStructDecls;69 std::map<const StructDecl *, int> & actorStructDecls; 70 std::map<const StructDecl *, int> & messageStructDecls; 185 71 const StructDecl ** requestDecl; 186 72 const EnumDecl ** allocationDecl; 187 73 const StructDecl ** actorDecl; 188 74 const StructDecl ** msgDecl; 189 FwdDeclTable& forwardDecls;75 std::vector<FunctionDecl *> & forwardDecls; 190 76 191 77 void postvisit( const FunctionDecl * decl ) { … … 204 90 205 91 // If the struct instances are derived actor and message types then generate the message send routine 206 auto actorIter = actorStructDecls.find( arg1InstType->aggr() ); 207 auto messageIter = messageStructDecls.find( arg2InstType->aggr() ); 208 if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) { 92 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) { 209 93 210 94 // check that we have found all the decls we need from <actor.hfa> … … 341 225 342 226 // forward decls to resolve use before decl problem for '|' routines 343 forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) ); 344 // forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 227 forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 345 228 346 229 sendOperatorFunction->stmts = sendBody; … … 350 233 351 234 public: 352 GenReceiveDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,235 GenReceiveDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls, 353 236 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 354 FwdDeclTable& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),237 std::vector<FunctionDecl *> & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 355 238 requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {} 356 239 }; 357 240 358 241 struct GenFwdDecls : public ast::WithDeclsToAdd<> { 359 unordered_set<const StructDecl *> & actorStructDecls;360 unordered_set<const StructDecl *> & messageStructDecls;361 FwdDeclTable& forwardDecls;362 363 void postvisit( const StructDecl * decl ) { 364 list<FunctionDecl *> toAddAfter;365 auto actorIter = actorStructDecls.find( decl );366 if ( actorIter != actorStructDecls.end() ) { // this is a derived actordecl367 // get list of fwd decls that we can now insert368 toAddAfter = forwardDecls.updateDecl( decl, false ); 369 370 // get rid of decl from actorStructDecls since we no longer need it371 actorStructDecls.erase( actorIter);372 } else {373 auto messageIter = messageStructDecls.find( decl ); 374 if ( messageIter == messageStructDecls.end() ) return;375 376 toAddAfter = forwardDecls.updateDecl( decl, true);377 378 // get rid of decl from messageStructDecls since we no longer need it 379 messageStructDecls.erase( messageIter );380 }381 382 // add the fwd decls to declsToAddAfter383 for ( FunctionDecl * func : toAddAfter ) {384 declsToAddAfter.push_back( func );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 forward decl 250 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 instances 258 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 routine 263 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) { 264 done = true; 265 for ( const auto & func : forwardDecls ) { 266 declsToAddBefore.push_back( func ); 267 } 385 268 } 386 269 } 387 270 388 271 public: 389 GenFwdDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,390 FwdDeclTable& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),391 forwardDecls(forwardDecls) {}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) {} 392 275 }; 393 276 394 277 void implementActors( TranslationUnit & translationUnit ) { 395 // unordered_maps to collect all derived actor and message types396 unordered_set<const StructDecl *> actorStructDecls;397 unordered_set<const StructDecl *> messageStructDecls;398 FwdDeclTableforwardDecls;278 // maps to collect all derived actor and message types 279 std::map<const StructDecl *, int> actorStructDecls; 280 std::map<const StructDecl *, int> messageStructDecls; 281 std::vector<FunctionDecl *> forwardDecls; 399 282 400 283 // for storing through the passes
Note:
See TracChangeset
for help on using the changeset viewer.