f5f8815c9752daa620bcab67cb392014a9b92207
[charm.git] / src / xlat-i / sdag / CSdagConstruct.C
1 #include <string.h>
2 #include <stdlib.h>
3 #include "sdag-globals.h"
4 #include "xi-symbol.h"
5 //#include "CParsedFile.h"
6 #include "EToken.h"
7
8 namespace xi {
9
10 SdagConstruct *buildAtomic(const char* code,
11                            SdagConstruct *pub_list,
12                            const char *trace_name)
13 {
14   char *tmp = strdup(code);
15   RemoveSdagComments(tmp);
16   SdagConstruct *ret = new SdagConstruct(SATOMIC, new XStr(tmp), pub_list, 0,0,0,0, 0 );
17   free(tmp);
18
19   if (trace_name)
20   {
21     tmp = strdup(trace_name);
22     tmp[strlen(tmp)-1]=0;
23     ret->traceName = new XStr(tmp+1);
24     free(tmp);
25   }
26
27   return ret;
28 }
29
30 void SdagConstruct::numberNodes(void)
31 {
32   switch(type) {
33     case SSDAGENTRY: nodeNum = numSdagEntries++; break;
34     case SOVERLAP: nodeNum = numOverlaps++; break;
35     case SWHEN: nodeNum = numWhens++; break;
36     case SFOR: nodeNum = numFors++; break;
37     case SWHILE: nodeNum = numWhiles++; break;
38     case SIF: nodeNum = numIfs++; if(con2!=0) con2->numberNodes(); break;
39     case SELSE: nodeNum = numElses++; break;
40     case SFORALL: nodeNum = numForalls++; break;
41     case SSLIST: nodeNum = numSlists++; break;
42     case SOLIST: nodeNum = numOlists++; break;
43     case SATOMIC: nodeNum = numAtomics++; break;
44     case SFORWARD: nodeNum = numForwards++; break;
45     case SCONNECT: nodeNum = numConnects++; break;
46     case SINT_EXPR:
47     case SIDENT: 
48     default:
49       break;
50   }
51   SdagConstruct *cn;
52   if (constructs != 0) {
53     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
54       cn->numberNodes();
55     }
56   }
57 }
58
59 void SdagConstruct::labelNodes(void)
60 {
61   char text[128];
62   switch(type) {
63     case SSDAGENTRY:
64       sprintf(text, "%s", con1->text->charstar());
65       label = new XStr(text);
66       break;
67     case SOVERLAP: 
68       sprintf(text, "_overlap_%d", nodeNum); 
69       label = new XStr(text);
70       break;
71     case SWHEN: 
72       sprintf(text, "_when_%d", nodeNum); 
73       label = new XStr(text);
74       EntryList *el;
75       el = elist;
76       while (el !=NULL) {
77         el->entry->label = new XStr(el->entry->name);
78         el=el->next; 
79       }
80       break;
81     case SFOR: 
82       sprintf(text, "_for_%d", nodeNum); 
83       label = new XStr(text);
84       break;
85     case SWHILE: 
86       sprintf(text, "_while_%d", nodeNum); 
87       label = new XStr(text);
88       break;
89     case SIF: 
90       sprintf(text, "_if_%d", nodeNum); 
91       label = new XStr(text);
92       if(con2!=0) con2->labelNodes();
93       break;
94     case SELSE: 
95       sprintf(text, "_else_%d", nodeNum); 
96       label = new XStr(text);
97       break;
98     case SFORALL: 
99       sprintf(text, "_forall_%d", nodeNum); 
100       label = new XStr(text);
101       break;
102     case SSLIST: 
103       sprintf(text, "_slist_%d", nodeNum); 
104       label = new XStr(text);
105       break;
106     case SOLIST: 
107       sprintf(text, "_olist_%d", nodeNum); 
108       label = new XStr(text);
109       break;
110     case SATOMIC: 
111       sprintf(text, "_atomic_%d", nodeNum); 
112       label = new XStr(text);
113       break;
114     case SFORWARD: 
115       sprintf(text, "_forward_%d", nodeNum); 
116       label = new XStr(text);
117       break;
118     case SCONNECT:
119       sprintf(text, "_connect_%s",connectEntry->charstar()); 
120       label = new XStr(text);
121       break;
122     case SINT_EXPR:
123     case SIDENT:
124     default:
125       break;
126   }
127   SdagConstruct *cn;
128   if (constructs != 0) {
129     for(cn=(SdagConstruct *)(constructs->begin()); !constructs->end(); cn=(SdagConstruct *)(constructs->next())) {
130       cn->labelNodes();
131     }
132   }
133 }
134
135 void EntryList::generateEntryList(TList<CEntry*>& CEntrylist, SdagConstruct *thisWhen)
136 {
137    EntryList *el;
138    el = this;
139    while (el != NULL)
140    {
141      el->entry->generateEntryList(CEntrylist, thisWhen);
142      el = el->next;
143    }
144 }
145
146 void Entry::generateEntryList(TList<CEntry*>& CEntrylist, SdagConstruct *thisWhen)
147 {
148    // case SENTRY:
149    CEntry *entry;
150    int notfound=1;
151    
152    for(entry=CEntrylist.begin(); !CEntrylist.end(); entry=CEntrylist.next()) {
153      if(*(entry->entry) == (const char *)name) 
154      {
155         ParamList *epl;
156         epl = entry->paramlist;
157         ParamList *pl;
158         pl = param;
159         notfound = 1;
160         if ((entry->paramlist->isVoid() == 1) && (pl->isVoid() == 1)) {
161            notfound = 0;
162         }
163         while ((pl != NULL) && (epl != NULL))
164         {
165            if (pl->isArray() && epl->isArray()) {
166              if (strcmp(pl->getBaseName(), epl->getBaseName()) == 0)
167                 notfound = 0;
168            }
169            else if (pl->isBuiltin() && epl->isBuiltin()) {
170              if (strcmp(pl->getBaseName(), epl->getBaseName()) == 0)
171                 notfound = 0;
172            }
173            else if (pl->isReference() && epl->isReference()) {
174              if (strcmp(pl->getBaseName(), epl->getBaseName()) == 0)
175                 notfound = 0;
176            }
177            else if (pl->isMessage() && epl->isMessage()) {
178              if (strcmp(pl->getBaseName(), epl->getBaseName()) == 0)
179                 notfound = 0;
180            }
181            else if (pl->isNamed() && epl->isNamed()) {
182              if (strcmp(pl->getBaseName(), epl->getBaseName()) == 0)
183                 notfound = 0;
184            }
185            pl = pl->next;
186            epl = epl->next;
187         }
188         if (((pl == NULL) && (epl != NULL)) ||
189            ((pl != NULL) && (epl == NULL)))
190              notfound = 1;
191         if (notfound == 0) {
192           // check to see if thisWhen is already in entry's whenList
193           int whenFound = 0;
194           TList<SdagConstruct*> *tmpList = &(entry->whenList);
195           SdagConstruct *tmpNode;
196           for(tmpNode = tmpList->begin(); !tmpList->end(); tmpNode = tmpList->next()) {
197             if(tmpNode->nodeNum == thisWhen->nodeNum)
198                whenFound = 1;
199           }
200           if(!whenFound)
201             entry->whenList.append(thisWhen);
202           entryPtr = entry;
203           if(intExpr != 0)
204             entry->refNumNeeded = 1; 
205          } 
206      }
207    }
208    if(notfound == 1) {
209      CEntry *newEntry;
210      newEntry = new CEntry(new XStr(name), param, estateVars, paramIsMarshalled() );
211      CEntrylist.append(newEntry);
212      entryPtr = newEntry;
213      newEntry->whenList.append(thisWhen);
214      if(intExpr != 0)
215        newEntry->refNumNeeded = 1; 
216    }
217       //break;
218 }
219
220 void SdagConstruct::generateEntryList(TList<CEntry*>& CEntrylist, SdagConstruct *thisWhen)
221 {
222   SdagConstruct *cn;
223   switch(type) {
224     case SWHEN:
225       elist->generateEntryList(CEntrylist, this);  /* con1 is the WHEN's ELIST */
226       break;
227     case SIF:
228         /* con2 is the ELSE corresponding to this IF */
229       if(con2!=0) con2->generateEntryList(CEntrylist, thisWhen); 
230       break;
231   }
232   if (constructs != 0) {
233     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
234       cn->generateEntryList(CEntrylist,thisWhen);
235     }
236   }
237 }
238  
239 void SdagConstruct::generateConnectEntries(XStr& op){
240    op << "  void " <<connectEntry->charstar() <<'(';
241    ParamList *pl = param;
242    XStr msgParams;
243    int i, numStars;
244    int count;
245    if (pl->isVoid() == 1) {
246      op << "void) {\n"; 
247    }
248    else if (pl->isMessage() == 1){
249      op << pl->getBaseName() <<" *" <<pl->getGivenName() <<") {\n";
250    }
251    else {
252     count = 0;
253     op << "CkMarshallMsg *" /*<< connectEntry->charstar()*/ <<"_msg) {\n";
254     msgParams <<"   char *impl_buf= _msg->msgBuf;\n";
255     param->beginUnmarshall(msgParams);
256    }
257    op << msgParams.charstar() <<"\n"; 
258    op << "  " <<text->charstar() <<"\n";
259
260    op << "  }\n";
261    
262 }
263
264 void SdagConstruct::generateConnectEntryList(TList<SdagConstruct*>& ConnectEList) {
265   if (type == SCONNECT)
266      ConnectEList.append(this);
267   if (constructs != 0) {
268     SdagConstruct *cn;
269     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
270       cn->generateConnectEntryList(ConnectEList);
271     }
272   }
273
274 }
275
276 void SdagConstruct::propagateState(int uniqueVarNum)
277
278   CStateVar *sv; 
279   /*if(type != SSDAGENTRY) {
280     fprintf(stderr, "use of non-entry as the outermost construct..\n");
281     exit(1);
282   }*/
283   stateVars = new TList<CStateVar*>();
284   ParamList *pl = param;
285   if (pl->isVoid() == 1) {
286      sv = new CStateVar(1, NULL, 0, NULL, 0, NULL, 0);
287      stateVars->append(sv);
288   }
289   else if (pl->isMessage() == 1){
290      sv = new CStateVar(0, pl->getBaseName(), 1, pl->getGivenName(), 0, NULL, 1);
291      stateVars->append(sv);
292   }
293   else {
294     while(pl != NULL) {
295       if (pl->isPointer() == 1) {
296         sv = new CStateVar(0, pl->getBaseName(), pl->getNumStars(), pl->getGivenName(), 0, NULL, 0); 
297       }
298       else if (pl->isReference() == 1) {
299         sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), new XStr("&"), NULL, 0); 
300
301       }
302       else if (pl->isArray() == 1) {
303         sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), 0, pl->getArrayLen(), 0); 
304       }
305       else if (pl->isBuiltin() == 1) {
306         sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), 0, NULL, 0); 
307
308       }
309       else if (pl->isNamed()) {
310           sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), 0, NULL, 0); 
311       }
312       pl = pl->next;
313       stateVars->append(sv);
314     }
315   }
316
317 #if CMK_BLUEGENE_CHARM
318   // adding _bgParentLog as the last extra parameter for tracing
319   stateVarsChildren = new TList<CStateVar*>();
320
321   for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next())
322     stateVarsChildren->append(sv);
323   sv = new CStateVar(0, "void *", 0,"_bgParentLog", 0, NULL, 1);  
324   stateVarsChildren->append(sv);
325 #else
326   stateVarsChildren = stateVars; 
327 #endif
328
329   SdagConstruct *cn;
330   TList<CStateVar*> *whensEntryMethodStateVars; 
331   whensEntryMethodStateVars = new TList<CStateVar*>();
332   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
333      cn->propagateState(*stateVarsChildren, *whensEntryMethodStateVars , *publishesList, uniqueVarNum);
334   }
335 }
336
337
338 void SdagConstruct::propagateState(TList<CStateVar*>& list, TList<CStateVar*>& wlist, TList<SdagConstruct*>& publist, int uniqueVarNum)
339 {
340   CStateVar *sv;
341   int i;
342   TList <CStateVar*> *olistTempStateVars;
343   TList<CStateVar*> *whensEntryMethodStateVars; 
344   olistTempStateVars = new TList<CStateVar*>();
345   stateVars = new TList<CStateVar*>();
346   switch(type) {
347     case SFORALL:
348       stateVarsChildren = new TList<CStateVar*>();
349       for(sv=list.begin(); !list.end(); sv=list.next()) {
350         stateVars->append(sv);
351         stateVarsChildren->append(sv);
352       }
353       sv = new CStateVar(0,"int", 0, con1->text->charstar(), 0,NULL, 0);
354       stateVarsChildren->append(sv);
355       {
356         char txt[128];
357         sprintf(txt, "_cf%d", nodeNum);
358         counter = new XStr(txt);
359         sv = new CStateVar(0, "CCounter", 1, txt,0,NULL, 1);
360         stateVarsChildren->append(sv);
361       }
362       break;
363     case SWHEN:
364       whensEntryMethodStateVars = new TList<CStateVar*>();
365       stateVarsChildren = new TList<CStateVar*>();
366       int numParameters; 
367       int count;
368       int isMsg;
369       int stateVarsHasVoid;
370       int stateVarsChildrenHasVoid; 
371       numParameters=0; count=0; isMsg=0; 
372       stateVarsHasVoid = 0;
373       stateVarsChildrenHasVoid = 0;
374       for(sv = stateVars->begin(); ((!stateVars->end()) && (stateVarsHasVoid != 1)); sv=stateVars->next()) {
375          if (sv->isVoid == 1)
376              stateVarsHasVoid == 1;     // what this means??? gengbin
377       }
378       for(sv=list.begin(); !list.end(); sv=list.next()) {
379          if ((sv->isVoid == 1) && (stateVarsHasVoid != 1)) {
380             stateVars->append(sv);
381             stateVarsHasVoid == 1;
382          }
383          else if (sv->isVoid != 1)
384             stateVars->append(sv);
385          if ((sv->isVoid == 1) && (stateVarsChildrenHasVoid != 1)) {
386             stateVarsChildren->append(sv);
387             stateVarsChildrenHasVoid == 1;
388          }
389          else if (sv->isVoid != 1) {
390             stateVarsChildren->append(sv);
391          }
392       }
393
394      
395       {  
396         EntryList *el;
397         el = elist;
398         ParamList *pl;
399         while (el != NULL) {
400           pl = el->entry->param;
401           el->entry->stateVars = new TList<CStateVar*>();
402           if (pl->isVoid()) {
403             sv = new CStateVar(1, NULL, 0, NULL, 0, NULL, 0);
404             //stateVars->append(sv);
405               stateVarsChildren->append(sv);
406               whensEntryMethodStateVars->append(sv); 
407               el->entry->estateVars.append(sv);
408               el->entry->stateVars->append(sv);
409           }
410           else if (pl->isMessage()){
411             sv = new CStateVar(0, pl->getBaseName(), 1, pl->getGivenName(), 0, NULL, 1);
412             //stateVars->append(sv);
413               stateVarsChildren->append(sv);
414               whensEntryMethodStateVars->append(sv); 
415               el->entry->estateVars.append(sv);
416               el->entry->stateVars->append(sv);
417           }
418           else {
419             while(pl != NULL) {
420               if (pl->isPointer()) {
421                 sv = new CStateVar(0, pl->getBaseName(), pl->getNumStars(), pl->getGivenName(), 0, NULL, 0); 
422               }
423               else if (pl->isReference()) {
424                 sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), new XStr("&"), NULL, 0); 
425               }
426               else if (pl->isArray()) {
427                 sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), 0, pl->getArrayLen(), 0); 
428               }
429               else if (pl->isBuiltin()) {
430                 sv = new CStateVar(0, pl->getBaseName(), 0, pl->getGivenName(), 0, NULL, 0); 
431               }
432               else if (pl->isNamed()) {
433                 sv = new CStateVar(0, (XStr)(*(pl->param->getType())), 0, pl->getGivenName(), 0, NULL, 0); 
434               }
435               else
436                  printf("PROBLEM - I DON'T KNOW THE TYPE\n");
437               pl = pl->next;
438               stateVarsChildren->append(sv);
439               whensEntryMethodStateVars->append(sv); 
440               el->entry->estateVars.append(sv);
441               el->entry->stateVars->append(sv);
442             }
443           }
444           el = el->next;
445
446         }
447       }
448       break;
449     case SIF:
450       for(sv=list.begin(); !list.end(); sv=list.next()) {
451         stateVars->append(sv);
452       }
453       stateVarsChildren = stateVars;
454       if(con2 != 0) con2->propagateState(list, wlist,publist, uniqueVarNum);
455       break;
456     case SOLIST:
457       stateVarsChildren = new TList<CStateVar*>();
458       for(sv=list.begin(); !list.end(); sv=list.next()) {
459         stateVars->append(sv);
460         stateVarsChildren->append(sv);
461       }
462       {
463         char txt[128];
464         sprintf(txt, "_co%d", nodeNum);
465         counter = new XStr(txt);
466         sv = new CStateVar(0,"CCounter",1, txt,0, NULL, 1);
467         stateVarsChildren->append(sv);
468       }
469       break;
470     case SFOR:
471     case SWHILE:
472     case SELSE:
473     case SSLIST:
474     case SOVERLAP:
475       for(sv=list.begin(); !list.end(); sv=list.next()) {
476         stateVars->append(sv);
477       }
478       stateVarsChildren = stateVars;
479       break;
480     case SATOMIC:
481       for(sv=list.begin(); !list.end(); sv=list.next()) {
482         stateVars->append(sv);
483       }
484       stateVarsChildren = stateVars;
485       if (con1 != 0) {
486         publist.append(con1);
487         /*SdagConstruct *sc;
488         SdagConstruct *sc1;
489         for(sc =publist.begin(); !publist.end(); sc=publist.next()) {
490            for(sc1=sc->constructs->begin(); !sc->constructs->end(); sc1 = sc->constructs->next())
491            printf("Publist = %s\n", sc1->text->charstar());
492         }*/
493       }
494       break;
495     case SFORWARD:
496       stateVarsChildren = new TList<CStateVar*>();
497       for(sv=list.begin(); !list.end(); sv=list.next()) { 
498         stateVars->append(sv);
499       }
500       for(sv=wlist.begin(); !wlist.end(); sv=wlist.next()) { 
501         stateVarsChildren->append(sv);
502       }
503
504       break;
505     case SCONNECT: 
506     case SINT_EXPR:
507     case SIDENT:
508     case SENTRY:
509     case SELIST:
510       break;
511     default:
512       fprintf(stderr, "internal error in sdag translator..\n");
513       exit(1);
514       break;
515   }
516   SdagConstruct *cn;
517   if (constructs != 0) {
518     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
519       if (type == SWHEN)
520          cn->propagateState(*stateVarsChildren, *whensEntryMethodStateVars, publist,  uniqueVarNum);
521       else
522          cn->propagateState(*stateVarsChildren, wlist, publist,  uniqueVarNum);
523     }
524  } 
525 }
526
527 void SdagConstruct::generateCode(XStr& op)
528 {
529   switch(type) {
530     case SSDAGENTRY:
531       generateSdagEntry(op);
532       break;
533     case SSLIST:
534       generateSlist(op);
535       break;
536     case SOLIST:
537       generateOlist(op);
538       break;
539     case SFORALL:
540       generateForall(op);
541       break;
542     case SATOMIC:
543       generateAtomic(op);
544       break;
545     case SIF:
546       generateIf(op);
547       if(con2 != 0)
548         con2->generateCode(op);
549       break;
550     case SELSE:
551       generateElse(op);
552       break;
553     case SWHILE:
554       generateWhile(op);
555       break;
556     case SFOR:
557       generateFor(op);
558       break;
559     case SOVERLAP:
560       generateOverlap(op);
561       break;
562     case SWHEN:
563       generateWhen(op);
564       break;
565     case SFORWARD:
566       generateForward(op);
567       break;
568     case SCONNECT:
569       generateConnect(op);
570       break;
571     default:
572       break;
573   }
574   SdagConstruct *cn;
575   if (constructs != 0) {
576     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
577       cn->generateCode(op);
578     }
579   }
580 }
581
582 void SdagConstruct::generateConnect(XStr& op) {
583   op << "  void " << label->charstar() << "() {\n";
584   op << "    int index;\n";
585   if ((param->isVoid() == 0) && (param->isMessage() == 0)) {
586      op << "    CkMarshallMsg *x;\n";  
587      op << "    index = CkIndex_Ar1::" <<connectEntry->charstar() <<"(x);\n";  //replace
588      op << "    CkCallback cb(index, CkArrayIndex1D(thisIndex), a1);\n";  // replace 
589   }
590   else if (param->isVoid() == 1) {
591      op << "    index = CkIndex_Ar1::" <<connectEntry->charstar() <<"(void);\n";  //replace
592      op << "    CkCallback cb(index, CkArrayIndex1D(thisIndex), a1);\n";  // replace 
593   }
594   else {
595      op << "    " << param->getBaseName() <<" *x;\n";  // replace
596      op << "    index = CkIndex_Ar1::" <<connectEntry->charstar() <<"(x);\n";  //replace
597      op << "    CkCallback cb(index, CkArrayIndex1D(thisIndex), a1);\n";  // replace 
598   }
599   op << "    myPublish->get_" <<connectEntry->charstar() <<"(cb);\n";  //replace - myPublish
600
601   op << "  }\n\n";  
602 }
603
604 void SdagConstruct::generateForward(XStr& op) {
605   SdagConstruct *cn;
606   op << "  void " << label->charstar() << "(";
607   generatePrototype(op, *stateVars);
608   op << ") {\n";
609   for (cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
610     op << "    { "<<cn->text->charstar()<<"(";
611     generateCall(op, *stateVarsChildren);
612     op<<"); }\n";
613   }
614   if(nextBeginOrEnd == 1)
615     op << "    " << next->label->charstar() << "(";
616   else
617     op << "    " << next->label->charstar() << "_end(";
618   generateCall(op, *stateVars);
619   op << ");\n";
620   op << "  }\n\n";
621 }
622
623
624 void SdagConstruct::generateWhen(XStr& op)
625 {
626   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
627   op << "  int " << label->charstar() << "(";
628   generatePrototype(op, *stateVars);
629   op << ") {\n";
630 #if CMK_BLUEGENE_CHARM
631   generateBeginTime(op);
632 #endif
633
634   CStateVar *sv;
635
636   Entry *e;
637   EntryList *el;
638   el = elist;
639   while (el != NULL){
640     e = el->entry;
641     if (e->param->isVoid() == 1)
642         op << "    CMsgBuffer *"<<e->getEntryName()<<"_buf;\n";
643     else if (e->paramIsMarshalled() == 1) {
644
645         op << "    CMsgBuffer *"<<e->getEntryName()<<"_buf;\n";
646         op << "    CkMarshallMsg *" <<
647                         e->getEntryName() << "_msg;\n";
648     }
649     else {
650         for(sv=e->stateVars->begin(); !e->stateVars->end(); e->stateVars->next()) {
651           op << "    CMsgBuffer *"<<sv->name->charstar()<<"_buf;\n";
652           op << "    " << sv->type->charstar() << " *" <<
653                           sv->name->charstar() << ";\n";
654         } 
655     }
656     el = el->next;
657   }
658
659   op << "\n";
660   el = elist;
661   while (el != NULL) {
662      e = el->entry;
663      if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() == 1)) {
664         if((e->intExpr == 0) || (e->param->isVoid() == 1)) {   // DOUBLE CHECK THIS LOGIC
665            op << "    " << e->getEntryName(); 
666            op << "_buf = __cDep->getMessage(" << e->entryPtr->entryNum << ");\n";
667         }           
668         else {
669            op << "    " << e->getEntryName() << 
670                  "_buf = __cDep->getMessage(" << e->entryPtr->entryNum <<
671                  ", " << e->intExpr << ");\n";
672         }
673      }
674      else { // The parameter is a message
675         sv = e->stateVars->begin();
676         if(e->intExpr == 0) {
677            op << "    " << sv->name->charstar(); 
678            op << "_buf = __cDep->getMessage(" << e->entryPtr->entryNum << ");\n";
679         }           
680         else {
681            op << "    " << sv->name->charstar() << 
682                  "_buf = __cDep->getMessage(" << e->entryPtr->entryNum <<
683                  ", " << e->intExpr << ");\n";
684         }
685      }  
686     el = el->next;
687   }
688
689   op << "\n";
690   op << "    if (";
691   el = elist;
692   while (el != NULL)  {
693      e = el->entry;
694      if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() ==1)) {
695         op << "(" << e->getEntryName() << "_buf != 0)";
696      }
697      else {
698         sv = e->stateVars->begin();
699         op << "(" << sv->name->charstar() << "_buf != 0)";
700      }
701      el = el->next;
702      if (el != NULL)
703         op << "&&";
704   }
705   op << ") {\n";
706
707 #if CMK_BLUEGENE_CHARM
708   // for tracing
709   //TODO: instead of this, add a length field to EntryList
710   int elen=0;
711   for(el=elist; el!=NULL; el=elist->next) elen++;
712  
713   op << "         void * logs1["<< elen << "]; \n";
714   op << "         void * logs2["<< elen + 1<< "]; \n";
715   int localnum = 0;
716   for(el=elist; el!=NULL; el=elist->next) {
717     e = el->entry;
718        if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() ==1)) {
719         op << "       logs1[" << localnum << "] = " << /*el->con4->text->charstar() sv->type->charstar()*/e->getEntryName() << "_buf->bgLog1; \n";
720         op << "       logs2[" << localnum << "] = " << /*el->con4->text->charstar() sv->type->charstar()*/e->getEntryName() << "_buf->bgLog2; \n";
721         localnum++;
722       }
723       else{
724         op << "       logs1[" << localnum << "] = " << /*el->con4->text->charstar()*/ sv->name->charstar()<< "_buf->bgLog1; \n";
725         op << "       logs2[" << localnum << "] = " << /*el->con4->text->charstar()*/ sv->name->charstar() << "_buf->bgLog2; \n";
726         localnum++;
727       }
728   }
729       
730   op << "       logs2[" << localnum << "] = " << "_bgParentLog; \n";
731   generateEventBracket(op,SWHEN);
732   op << "       _TRACE_BG_FORWARD_DEPS(logs1,logs2,"<< localnum << ",_bgParentLog);\n";
733 #endif
734
735   el = elist;
736   while (el != NULL) {
737      e = el->entry;
738      if (e->param->isVoid() == 1) {
739         op <<"       CkFreeSysMsg((void *) "<<e->getEntryName() <<"_buf->msg);\n";
740         op << "       __cDep->removeMessage(" << e->getEntryName() <<
741               "_buf);\n";
742         op << "      delete " << e->getEntryName() << "_buf;\n";
743      }
744      else if (e->paramIsMarshalled() == 1) {
745         op << "       " << e->getEntryName() << "_msg = (CkMarshallMsg *)"  
746                << e->getEntryName() << "_buf->msg;\n";
747         op << "       char *"<<e->getEntryName() <<"_impl_buf=((CkMarshallMsg *)"
748            <<e->getEntryName() <<"_msg)->msgBuf;\n";
749         op <<"       PUP::fromMem " <<e->getEntryName() <<"_implP(" 
750            <<e->getEntryName() <<"_impl_buf);\n";
751
752         for(sv=e->stateVars->begin(); !e->stateVars->end(); sv=e->stateVars->next()) {
753            if (sv->arrayLength != NULL)
754               op <<"      int impl_off_"<<sv->name->charstar()
755                  <<"; "<<e->getEntryName() <<"_implP|impl_off_"
756                  <<sv->name->charstar()<<";\n";
757            else
758                op <<"       "<<sv->type->charstar()<<" "<<sv->name->charstar()
759                <<"; " <<e->getEntryName() <<"_implP|"
760                <<sv->name->charstar()<<";\n";
761         }
762         op << "       " <<e->getEntryName() <<"_impl_buf+=CK_ALIGN("
763            <<e->getEntryName() <<"_implP.size(),16);\n";
764         for(sv=e->stateVars->begin(); !e->stateVars->end(); sv=e->stateVars->next()) {
765            if (sv->arrayLength != NULL)
766               op << "    "<<sv->type->charstar()<< " *" <<sv->name->charstar() <<"=(" <<sv->type->charstar()
767                  <<" *)(" <<e->getEntryName() <<"_impl_buf+" <<"impl_off_"
768                  <<sv->name->charstar()<<");\n";
769         }
770         op << "       __cDep->removeMessage(" << e->getEntryName() <<
771               "_buf);\n";
772         op << "       delete " << e->getEntryName() << "_buf;\n";
773      }
774      else {  // There was a message as the only parameter
775         sv = e->stateVars->begin();
776         op << "       " << sv->name->charstar() << " = (" << 
777               sv->type->charstar() << " *) " <<
778               sv->name->charstar() << "_buf->msg;\n";
779         op << "       __cDep->removeMessage(" << sv->name->charstar() <<
780               "_buf);\n";
781         op << "       delete " << sv->name->charstar() << "_buf;\n";
782      }
783      el = el->next;
784   }
785
786   // max(current,merge) --> current, then reset the mergepath
787 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
788   op << "       " << label->charstar()  << "_PathMergePoint.updateMax(currentlyExecutingPath); /* Critical Path Detection */ \n";
789   op << "       currentlyExecutingPath = " << label->charstar()  << "_PathMergePoint; /* Critical Path Detection */ \n";
790   op << "       " << label->charstar()  << "_PathMergePoint.reset(); /* Critical Path Detection */ \n";
791 #endif
792
793   if (constructs != 0) {
794     if (!constructs->empty() ) {
795        op << "       " << constructs->front()->label->charstar() << "(";
796        generateCall(op, *stateVarsChildren);
797        op << ");\n";
798     }
799     else {
800        op << "       " << label->charstar() << "_end(";
801        generateCall(op, *stateVarsChildren);
802        op << ");\n";
803     }
804   }
805   else {
806      op << "       " << label->charstar() << "_end(";
807      generateCall(op, *stateVarsChildren);
808      op << ");\n";
809   }
810
811   el = elist;
812   while (el != NULL){
813     e = el->entry;
814     if (e->paramIsMarshalled() == 1) {
815         op << "       delete " << e->getEntryName() << "_msg;\n";
816     }
817     el = el->next;
818   }
819   op << "       return 1;\n";
820   op << "    } else {\n";
821
822   int nRefs=0, nAny=0;
823   el = elist;
824   while (el != NULL) {
825     e = el->entry;
826     if(e->intExpr == 0)
827       nAny++;
828     else
829       nRefs++;
830     el = el->next;
831   }
832 // keep these consts consistent with sdag.h in runtime
833
834 #define MAXARG 8
835 #define MAXANY 8
836 #define MAXREF 8
837
838   if(stateVars->length() > MAXARG) {
839     fprintf(stderr, "numStateVars more that %d, contact developers.\n",
840                      MAXARG);
841     exit(1);
842   }
843   if(nRefs > MAXREF) {
844     fprintf(stderr, "numDepends more that %d, contact developers.\n",
845                      MAXREF);
846     exit(1);
847   }
848   if(nAny > MAXANY) {
849     fprintf(stderr, "numDepends more that %d, contact developers.\n",
850                      MAXANY);
851     exit(1);
852   }
853   op << "       CWhenTrigger *tr;\n";
854   op << "       tr = new CWhenTrigger(" << nodeNum << ", " <<
855         stateVars->length() << ", " << nRefs << ", " << nAny << ");\n";
856   int iArgs=0;
857  
858 //  op << "       int impl_off=0;\n";
859   int hasArray = 0;
860   int isVoid = 0;
861   int numParamsNeedingMarshalling = 0;
862   int paramIndex =0;
863   for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
864     if (sv->isVoid == 1) {
865         isVoid = 1;
866        op <<"       tr->args[" <<iArgs++ <<"] = (size_t) CkAllocSysMsg();\n";
867     }
868     else {
869       if (sv->isMsg == 1) {
870          op << "       tr->args["<<iArgs++ <<"] = (size_t) " <<sv->name->charstar()<<";\n";
871       }
872       else {
873          numParamsNeedingMarshalling++;
874          if (numParamsNeedingMarshalling == 1) {
875            op << "       int impl_off=0;\n";
876            paramIndex = iArgs;
877            iArgs++;
878          }
879       }
880       if (sv->arrayLength !=NULL) {
881          hasArray++;
882          if (hasArray == 1)
883            op<< "       int impl_arrstart=0;\n";
884          op <<"       int impl_off_"<<sv->name->charstar()<<", impl_cnt_"<<sv->name->charstar()<<";\n";
885          op <<"       impl_off_"<<sv->name->charstar()<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<sv->type->charstar()<<"));\n";
886          op <<"       impl_off+=(impl_cnt_"<<sv->name->charstar()<<"=sizeof("<<sv->type->charstar()<<")*("<<sv->arrayLength->charstar()<<"));\n";
887       }
888     }
889   }
890   if (numParamsNeedingMarshalling > 0) {
891      op << "       { \n";
892      op << "         PUP::sizer implP;\n";
893      for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
894        if (sv->arrayLength !=NULL)
895          op << "         implP|impl_off_" <<sv->name->charstar() <<";\n";
896        else if ((sv->isMsg != 1) && (sv->isVoid !=1)) 
897          op << "         implP|" <<sv->name->charstar() <<";\n";
898      }
899      if (hasArray > 0) {
900         op <<"         impl_arrstart=CK_ALIGN(implP.size(),16);\n";
901         op <<"         impl_off+=impl_arrstart;\n";
902      }
903      else {
904         op << "         impl_off+=implP.size();\n";
905      }
906      op << "       }\n";
907      op << "       CkMarshallMsg *impl_msg;\n";
908      op << "       impl_msg = CkAllocateMarshallMsg(impl_off,NULL);\n";
909      op << "       {\n";
910      op << "         PUP::toMem implP((void *)impl_msg->msgBuf);\n";
911      for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
912        if (sv->arrayLength !=NULL)
913           op << "         implP|impl_off_" <<sv->name->charstar() <<";\n";
914        else if ((sv->isMsg != 1) && (sv->isVoid != 1))  
915           op << "         implP|" <<sv->name->charstar() <<";\n";
916      }
917      op << "       }\n";
918      if (hasArray > 0) {
919         op <<"       char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
920         for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
921            if (sv->arrayLength !=NULL)
922               op << "       memcpy(impl_buf+impl_off_"<<sv->name->charstar()<<
923                          ","<<sv->name->charstar()<<",impl_cnt_"<<sv->name->charstar()<<");\n";
924         }  
925      }
926   op << "       tr->args[" <<paramIndex <<"] = (size_t) impl_msg;\n";
927   }
928   int iRef=0, iAny=0;
929
930   el = elist;
931   while (el != NULL) {
932     e = el->entry;
933     if(e->intExpr == 0) {
934       op << "       tr->anyEntries[" << iAny++ << "] = " <<
935             e->entryPtr->entryNum << ";\n";
936     } else {
937       op << "       tr->entries[" << iRef << "] = " << 
938             e->entryPtr->entryNum << ";\n";
939       op << "       tr->refnums[" << iRef++ << "] = " <<
940             e->intExpr << ";\n";
941     }
942     el = el->next;
943   }
944
945 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
946   // max(current,merge) --> current
947   op << "       " << label->charstar()  << "_PathMergePoint.updateMax(currentlyExecutingPath); /* Critical Path Detection */ \n";
948   op << "       currentlyExecutingPath = " << label->charstar()  << "_PathMergePoint; /* Critical Path Detection */ \n";
949 #endif
950
951   op << "       __cDep->Register(tr);\n";
952   op << "       return 0;\n";
953   op << "    }\n";
954
955   // end actual code
956   op << "  }\n\n";
957
958   // trace
959   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
960   strcat(nameStr,"_end");
961
962   // end function
963   op << "  void " << label->charstar() << "_end(";
964   generatePrototype(op, *stateVarsChildren);
965   op << ") {\n";
966 #if CMK_BLUEGENE_CHARM
967   generateBeginTime(op);
968   generateEventBracket(op,SWHEN_END);
969 #endif
970   // actual code here 
971   if(nextBeginOrEnd == 1)
972    op << "    " << next->label->charstar();
973   else 
974     op << "    " << next->label->charstar() << "_end";
975
976   op << "(";
977
978   generateCall(op, *stateVars); 
979   
980   op << ");\n";
981
982   el = elist;
983   while (el) {
984     e = el->entry;
985     if (e->param->isMessage() == 1) {
986       sv = e->stateVars->begin();
987       op << "    CmiFree(UsrToEnv(" << sv->name->charstar() << "));\n";
988     }
989
990     el = el->next;
991   }
992
993   // end actual code
994   op << "  }\n\n";
995 }
996
997 void SdagConstruct::generateWhile(XStr& op)
998 {
999   // inlined start function
1000   op << "  void " << label->charstar() << "(";
1001   generatePrototype(op, *stateVars);
1002   op << ") {\n";
1003   // actual code here 
1004   op << "    if (" << con1->text->charstar() << ") {\n";
1005   op << "      " << constructs->front()->label->charstar() << 
1006         "(";
1007   generateCall(op, *stateVarsChildren);
1008   op << ");\n";
1009   op << "    } else {\n";
1010   if(nextBeginOrEnd == 1)
1011    op << "      " << next->label->charstar() << "(";
1012   else
1013    op << "      " << next->label->charstar() << "_end(";
1014   generateCall(op, *stateVars);
1015   op << ");\n";
1016   op << "    }\n";
1017   // end actual code
1018   op << "  }\n\n";
1019   // inlined end function
1020   op << "  void " << label->charstar() << "_end(";
1021   generatePrototype(op, *stateVarsChildren);
1022   op << ") {\n";
1023   // actual code here 
1024   op << "    if (" << con1->text->charstar() << ") {\n";
1025   op << "      " << constructs->front()->label->charstar() <<
1026         "(";
1027   generateCall(op, *stateVarsChildren);
1028   op << ");\n";
1029   op << "    } else {\n";
1030   if(nextBeginOrEnd == 1)
1031    op << "      " <<  next->label->charstar() << "(";
1032   else
1033    op << "      " << next->label->charstar() << "_end(";
1034   generateCall(op, *stateVars);
1035   op << ");\n";
1036   op << "    }\n";
1037   // end actual code
1038   op << "  }\n\n";
1039 }
1040
1041 void SdagConstruct::generateFor(XStr& op)
1042 {
1043   // inlined start function
1044   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1045   op << "  void " << label->charstar() << "(";
1046   generatePrototype(op, *stateVars);
1047   op << ") {\n";
1048 #if CMK_BLUEGENE_CHARM
1049   // actual code here 
1050   generateBeginTime(op);
1051 #endif
1052   op << "    " << con1->text->charstar() << ";\n";
1053   //Record only the beginning for FOR
1054 #if CMK_BLUEGENE_CHARM
1055   generateEventBracket(op,SFOR);
1056 #endif
1057   op << "    if (" << con2->text->charstar() << ") {\n";
1058   op << "      " << constructs->front()->label->charstar() <<
1059         "(";
1060   generateCall(op, *stateVarsChildren);
1061   op << ");\n";
1062   op << "    } else {\n";
1063   if(nextBeginOrEnd == 1)
1064    op << "      " << next->label->charstar() << "(";
1065   else
1066    op << "      " << next->label->charstar() << "_end(";
1067   generateCall(op, *stateVars);
1068   op << ");\n";
1069   op << "    }\n";
1070   // end actual code
1071   op << "  }\n";
1072   // inlined end function
1073   // trace
1074   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1075   strcat(nameStr,"_end");
1076   op << "  void " << label->charstar() << "_end(";
1077   generatePrototype(op, *stateVarsChildren);
1078   op << ") {\n";
1079 #if CMK_BLUEGENE_CHARM
1080   generateBeginTime(op);
1081 #endif
1082   // actual code here 
1083   op << con3->text->charstar() << ";\n";
1084   op << "    if (" << con2->text->charstar() << ") {\n";
1085   op << "      " << constructs->front()->label->charstar() <<
1086         "(";
1087   generateCall(op, *stateVarsChildren);
1088   op << ");\n";
1089   op << "    } else {\n";
1090 #if CMK_BLUEGENE_CHARM
1091   generateEventBracket(op,SFOR_END);
1092 #endif
1093   if(nextBeginOrEnd == 1)
1094    op << "      " << next->label->charstar() << "(";
1095   else
1096    op << "      " << next->label->charstar() << "_end(";
1097    generateCall(op, *stateVars);
1098   op << ");\n";
1099   op << "    }\n";
1100   // end actual code
1101   op << "  }\n";
1102 }
1103
1104 void SdagConstruct::generateIf(XStr& op)
1105 {
1106   // inlined start function
1107   strcpy(nameStr,label->charstar());
1108   op << "  void " << label->charstar() << "(";
1109   generatePrototype(op, *stateVars);
1110   op << ") {\n";
1111 #if CMK_BLUEGENE_CHARM
1112   generateBeginTime(op);
1113   generateEventBracket(op,SIF);
1114 #endif
1115   // actual code here 
1116   op << "    if (" << con1->text->charstar() << ") {\n";
1117   op << "      " << constructs->front()->label->charstar() <<
1118         "(";
1119   generateCall(op, *stateVarsChildren);
1120   op << ");\n";
1121   op << "    } else {\n";
1122   if (con2 != 0) {
1123     op << "      " << con2->label->charstar() << "(";
1124     generateCall(op, *stateVarsChildren);
1125     op << ");\n";
1126   } else {
1127     op << "      " << label->charstar() << "_end(";
1128     generateCall(op, *stateVarsChildren);
1129     op << ");\n";
1130   }
1131   op << "    }\n";
1132   // end actual code
1133   op << "  }\n\n";
1134   // inlined end function
1135   strcpy(nameStr,label->charstar());
1136   strcat(nameStr,"_end");
1137   op << "  void " << label->charstar() << "_end(";
1138   generatePrototype(op, *stateVarsChildren);
1139   op << ") {\n";
1140 #if CMK_BLUEGENE_CHARM
1141   generateBeginTime(op);
1142   generateEventBracket(op,SIF_END);
1143 #endif
1144   // actual code here 
1145   if(nextBeginOrEnd == 1)
1146    op << "      " << next->label->charstar() << "(";
1147   else
1148    op << "      " << next->label->charstar() << "_end(";
1149   generateCall(op, *stateVars);
1150   op << ");\n";
1151   // end actual code
1152   op << "  }\n\n";
1153 }
1154
1155 void SdagConstruct::generateElse(XStr& op)
1156 {
1157   // inlined start function
1158   strcpy(nameStr,label->charstar());
1159   op << "  void " << label->charstar() << "(";
1160   generatePrototype(op, *stateVars);
1161   op << ") {\n";
1162   // trace
1163   generateBeginTime(op);
1164   generateEventBracket(op,SELSE);
1165   // actual code here 
1166   op << "    " << constructs->front()->label->charstar() << 
1167         "(";
1168   generateCall(op, *stateVarsChildren);
1169   op << ");\n";
1170   // end actual code
1171   op << "  }\n\n";
1172   // inlined end function
1173   // trace
1174   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1175   strcat(nameStr,"_end");
1176   op << "  void " << label->charstar() << "_end(";
1177   generatePrototype(op, *stateVarsChildren);
1178   op << ") {\n";
1179 #if CMK_BLUEGENE_CHARM
1180   generateBeginTime(op);
1181   generateEventBracket(op,SELSE_END);
1182 #endif
1183   // actual code here 
1184   if(nextBeginOrEnd == 1)
1185    op << "      " << next->label->charstar() << "(";
1186   else
1187    op << "      " << next->label->charstar() << "_end(";
1188   generateCall(op, *stateVars);
1189   op << ");\n";
1190   // end actual code
1191   op << "  }\n\n";
1192 }
1193
1194 void SdagConstruct::generateForall(XStr& op)
1195 {
1196   // inlined start function
1197   op << "  void " << label->charstar() << "(";
1198   generatePrototype(op, *stateVars);
1199   op << ") {\n";
1200   // actual code here 
1201   op << "    int __first = (" << con2->text->charstar() <<
1202         "), __last = (" << con3->text->charstar() << 
1203         "), __stride = (" << con4->text->charstar() << ");\n";
1204   op << "    if (__first > __last) {\n";
1205   op << "      int __tmp=__first; __first=__last; __last=__tmp;\n";
1206   op << "      __stride = -__stride;\n";
1207   op << "    }\n";
1208   op << "    CCounter *" << counter->charstar() << 
1209         " = new CCounter(__first,__last,__stride);\n"; 
1210   op << "    for(int " << con1->text->charstar() << 
1211         "=__first;" << con1->text->charstar() <<
1212         "<=__last;" << con1->text->charstar() << "+=__stride) {\n";
1213   op << "      " << constructs->front()->label->charstar() <<
1214         "(";
1215   generateCall(op, *stateVarsChildren);
1216   op << ");\n";
1217   op << "    }\n";
1218   // end actual code
1219   op << "  }\n\n";
1220   // inlined end function
1221   op << "  void " << label->charstar() << "_end(";
1222   generatePrototype(op, *stateVarsChildren);
1223   op << ") {\n";
1224   // actual code here 
1225   op << "    " << counter->charstar() << "->decrement(); /* DECREMENT 1 */ \n";
1226   op << "    if (" << counter->charstar() << "->isDone()) {\n";
1227   op << "      delete " << counter->charstar() << ";\n";
1228   if(nextBeginOrEnd == 1)
1229    op << "      " << next->label->charstar() << "(";
1230   else
1231    op << "      " << next->label->charstar() << "_end(";
1232   generateCall(op, *stateVars);
1233   op << ");\n";
1234   // end actual code
1235   op << "    }\n  }\n\n";
1236 }
1237
1238 void SdagConstruct::generateOlist(XStr& op)
1239 {
1240   SdagConstruct *cn;
1241   // inlined start function
1242   op << "  void " << label->charstar() << "(";
1243   generatePrototype(op, *stateVars);
1244   op << ") {\n";
1245   // actual code here 
1246   op << "    CCounter *" << counter->charstar() << "= new CCounter(" <<
1247         constructs->length() << ");\n";
1248   for(cn=constructs->begin(); 
1249                      !constructs->end(); cn=constructs->next()) {
1250     op << "    " << cn->label->charstar() << "(";
1251     generateCall(op, *stateVarsChildren);
1252     op << ");\n";
1253   }
1254   // end actual code
1255   op << "  }\n";
1256
1257   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1258   strcat(nameStr,"_end");
1259 #if CMK_BLUEGENE_CHARM
1260   op << "  CkVec<void*> " <<label->charstar() << "_bgLogList;\n";
1261 #endif
1262
1263   // inlined end function
1264   op << "  void " << label->charstar() << "_end(";
1265   generatePrototype(op, *stateVarsChildren);
1266   op << ") {\n";
1267 #if CMK_BLUEGENE_CHARM
1268   generateBeginTime(op);
1269   op << "    " <<label->charstar() << "_bgLogList.insertAtEnd(_bgParentLog);\n";
1270 #endif
1271   // actual code here 
1272   //Accumulate all the bgParent pointers that the calling when_end functions give
1273   op << "    " << counter->charstar() << "->decrement();\n";
1274  
1275 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1276  op << "    olist_" << counter->charstar() << "_PathMergePoint.updateMax(currentlyExecutingPath);  /* Critical Path Detection FIXME: is the currently executing path the right thing for this? The duration ought to have been added somewhere. */ \n";
1277 #endif
1278
1279   op << "    if (" << counter->charstar() << "->isDone()) {\n";
1280
1281 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1282   op << "      currentlyExecutingPath = olist_" << counter->charstar() << "_PathMergePoint; /* Critical Path Detection */ \n";
1283   op << "      olist_" << counter->charstar() << "_PathMergePoint.reset(); /* Critical Path Detection */ \n";
1284 #endif
1285
1286   op << "      delete " << counter->charstar() << ";\n";
1287
1288 #if CMK_BLUEGENE_CHARM
1289   generateListEventBracket(op,SOLIST_END);
1290   op << "       "<< label->charstar() <<"_bgLogList.length()=0;\n";
1291 #endif
1292
1293   if(nextBeginOrEnd == 1)
1294    op << "      " << next->label->charstar() << "(";
1295   else
1296    op << "      " << next->label->charstar() << "_end(";
1297   generateCall(op, *stateVars);
1298   op << ");\n";
1299   // end actual code
1300   op << "    }\n";
1301   op << "  }\n";
1302 }
1303
1304 void SdagConstruct::generateOverlap(XStr& op)
1305 {
1306   // inlined start function
1307   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1308   op << "  void " << label->charstar() << "(";
1309   generatePrototype(op, *stateVars);
1310   op << ") {\n";
1311 #if CMK_BLUEGENE_CHARM
1312   generateBeginTime(op);
1313   generateEventBracket(op,SOVERLAP);
1314 #endif
1315   // actual code here 
1316   op << "    " << constructs->front()->label->charstar() <<
1317         "(";
1318   generateCall(op, *stateVarsChildren);
1319   op << ");\n";
1320   // end actual code
1321   op << "  }\n";
1322   // trace
1323   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1324   strcat(nameStr,"_end");
1325   // inlined end function
1326   op << "  void " << label->charstar() << "_end(";
1327   generatePrototype(op, *stateVarsChildren);
1328   op << ") {\n";
1329 #if CMK_BLUEGENE_CHARM
1330   generateBeginTime(op);
1331   generateEventBracket(op,SOVERLAP_END);
1332 #endif
1333   // actual code here 
1334   if(nextBeginOrEnd == 1)
1335    op << "    " << next->label->charstar() << "(";
1336   else
1337    op << "    " << next->label->charstar() << "_end(";
1338   generateCall(op, *stateVars);
1339   op << ");\n";
1340   // end actual code
1341   op << "  }\n";
1342 }
1343
1344 void SdagConstruct::generateSlist(XStr& op)
1345 {
1346   // inlined start function
1347   op << "  void " << label->charstar() << "(";
1348   generatePrototype(op, *stateVars);
1349   op << ") {\n";
1350   // actual code here 
1351   op << "    " << constructs->front()->label->charstar() <<
1352         "(";
1353   generateCall(op, *stateVarsChildren);
1354   op << ");\n";
1355   // end actual code
1356   op << "  }\n";
1357   // inlined end function
1358   op << "  void " << label->charstar() << "_end(";
1359   generatePrototype(op, *stateVarsChildren); 
1360   op << ") {\n";
1361   // actual code here 
1362   if(nextBeginOrEnd == 1)
1363    op << "    " << next->label->charstar() << "(";
1364   else
1365    op << "    " << next->label->charstar() << "_end(";
1366   generateCall(op, *stateVars);
1367   op << ");\n";
1368   // end actual code
1369   op << "  }\n";
1370 }
1371
1372 void SdagConstruct::generateSdagEntry(XStr& op)
1373 {
1374   // header file
1375   op << "public:\n";
1376   op << "  void " << con1->text->charstar() << "(";
1377   generatePrototype(op, *stateVars);
1378   op << ") {\n";
1379   SdagConstruct *sc;
1380   SdagConstruct *sc1;
1381   for(sc =publishesList->begin(); !publishesList->end(); sc=publishesList->next()) {
1382      for(sc1=sc->constructs->begin(); !sc->constructs->end(); sc1 = sc->constructs->next())
1383         op << "    _connect_" << sc1->text->charstar() <<"();\n";
1384   }
1385 #if CMK_BLUEGENE_CHARM
1386   generateEndSeq(op);
1387 #endif
1388   // actual code here 
1389   op << "    " << constructs->front()->label->charstar() <<
1390         "(";
1391   generateCall(op, *stateVarsChildren);
1392   op << ");\n";
1393 #if CMK_BLUEGENE_CHARM
1394   generateTlineEndCall(op);
1395   generateBeginExec(op, "spaceholder");
1396 #endif
1397   generateDummyBeginExecute(op);
1398   // end actual code
1399   op << "  }\n\n";
1400   op << "private:\n";
1401   op << "  void " << con1->text->charstar() << "_end(";
1402 #if CMK_BLUEGENE_CHARM
1403   generatePrototype(op, *stateVarsChildren);
1404 #else
1405   generatePrototype(op, *stateVars);
1406 #endif
1407   op << ") {\n";
1408   op << "  }\n\n";
1409 }
1410
1411 void SdagConstruct::generateAtomic(XStr& op)
1412
1413   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1414   op << "  void " << label->charstar() << "(";
1415   generatePrototype(op, *stateVars);
1416   op << ") {\n";
1417 #if CMK_BLUEGENE_CHARM
1418   generateBeginExec(op, nameStr);
1419 #endif
1420   generateTraceBeginCall(op);
1421   op << "    " << text->charstar() << "\n";
1422   // trace
1423   generateTraceEndCall(op);
1424 #if CMK_BLUEGENE_CHARM
1425   generateEndExec(op);
1426 #endif
1427   SdagConstruct *cn;
1428   if(nextBeginOrEnd == 1)
1429     op << "    " << next->label->charstar() << "(";
1430   else
1431     op << "    " << next->label->charstar() << "_end(";
1432   generateCall(op, *stateVars);
1433   op << ");\n";
1434   op << "  }\n\n";
1435 }
1436
1437 void SdagConstruct::generatePrototype(XStr& op, ParamList *list)
1438 {
1439    ParamList *pl = list;
1440    int count = 0;
1441    int i, numStars;
1442    if (pl->isVoid() == 1) {
1443      op << "void"; 
1444    }
1445    else if (pl->isMessage() == 1){
1446      op << pl->getBaseName() <<" *" <<pl->getGivenName() ;
1447    }
1448    else {
1449      while(pl != NULL) {
1450        if (count > 0)
1451           op <<", ";
1452        if (pl->isPointer() == 1) {
1453          op <<pl->getBaseName(); 
1454          numStars = pl->getNumStars();
1455          for(i=0; i< numStars; i++)
1456            op <<"*";
1457          op <<" "<<pl->getGivenName();
1458        }
1459        else if (pl->isReference() == 1) 
1460          op <<pl->getBaseName() <<"& " <<pl->getGivenName();
1461        else if (pl->isArray() == 1) 
1462          op <<pl->getBaseName() <<"* " <<pl->getGivenName();
1463        else if ((pl->isBuiltin() == 1) || (pl->isNamed() == 1))
1464          op <<pl->getBaseName() <<" " <<pl->getGivenName();
1465        pl = pl->next;
1466        count++;
1467      }
1468    }
1469 }
1470
1471
1472 void SdagConstruct::generatePrototype(XStr& op, TList<CStateVar*>& list)
1473 {
1474   CStateVar *sv;
1475   int isVoid;
1476   int count;
1477   count = 0;
1478   for(sv=list.begin(); !list.end(); ) {
1479     isVoid = sv->isVoid;
1480     if ((count != 0) && (isVoid != 1))
1481        op << ", ";
1482     if (sv->isVoid != 1) {
1483       if (sv->type != 0) 
1484          op <<sv->type->charstar() <<" ";
1485       if (sv->byRef != 0)
1486          op <<" &";
1487       if (sv->arrayLength != NULL) 
1488          op <<"*";
1489       else if (sv->numPtrs != 0) {
1490         for (int i=0; i<sv->numPtrs; i++) 
1491           op <<"*";
1492          op <<" ";
1493       }
1494       if (sv->name != 0)
1495          op <<sv->name->charstar();
1496     }
1497     if (sv->isVoid != 1)
1498        count++;
1499     sv = list.next();
1500   }
1501 }
1502
1503 void SdagConstruct::generateCall(XStr& op, TList<CStateVar*>& list) {
1504   CStateVar *sv;
1505   int isVoid;
1506   int count;
1507   count = 0;
1508   for(sv=list.begin(); !list.end(); ) {
1509      isVoid = sv->isVoid;
1510      if ((count != 0) && (isVoid != 1))
1511         op << ", ";
1512      if (sv->name != 0) 
1513        op << sv->name->charstar();
1514     if (sv->isVoid != 1)
1515        count++;
1516     sv = list.next();
1517   }
1518 }
1519
1520 // boe = 1, if the next call is to begin construct
1521 // boe = 0, if the next call is to end a contruct
1522 void SdagConstruct::setNext(SdagConstruct *n, int boe)
1523 {
1524   switch(type) {
1525     case SSLIST:
1526       next = n;
1527       nextBeginOrEnd = boe;
1528       {
1529         SdagConstruct *notConnectNode = this;
1530         SdagConstruct *cn=constructs->begin();
1531         if (cn==0) // empty slist
1532           return;
1533         else if (cn->type != SCONNECT)
1534           notConnectNode = cn;
1535         int flag = 1;
1536         SdagConstruct *nextNode=constructs->next();
1537         for(; nextNode != 0;) {
1538           if (nextNode->type != SCONNECT)
1539             notConnectNode = nextNode;
1540           flag = 1;
1541           while ((flag == 1) && (nextNode->type == SCONNECT)) {
1542             nextNode = constructs->next();
1543             if (nextNode == 0)
1544               flag = 0;
1545           }
1546           if (nextNode != 0) {
1547             cn->setNext(nextNode, 1);
1548             cn = nextNode;
1549             nextNode = constructs->next();
1550           }
1551         }
1552         cn->setNext(this, 0);
1553       }
1554       return;
1555     case SSDAGENTRY:
1556     case SOVERLAP:
1557     case SOLIST:
1558     case SFORALL:
1559     case SWHEN:
1560     case SFOR:
1561     case SWHILE:
1562     case SATOMIC:
1563     case SFORWARD:
1564     case SELSE:
1565       next = n;
1566       nextBeginOrEnd = boe;
1567       n = this; boe = 0; break;
1568     case SIF:
1569       next = n;
1570       nextBeginOrEnd = boe;
1571       if(con2 != 0)
1572         con2->setNext(n, boe);
1573       n = this;
1574       boe = 0;
1575       break;
1576     default:
1577       break;
1578   }
1579   SdagConstruct *cn;
1580   if (constructs != 0) {
1581     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1582       cn->setNext(n, boe);
1583     }
1584   }
1585 }
1586
1587
1588 // for trace
1589
1590 void SdagConstruct::generateTrace()
1591 {
1592   char text[1024];
1593   switch(type) {
1594   case SATOMIC:
1595     if (traceName) {
1596       sprintf(text, "%s_%s", CParsedFile::className->charstar(), traceName->charstar());
1597       // remove blanks
1598       for (int i=0; i<strlen(text); i++)
1599         if (text[i]==' '||text[i]=='\t') text[i]='_';
1600     }
1601     else {
1602       sprintf(text, "%s%s", CParsedFile::className->charstar(), label->charstar());
1603     }
1604     traceName = new XStr(text);
1605     break;
1606   default:
1607     break;
1608   }
1609
1610   SdagConstruct *cn;
1611   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1612     cn->generateTrace();
1613   }
1614   if (con1) con1->generateTrace();
1615   if (con2) con2->generateTrace();
1616   if (con3) con3->generateTrace();
1617 }
1618
1619 void SdagConstruct::generateTraceBeginCall(XStr& op)          // for trace
1620 {
1621   if(traceName)
1622     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, " << "__idx_" << traceName->charstar() << ", CkMyPe(), 0, NULL); \n";
1623 }
1624
1625 void SdagConstruct::generateDummyBeginExecute(XStr& op)
1626 {
1627     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, _dummyEP, CkMyPe(), 0, NULL); \n";
1628 }
1629
1630 void SdagConstruct::generateTraceEndCall(XStr& op)          // for trace
1631 {
1632   op << "    " << "_TRACE_END_EXECUTE(); \n";
1633 }
1634
1635 void SdagConstruct::generateBeginExec(XStr& op, const char *name){
1636   op << "     " << "_TRACE_BG_BEGIN_EXECUTE_NOMSG(\""<<name<<"\",&_bgParentLog,1);\n"; 
1637 }
1638
1639 void SdagConstruct::generateEndExec(XStr& op){
1640   op << "     " << "_TRACE_BG_END_EXECUTE(0);\n";
1641 }
1642
1643 void SdagConstruct::generateBeginTime(XStr& op)
1644 {
1645   //Record begin time for tracing
1646   op << "    double __begintime = CkVTimer(); \n";
1647 }
1648
1649 void SdagConstruct::generateTlineEndCall(XStr& op)
1650 {
1651   //Trace this event
1652   op <<"    _TRACE_BG_TLINE_END(&_bgParentLog);\n";
1653 }
1654
1655 void SdagConstruct::generateEndSeq(XStr& op)
1656 {
1657   op <<  "    void* _bgParentLog = NULL;\n";
1658   op <<  "    CkElapse(0.01e-6);\n";
1659   //op<<  "    BgElapse(1e-6);\n";
1660   generateTlineEndCall(op);
1661   generateTraceEndCall(op);
1662   generateEndExec(op);
1663 }
1664
1665 void SdagConstruct::generateEventBracket(XStr& op, int eventType)
1666 {
1667   //Trace this event
1668   op << "     _TRACE_BG_USER_EVENT_BRACKET(\"" << nameStr
1669      << "\", __begintime, CkVTimer(),&_bgParentLog); \n";
1670 }
1671
1672 void SdagConstruct::generateListEventBracket(XStr& op, int eventType)
1673 {
1674   op << "    _TRACE_BGLIST_USER_EVENT_BRACKET(\"" << nameStr
1675      << "\",__begintime,CkVTimer(),&_bgParentLog, " << label->charstar()
1676      << "_bgLogList);\n";
1677 }
1678
1679 void SdagConstruct::generateRegisterEp(XStr& op)          // for trace
1680 {
1681   if (traceName) {
1682     op << "    __idx_" << traceName->charstar()
1683        << " = CkRegisterEp(\"" << traceName->charstar()
1684        << "(void)\", NULL, 0, CkIndex_" << CParsedFile::className->charstar()
1685        << "::__idx, 0);\n";
1686   }
1687
1688   SdagConstruct *cn;
1689   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1690     cn->generateRegisterEp(op);
1691   }
1692   if (con1) con1->generateRegisterEp(op);
1693   if (con2) con2->generateRegisterEp(op);
1694   if (con3) con3->generateRegisterEp(op);
1695 }
1696
1697 void SdagConstruct::generateTraceEpDecl(XStr& op)          // for trace
1698 {
1699   if (traceName) {
1700     op << "  static int __idx_" << traceName->charstar() << ";\n"; 
1701   }
1702   SdagConstruct *cn;
1703   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1704     cn->generateTraceEpDecl(op);
1705   }
1706   if (con1) con1->generateTraceEpDecl(op);
1707   if (con2) con2->generateTraceEpDecl(op);
1708   if (con3) con3->generateTraceEpDecl(op);
1709 }
1710
1711
1712 void SdagConstruct::generateTraceEpDef(XStr& op)          // for trace
1713 {
1714   if (traceName) {
1715     op << "  int " << CParsedFile::className->charstar()
1716        << "::__idx_" << traceName->charstar() << "=0;\\\n";
1717   }
1718   SdagConstruct *cn;
1719   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1720     cn->generateTraceEpDef(op);
1721   }
1722   if (con1) con1->generateTraceEpDef(op);
1723   if (con2) con2->generateTraceEpDef(op);
1724   if (con3) con3->generateTraceEpDef(op);
1725 }
1726
1727
1728 void RemoveSdagComments(char *str)
1729 {
1730   char *ptr = str;
1731   while (ptr = strstr(ptr, "//")) {
1732     char *lend = strstr(ptr, "\n");
1733     if (lend==NULL) break;
1734     while (ptr != lend) *ptr++=' ';
1735   }
1736 }
1737
1738 }