charmxi cleanup: rename atomic construct to serial internally
[charm.git] / src / xlat-i / sdag / CSdagConstruct.C
bloba17c7a9d7c80f2f80f0684a9166a84f66310069b
1 #include <string.h>
2 #include <stdlib.h>
3 #include "sdag-globals.h"
4 #include "xi-symbol.h"
5 #include "xi-Chare.h"
6 #include "constructs/Constructs.h"
7 #include "CParsedFile.h"
8 #include "EToken.h"
9 #include "CStateVar.h"
10 #include <list>
11 using std::list;
12 #include <algorithm>
13 using std::for_each;
14 #include <functional>
15 using std::mem_fun;
17 namespace xi {
18   SdagConstruct::SdagConstruct(EToken t, SdagConstruct *construct1) {
19     init(t);
20     constructs->push_back(construct1);
21   }
23   SdagConstruct::SdagConstruct(EToken t, SdagConstruct *construct1, SdagConstruct *aList) {
24     init(t);
25     constructs->push_back(construct1);
26     constructs->insert(constructs->end(), aList->constructs->begin(), aList->constructs->end());
27   }
29   SdagConstruct::SdagConstruct(EToken t, XStr *txt, SdagConstruct *c1, SdagConstruct *c2, SdagConstruct *c3,
30                                SdagConstruct *c4, SdagConstruct *constructAppend, EntryList *el) {
31     init(t);
32     text = txt;
33     con1 = c1; con2 = c2; con3 = c3; con4 = c4;
34     if (constructAppend != 0) constructs->push_back(constructAppend);
35     elist = el;
36   }
38   SdagConstruct::SdagConstruct(EToken t, const char *entryStr, const char *codeStr, ParamList *pl) {
39     init(t);
40     text = new XStr(codeStr);
41     param = pl;
42   }
44   void SdagConstruct::init(EToken& t) {
45     con1 = 0; con2 = 0; con3 = 0; con4 = 0;
46     traceName = 0;
47     elist = 0;
48     constructs = new list<SdagConstruct*>();
49     type = t;
50     label_str = 0;
51   }
53   SdagConstruct::~SdagConstruct() {
54     delete constructs;
55     delete text;
56   }
58   void SdagConstruct::numberNodes(void) {
59     if (constructs != 0)
60       for_each(constructs->begin(), constructs->end(), mem_fun(&SdagConstruct::numberNodes));
61   }
63   XStr* SdagConstruct::createLabel(const char* str, int nodeNum) {
64     char text[128];
65     if (nodeNum != -1)
66       sprintf(text, "_%s_%d", str, nodeNum);
67     else
68       sprintf(text, "%s", str);
70     return new XStr(text);
71   }
73   void SdagConstruct::labelNodes() {
74     if (label_str != 0)
75       label = createLabel(label_str, nodeNum);
77     if (constructs != 0)
78       for_each(constructs->begin(), constructs->end(), mem_fun(&SdagConstruct::labelNodes));
79   }
81   void EntryList::generateEntryList(list<CEntry*>& CEntrylist, WhenConstruct *thisWhen) {
82     EntryList *el = this;
83     while (el != NULL) {
84       el->entry->generateEntryList(CEntrylist, thisWhen);
85       el = el->next;
86     }
87   }
89   void Entry::generateEntryList(list<CEntry*>& CEntrylist, WhenConstruct *thisWhen) {
90     // case SENTRY:
91     bool found = false;
92    
93     for(list<CEntry *>::iterator entry=CEntrylist.begin(); 
94         entry != CEntrylist.end(); ++entry) {
95       if(*((*entry)->entry) == (const char *)name) 
96         {
97           ParamList *epl;
98           epl = (*entry)->paramlist;
99           ParamList *pl;
100           pl = param;
101           found = false;
102           if (((*entry)->paramlist->isVoid() == 1) && (pl->isVoid() == 1)) {
103             found = true;
104           }
105           while ((pl != NULL) && (epl != NULL))
106             {
107               bool kindMatches =
108                 (pl->isArray() && epl->isArray()) ||
109                 (pl->isBuiltin() && epl->isBuiltin()) ||
110                 (pl->isReference() && epl->isReference()) ||
111                 (pl->isMessage() && epl->isMessage()) ||
112                 (pl->isNamed() && epl->isNamed());
113               bool baseNameMatches = (strcmp(pl->getBaseName(), epl->getBaseName()) == 0);
114               if (kindMatches && baseNameMatches)
115                 found = true;
117               pl = pl->next;
118               epl = epl->next;
119             }
120           if (((pl == NULL) && (epl != NULL)) ||
121               ((pl != NULL) && (epl == NULL)))
122             found = false;
123           if (found) {
124             // check to see if thisWhen is already in entry's whenList
125             bool whenFound = false;
126             for(list<WhenConstruct*>::iterator it = (*entry)->whenList.begin();
127                 it != (*entry)->whenList.end(); ++it) {
128               if ((*it)->nodeNum == thisWhen->nodeNum)
129                 whenFound = true;
130             }
131             if(!whenFound)
132               (*entry)->whenList.push_back(thisWhen);
133             entryPtr = *entry;
134             if(intExpr != 0)
135               (*entry)->refNumNeeded = 1; 
136           } 
137         }
138     }
139     if(!found) {
140       CEntry *newEntry;
141       newEntry = new CEntry(new XStr(name), param, estateVars, paramIsMarshalled(), first_line_, last_line_);
142       CEntrylist.push_back(newEntry);
143       entryPtr = newEntry;
144       newEntry->whenList.push_back(thisWhen);
145       if(intExpr != 0)
146         newEntry->refNumNeeded = 1; 
147     }
148     //break;
149   }
151   void SdagConstruct::generateEntryList(list<CEntry*>& CEntrylist, WhenConstruct *thisWhen) {
152     if (SIF == type && con2 != 0)
153       con2->generateEntryList(CEntrylist, thisWhen);
154     generateChildrenEntryList(CEntrylist, thisWhen);
155   }
157   void SdagConstruct::generateChildrenEntryList(list<CEntry*>& CEntrylist, WhenConstruct *thisWhen) {
158     if (constructs != 0)
159       for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end(); ++it)
160         (*it)->generateEntryList(CEntrylist, thisWhen);
161   }
163   void SdagConstruct::propagateState(int uniqueVarNum) {
164     CStateVar *sv; 
165     list<EncapState*> encap;
167     stateVars = new list<CStateVar*>();
168     ParamList *pl = param;
169     if (!pl->isVoid()) {
170       while (pl != NULL) {
171         stateVars->push_back(new CStateVar(pl));
172         pl = pl->next;
173       }
174     
175       EncapState* state = new EncapState(this->entry, *stateVars);
176       if (!this->entry->paramIsMarshalled() && !this->entry->param->isVoid())
177         state->isMessage = true;
178       encap.push_back(state);
179     }
181     encapState = encap;
183 #if CMK_BIGSIM_CHARM
184     // adding _bgParentLog as the last extra parameter for tracing
185     stateVarsChildren = new list<CStateVar*>(*stateVars);
186     sv = new CStateVar(0, "void *", 0,"_bgParentLog", 0, NULL, 1);
187     sv->isBgParentLog = true;
188     stateVarsChildren->push_back(sv);
190     {
191       list<CStateVar*> lst;
192       lst.push_back(sv);
193       EncapState *state = new EncapState(NULL, lst);
194       state->type = new XStr("void");
195       state->name = new XStr("_bgParentLog");
196       state->isBgParentLog = true;
197       encapStateChild.push_back(state);
198       encap.push_back(state);
199     }
200 #else
201     stateVarsChildren = stateVars; 
202 #endif
204     encapStateChild = encap;
206     list<CStateVar*> whensEntryMethodStateVars;
207     for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
208          ++it)
209       (*it)->propagateState(encap, *stateVarsChildren, whensEntryMethodStateVars, uniqueVarNum);
210   }
212   void SdagConstruct::propagateState(list<EncapState*> encap, list<CStateVar*>& plist, list<CStateVar*>& wlist, int uniqueVarNum) {
213     CStateVar *sv;
214     list<CStateVar*> *whensEntryMethodStateVars = NULL;
216     encapState = encap;
218     stateVars = new list<CStateVar*>();
219     switch(type) {
220     case SINT_EXPR:
221     case SIDENT:
222     case SENTRY:
223     case SELIST:
224       break;
225     default:
226       fprintf(stderr, "internal error in sdag translator..\n");
227       exit(1);
228       break;
229     }
231     encapStateChild = encap;
233     propagateStateToChildren(encap, *stateVarsChildren, wlist, uniqueVarNum);
234     delete whensEntryMethodStateVars;
235   }
238   void SdagConstruct::propagateStateToChildren(list<EncapState*> encap, list<CStateVar*>& stateVarsChildren, list<CStateVar*>& wlist, int uniqueVarNum) {
239     if (constructs != 0)
240       for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end(); ++it)
241         (*it)->propagateState(encap, stateVarsChildren, wlist, uniqueVarNum);
242   }
244   void SdagConstruct::generateCode(XStr& decls, XStr& defs, Entry *entry) {
245     generateChildrenCode(decls, defs, entry);
246   }
248   void SdagConstruct::generateChildrenCode(XStr& decls, XStr& defs, Entry* entry) {
249     if (constructs != 0)
250       for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end(); ++it)
251         (*it)->generateCode(decls, defs, entry);
252   }
254   void SdagConstruct::buildTypes(list<EncapState*>& state) {
255     for (list<EncapState*>::iterator iter = state.begin(); iter != state.end(); ++iter) {
256       EncapState& encap = **iter;
257       if (!encap.type) {
258         if (encap.entry->entryPtr && encap.entry->entryPtr->decl_entry)
259           encap.type = encap.entry->entryPtr->decl_entry->genClosureTypeNameProxyTemp;
260         else
261           encap.type = encap.entry->genClosureTypeNameProxyTemp;
262       }
263     }
264   }
266   int SdagConstruct::unravelClosuresBegin(XStr& defs, bool child) {
267     int cur = 0;
269     list<EncapState*>& encaps = child ? encapStateChild : encapState;
271     // traverse all the state variables bring them into scope
272     for (list<EncapState*>::iterator iter = encaps.begin(); iter != encaps.end(); ++iter, ++cur) {
273       EncapState& state = **iter;
275       indentBy(defs, cur + 1);
277       defs << "{\n";
279       int i = 0;
280       for (list<CStateVar*>::iterator iter2 = state.vars.begin(); iter2 != state.vars.end(); ++iter2, ++i) {
281         CStateVar& var = **iter2;
283         // if the var is one of the following it a system state var that should
284         // not be brought into scope
285         if (!var.isCounter && !var.isSpeculator && !var.isBgParentLog) {
286           indentBy(defs, cur + 2);
288           defs << var.type << (var.arrayLength || var.isMsg ? "*" : "") << "& " << var.name << " = ";
289           state.name ? (defs << *state.name) : (defs << "gen" << cur);
290           if (!var.isMsg)
291             defs << "->" << "getP" << i << "();\n";
292           else
293             defs << ";\n";
294         }
295       }
296     }
298     return cur + 1;
299   }
301   void SdagConstruct::unravelClosuresEnd(XStr& defs, bool child) {
302     list<EncapState*>& encaps = child ? encapStateChild : encapState;
304     int cur = encaps.size();
306     // traverse all the state variables bring them into scope
307     for (list<EncapState*>::iterator iter = encaps.begin(); iter != encaps.end(); ++iter, --cur) {
308       EncapState& state = **iter;
310       indentBy(defs, cur);
312       defs << "}\n";
313     }
314   }
316   void generateVarSignature(XStr& str,
317                          const XStr* name, const char* suffix,
318                          list<CStateVar*>* params) {
319     
320   }
321   void generateVarSignature(XStr& decls, XStr& defs,
322                          const Entry* entry, bool declareStatic, const char* returnType,
323                          const XStr* name, bool isEnd,
324                          list<CStateVar*>* params) {
325     generateVarSignature(decls, defs, entry->getContainer(), declareStatic, returnType,
326                       name, isEnd, params);
327   }
328   void generateVarSignature(XStr& decls, XStr& defs,
329                          const Chare* chare, bool declareStatic, const char* returnType,
330                          const XStr* name, bool isEnd,
331                          list<CStateVar*>* params) {
332     decls << "  " << (declareStatic ? "static " : "") << returnType << " ";
334     templateGuardBegin(false, defs);
335     defs << chare->tspec() << returnType << " " << chare->baseName() << "::";
337     XStr op;
339     op << name;
340     if (isEnd)
341       op << "_end";
342     op << "(";
344     if (params) {
345       CStateVar *sv;
346       int count = 0;
347       for (list<CStateVar*>::iterator iter = params->begin();
348            iter != params->end();
349            ++iter) {
350         CStateVar *sv = *iter;
351         if (sv->isVoid != 1) {
352           if (count != 0)
353             op << ", ";
355           // @TODO uncommenting this requires that PUP work on const types
356           //if (sv->byConst)
357           //op << "const ";
358           if (sv->type != 0) 
359             op <<sv->type <<" ";
360           if (sv->declaredRef)
361             op <<" &";
362           if (sv->arrayLength != NULL) 
363             op <<"* ";
364           if (sv->name != 0)
365             op <<sv->name;
367           count++;
368         }
369       }
370     }
372     op << ")";
374     decls << op << ";\n";
375     defs << op << " { // Potentially missing " << chare->baseName() << "_SDAG_CODE in your class definition?\n";
376   }
377   void endMethod(XStr& op) {
378     op << "}\n";
379     templateGuardEnd(op);
380     op << "\n\n";
381   }
383   void generateClosureSignature(XStr& decls, XStr& defs,
384                                 const Entry* entry, bool declareStatic, const char* returnType,
385                                 const XStr* name, bool isEnd,
386                                 list<EncapState*> encap, int numRefs) {
387     generateClosureSignature(decls, defs, entry->getContainer(), declareStatic, returnType,
388                              name, isEnd, encap, numRefs);
389   }
390   void generateClosureSignature(XStr& decls, XStr& defs, const Chare* chare,
391                                 bool declareStatic, const char* returnType,
392                                 const XStr* name, bool isEnd, list<EncapState*> encap, int numRefs) {
393     decls << "  " << (declareStatic ? "static " : "") << returnType << " ";
395     templateGuardBegin(false, defs);
396     defs << chare->tspec() << returnType << " " << chare->baseName() << "::";
398     XStr op;
400     op << name;
401     if (isEnd) op << "_end";
402     op << "(";
404     int cur = 0;
405     for (list<EncapState*>::iterator iter = encap.begin();
406          iter != encap.end(); ++iter, ++cur) {
407       EncapState *state = *iter;
409       if (state->type) {
410         op << *state->type << "* ";
411         if (state->name) op << *state->name;
412         else op << "gen" << cur;
413       } else {
414         fprintf(stderr, "type was not propagated to this phase");
415         exit(120);
416       }
418       if (cur != encap.size() - 1) op << ", ";
419     }
421     for (int i = 0; i < numRefs; i++) op << ((cur+i) > 0 ? ", " : "") << "int refnum_" << i;
423     op << ")";
425     decls << op << ";\n";
426     defs << op << " {\n";
427   }
429   void SdagConstruct::generateCall(XStr& op, list<EncapState*>& scope,
430                                       list<EncapState*>& next, const XStr* name,
431                                       const char* nameSuffix) {
432     op << name << (nameSuffix ? nameSuffix : "") << "(";
434     int cur = 0;
435     for (list<EncapState*>::iterator iter = next.begin(); iter != next.end(); ++iter, ++cur) {
436       EncapState *state = *iter;
438       if (state->type) {
439         if (cur >= scope.size()) {
440           int offset = cur - scope.size();
441           if (!state->isMessage)
442             op << "static_cast<" << *state->type << "*>(buf" << offset << "->cl)";
443           else
444             op << "static_cast<" << *state->type << "*>(static_cast<SDAG::MsgClosure*>(buf" << offset << "->cl)->msg)";
445         } else {
446           if (state->name) op << *state->name; else op << "gen" << cur;
447         }
448       } else {
449         fprintf(stderr, "type was not propagated to this phase");
450         exit(120);
451       }
453       if (cur != next.size() - 1) op << ", ";
454     }
456     op << ");\n";
457   }
459   // boe = 1, if the next call is to begin construct
460   // boe = 0, if the next call is to end a contruct
461   void SdagConstruct::setNext(SdagConstruct *n, int boe) {
462     switch(type) {
463     case SSLIST:
464       next = n;
465       nextBeginOrEnd = boe;
466       {
467         if (constructs->empty())
468           return;
470         list<SdagConstruct*>::iterator it = constructs->begin();
471         SdagConstruct *cn = *it;
472         ++it;
474         for(; it != constructs->end(); ++it) {
475           cn->setNext(*it, 1);
476           cn = *it;
477         }
478         cn->setNext(this, 0);
479       }
480       return;
481     case SCASELIST:
482       next = n;
483       nextBeginOrEnd = boe;
484       {
485         for(list<SdagConstruct*>::iterator it = constructs->begin();
486             it != constructs->end();
487             ++it) {
488           (*it)->setNext(this, 0);
489         }
490       }
491       return;
492     case SCASE:
493     case SSDAGENTRY:
494     case SOVERLAP:
495     case SOLIST:
496     case SFORALL:
497     case SWHEN:
498     case SFOR:
499     case SWHILE:
500     case SSERIAL:
501     case SELSE:
502       next = n;
503       nextBeginOrEnd = boe;
504       n = this; boe = 0; break;
505     case SIF:
506       next = n;
507       nextBeginOrEnd = boe;
508       if(con2 != 0)
509         con2->setNext(n, boe);
510       n = this;
511       boe = 0;
512       break;
513     default:
514       break;
515     }
516     SdagConstruct *cn;
517     if (constructs != 0) {
518       for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
519            ++it) {
520         (*it)->setNext(n, boe);
521       }
522     }
523   }
525   // for trace
526   void SdagConstruct::generateTrace() {
527     for_each(constructs->begin(), constructs->end(), mem_fun(&SdagConstruct::generateTrace));
528     if (con1) con1->generateTrace();
529     if (con2) con2->generateTrace();
530     if (con3) con3->generateTrace();
531   }
533   void SdagConstruct::generateTraceBeginCall(XStr& op, int indent) {
534     if (traceName) {
535       indentBy(op, indent);
536       op << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, (" << "_sdag_idx_" << traceName << "()), CkMyPe(), 0, ";
538       if (entry->getContainer()->isArray())
539         op << "ckGetArrayIndex().getProjectionID()";
540       else
541         op << "NULL";
543       op << ", this); \n";
544     }
545   }
547   void SdagConstruct::generateDummyBeginExecute(XStr& op, int indent, Entry *entry) {
548     indentBy(op, indent);
549     op << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, _sdagEP, CkMyPe(), 0, ";
551     if (entry->getContainer()->isArray())
552       op << "ckGetArrayIndex().getProjectionID()";
553     else
554       op << "NULL";
556     op << ", this); \n";
557   }
559   void SdagConstruct::generateTraceEndCall(XStr& op, int indent) {
560     indentBy(op, indent);
561     op << "_TRACE_END_EXECUTE(); \n";
562   }
564   void SdagConstruct::generateBeginExec(XStr& op, const char *name) {
565     op << "     " << "_TRACE_BG_BEGIN_EXECUTE_NOMSG(\""<<name<<"\", &_bgParentLog,1);\n";
566   }
568   void SdagConstruct::generateEndExec(XStr& op){
569     op << "     " << "_TRACE_BG_END_EXECUTE(0);\n";
570   }
572   void SdagConstruct::generateBeginTime(XStr& op) {
573     //Record begin time for tracing
574     op << "  double __begintime = CkVTimer(); \n";
575   }
577   void SdagConstruct::generateTlineEndCall(XStr& op) {
578     //Trace this event
579     op <<"    _TRACE_BG_TLINE_END(&_bgParentLog);\n";
580   }
582   void SdagConstruct::generateEndSeq(XStr& op) {
583     op <<  "    void* _bgParentLog = NULL;\n";
584     op <<  "    CkElapse(0.01e-6);\n";
585     //op<<  "    BgElapse(1e-6);\n";
586     generateTlineEndCall(op);
587     generateTraceEndCall(op, 1);
588     generateEndExec(op);
589   }
591   void SdagConstruct::generateEventBracket(XStr& op, int eventType) {
592     (void) eventType;
593     //Trace this event
594     op << "     _TRACE_BG_USER_EVENT_BRACKET(\"" << nameStr
595        << "\", __begintime, CkVTimer(), &_bgParentLog); \n";
596   }
598   void SdagConstruct::generateListEventBracket(XStr& op, int eventType) {
599     (void) eventType;
600     op << "     _TRACE_BGLIST_USER_EVENT_BRACKET(\"" << nameStr
601        << "\", __begintime,CkVTimer(), &_bgParentLog, " << label
602        << "_bgLogList);\n";
603   }
605   void SdagConstruct::generateRegisterEp(XStr& defs) {
606     if (traceName)
607       defs << "  (void)_sdag_idx_" << traceName << "();\n";
609     for (list<SdagConstruct*>::iterator iter = constructs->begin(); iter != constructs->end(); ++iter)
610       (*iter)->generateRegisterEp(defs);
611     if (con1) con1->generateRegisterEp(defs);
612     if (con2) con2->generateRegisterEp(defs);
613     if (con3) con3->generateRegisterEp(defs);
614   }
616   void SdagConstruct::generateTraceEp(XStr& decls, XStr& defs, Chare* chare) {
617     if (traceName) {
618       XStr regName, idxName;
620       idxName << "_sdag_idx_" << traceName;
621       regName << "_sdag_reg_" << traceName;
622       generateVarSignature(decls, defs, chare, true, "int", &idxName, false, NULL);
623       defs << "  static int epidx = " << regName << "();\n"
624            << "  return epidx;\n";
625       endMethod(defs);
627       generateVarSignature(decls, defs, chare, true, "int", &regName, false, NULL);
628       defs << "  return CkRegisterEp(\""
629            << traceName << "\", NULL, 0, " << chare->indexName() << "::__idx, 0"
630            << ");\n";
631       endMethod(defs);
632     }
634     for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
635          ++it) {
636       (*it)->generateTraceEp(decls, defs, chare);
637     }
638     if (con1) con1->generateTraceEp(decls, defs, chare);
639     if (con2) con2->generateTraceEp(decls, defs, chare);
640     if (con3) con3->generateTraceEp(decls, defs, chare);
641   }
642 }   // namespace xi