Changes in src/Concurrency/Actors.cpp [ccf1d99:34ed17b]
- File:
-
- 1 edited
-
src/Concurrency/Actors.cpp (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Actors.cpp
rccf1d99 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 #define __ALLOC 0 // C_TODO: complete swap to no-alloc version183 184 68 struct GenReceiveDecls : public ast::WithDeclsToAdd<> { 185 unordered_set<const StructDecl *> & actorStructDecls;186 unordered_set<const StructDecl *> & messageStructDecls;69 std::map<const StructDecl *, int> & actorStructDecls; 70 std::map<const StructDecl *, int> & messageStructDecls; 187 71 const StructDecl ** requestDecl; 188 72 const EnumDecl ** allocationDecl; 189 73 const StructDecl ** actorDecl; 190 74 const StructDecl ** msgDecl; 191 FwdDeclTable& forwardDecls;75 std::vector<FunctionDecl *> & forwardDecls; 192 76 193 77 void postvisit( const FunctionDecl * decl ) { … … 206 90 207 91 // If the struct instances are derived actor and message types then generate the message send routine 208 auto actorIter = actorStructDecls.find( arg1InstType->aggr() ); 209 auto messageIter = messageStructDecls.find( arg2InstType->aggr() ); 210 if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) { 92 if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) { 211 93 212 94 // check that we have found all the decls we need from <actor.hfa> … … 225 107 return receiver; 226 108 } 227 */ // C_TODO: update this with new no alloc version109 */ 228 110 CompoundStmt * sendBody = new CompoundStmt( decl->location ); 229 111 230 #if __ALLOC231 112 // Generates: request * new_req = alloc(); 232 113 sendBody->push_back( new DeclStmt( … … 239 120 ) 240 121 )); 241 #else242 // 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 #endif252 122 253 123 // Function type is: Allocation (*)( derived_actor &, derived_msg & ) … … 290 160 )); 291 161 292 #if __ALLOC293 162 // Generates: (*new_req){ &receiver, &msg, fn }; 294 163 sendBody->push_back( new ExprStmt( … … 320 189 ) 321 190 )); 322 #else323 // 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 #endif353 191 354 192 // Generates: return receiver; … … 387 225 388 226 // forward decls to resolve use before decl problem for '|' routines 389 forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) ); 390 // forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 227 forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) ); 391 228 392 229 sendOperatorFunction->stmts = sendBody; … … 396 233 397 234 public: 398 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, 399 236 const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 400 FwdDeclTable& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),237 std::vector<FunctionDecl *> & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 401 238 requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {} 402 239 }; 403 240 404 241 struct GenFwdDecls : public ast::WithDeclsToAdd<> { 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 actordecl413 // get list of fwd decls that we can now insert414 toAddAfter = forwardDecls.updateDecl( decl, false ); 415 416 // get rid of decl from actorStructDecls since we no longer need it417 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 declsToAddAfter429 for ( FunctionDecl * func : toAddAfter ) {430 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 } 431 268 } 432 269 } 433 270 434 271 public: 435 GenFwdDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,436 FwdDeclTable& forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),437 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) {} 438 275 }; 439 276 440 277 void implementActors( TranslationUnit & translationUnit ) { 441 // unordered_maps to collect all derived actor and message types442 unordered_set<const StructDecl *> actorStructDecls;443 unordered_set<const StructDecl *> messageStructDecls;444 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; 445 282 446 283 // for storing through the passes
Note:
See TracChangeset
for help on using the changeset viewer.