35f7124034c602b5c0a0294d499f2eb439f01211
[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     } else if (e->param->isMessage() == 1) {
817         op << "       CmiFree(UsrToEnv(" << e->param->param->getGivenName() << "));\n";
818     }
819     el = el->next;
820   }
821   op << "       return 1;\n";
822   op << "    } else {\n";
823
824   int nRefs=0, nAny=0;
825   el = elist;
826   while (el != NULL) {
827     e = el->entry;
828     if(e->intExpr == 0)
829       nAny++;
830     else
831       nRefs++;
832     el = el->next;
833   }
834 // keep these consts consistent with sdag.h in runtime
835
836 #define MAXARG 8
837 #define MAXANY 8
838 #define MAXREF 8
839
840   if(stateVars->length() > MAXARG) {
841     fprintf(stderr, "numStateVars more that %d, contact developers.\n",
842                      MAXARG);
843     exit(1);
844   }
845   if(nRefs > MAXREF) {
846     fprintf(stderr, "numDepends more that %d, contact developers.\n",
847                      MAXREF);
848     exit(1);
849   }
850   if(nAny > MAXANY) {
851     fprintf(stderr, "numDepends more that %d, contact developers.\n",
852                      MAXANY);
853     exit(1);
854   }
855   op << "       CWhenTrigger *tr;\n";
856   op << "       tr = new CWhenTrigger(" << nodeNum << ", " <<
857         stateVars->length() << ", " << nRefs << ", " << nAny << ");\n";
858   int iArgs=0;
859  
860 //  op << "       int impl_off=0;\n";
861   int hasArray = 0;
862   int isVoid = 0;
863   int numParamsNeedingMarshalling = 0;
864   int paramIndex =0;
865   for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
866     if (sv->isVoid == 1) {
867         isVoid = 1;
868        op <<"       tr->args[" <<iArgs++ <<"] = (size_t) CkAllocSysMsg();\n";
869     }
870     else {
871       if (sv->isMsg == 1) {
872          op << "       tr->args["<<iArgs++ <<"] = (size_t) " <<sv->name->charstar()<<";\n";
873       }
874       else {
875          numParamsNeedingMarshalling++;
876          if (numParamsNeedingMarshalling == 1) {
877            op << "       int impl_off=0;\n";
878            paramIndex = iArgs;
879            iArgs++;
880          }
881       }
882       if (sv->arrayLength !=NULL) {
883          hasArray++;
884          if (hasArray == 1)
885            op<< "       int impl_arrstart=0;\n";
886          op <<"       int impl_off_"<<sv->name->charstar()<<", impl_cnt_"<<sv->name->charstar()<<";\n";
887          op <<"       impl_off_"<<sv->name->charstar()<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<sv->type->charstar()<<"));\n";
888          op <<"       impl_off+=(impl_cnt_"<<sv->name->charstar()<<"=sizeof("<<sv->type->charstar()<<")*("<<sv->arrayLength->charstar()<<"));\n";
889       }
890     }
891   }
892   if (numParamsNeedingMarshalling > 0) {
893      op << "       { \n";
894      op << "         PUP::sizer implP;\n";
895      for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
896        if (sv->arrayLength !=NULL)
897          op << "         implP|impl_off_" <<sv->name->charstar() <<";\n";
898        else if ((sv->isMsg != 1) && (sv->isVoid !=1)) 
899          op << "         implP|" <<sv->name->charstar() <<";\n";
900      }
901      if (hasArray > 0) {
902         op <<"         impl_arrstart=CK_ALIGN(implP.size(),16);\n";
903         op <<"         impl_off+=impl_arrstart;\n";
904      }
905      else {
906         op << "         impl_off+=implP.size();\n";
907      }
908      op << "       }\n";
909      op << "       CkMarshallMsg *impl_msg;\n";
910      op << "       impl_msg = CkAllocateMarshallMsg(impl_off,NULL);\n";
911      op << "       {\n";
912      op << "         PUP::toMem implP((void *)impl_msg->msgBuf);\n";
913      for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
914        if (sv->arrayLength !=NULL)
915           op << "         implP|impl_off_" <<sv->name->charstar() <<";\n";
916        else if ((sv->isMsg != 1) && (sv->isVoid != 1))  
917           op << "         implP|" <<sv->name->charstar() <<";\n";
918      }
919      op << "       }\n";
920      if (hasArray > 0) {
921         op <<"       char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
922         for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
923            if (sv->arrayLength !=NULL)
924               op << "       memcpy(impl_buf+impl_off_"<<sv->name->charstar()<<
925                          ","<<sv->name->charstar()<<",impl_cnt_"<<sv->name->charstar()<<");\n";
926         }  
927      }
928   op << "       tr->args[" <<paramIndex <<"] = (size_t) impl_msg;\n";
929   }
930   int iRef=0, iAny=0;
931
932   el = elist;
933   while (el != NULL) {
934     e = el->entry;
935     if(e->intExpr == 0) {
936       op << "       tr->anyEntries[" << iAny++ << "] = " <<
937             e->entryPtr->entryNum << ";\n";
938     } else {
939       op << "       tr->entries[" << iRef << "] = " << 
940             e->entryPtr->entryNum << ";\n";
941       op << "       tr->refnums[" << iRef++ << "] = " <<
942             e->intExpr << ";\n";
943     }
944     el = el->next;
945   }
946
947 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
948   // max(current,merge) --> current
949   op << "       " << label->charstar()  << "_PathMergePoint.updateMax(currentlyExecutingPath); /* Critical Path Detection */ \n";
950   op << "       currentlyExecutingPath = " << label->charstar()  << "_PathMergePoint; /* Critical Path Detection */ \n";
951 #endif
952
953   op << "       __cDep->Register(tr);\n";
954   op << "       return 0;\n";
955   op << "    }\n";
956
957   // end actual code
958   op << "  }\n\n";
959
960   // trace
961   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
962   strcat(nameStr,"_end");
963
964   // end function
965   op << "  void " << label->charstar() << "_end(";
966   generatePrototype(op, *stateVarsChildren);
967   op << ") {\n";
968 #if CMK_BLUEGENE_CHARM
969   generateBeginTime(op);
970   generateEventBracket(op,SWHEN_END);
971 #endif
972   // actual code here 
973   if(nextBeginOrEnd == 1)
974    op << "    " << next->label->charstar();
975   else 
976     op << "    " << next->label->charstar() << "_end";
977
978   op << "(";
979
980   generateCall(op, *stateVars); 
981   
982   op << ");\n";
983   // end actual code
984   op << "  }\n\n";
985 }
986
987 void SdagConstruct::generateWhile(XStr& op)
988 {
989   // inlined start function
990   op << "  void " << label->charstar() << "(";
991   generatePrototype(op, *stateVars);
992   op << ") {\n";
993   // actual code here 
994   op << "    if (" << con1->text->charstar() << ") {\n";
995   op << "      " << constructs->front()->label->charstar() << 
996         "(";
997   generateCall(op, *stateVarsChildren);
998   op << ");\n";
999   op << "    } else {\n";
1000   if(nextBeginOrEnd == 1)
1001    op << "      " << next->label->charstar() << "(";
1002   else
1003    op << "      " << next->label->charstar() << "_end(";
1004   generateCall(op, *stateVars);
1005   op << ");\n";
1006   op << "    }\n";
1007   // end actual code
1008   op << "  }\n\n";
1009   // inlined end function
1010   op << "  void " << label->charstar() << "_end(";
1011   generatePrototype(op, *stateVarsChildren);
1012   op << ") {\n";
1013   // actual code here 
1014   op << "    if (" << con1->text->charstar() << ") {\n";
1015   op << "      " << constructs->front()->label->charstar() <<
1016         "(";
1017   generateCall(op, *stateVarsChildren);
1018   op << ");\n";
1019   op << "    } else {\n";
1020   if(nextBeginOrEnd == 1)
1021    op << "      " <<  next->label->charstar() << "(";
1022   else
1023    op << "      " << next->label->charstar() << "_end(";
1024   generateCall(op, *stateVars);
1025   op << ");\n";
1026   op << "    }\n";
1027   // end actual code
1028   op << "  }\n\n";
1029 }
1030
1031 void SdagConstruct::generateFor(XStr& op)
1032 {
1033   // inlined start function
1034   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1035   op << "  void " << label->charstar() << "(";
1036   generatePrototype(op, *stateVars);
1037   op << ") {\n";
1038 #if CMK_BLUEGENE_CHARM
1039   // actual code here 
1040   generateBeginTime(op);
1041 #endif
1042   op << "    " << con1->text->charstar() << ";\n";
1043   //Record only the beginning for FOR
1044 #if CMK_BLUEGENE_CHARM
1045   generateEventBracket(op,SFOR);
1046 #endif
1047   op << "    if (" << con2->text->charstar() << ") {\n";
1048   op << "      " << constructs->front()->label->charstar() <<
1049         "(";
1050   generateCall(op, *stateVarsChildren);
1051   op << ");\n";
1052   op << "    } else {\n";
1053   if(nextBeginOrEnd == 1)
1054    op << "      " << next->label->charstar() << "(";
1055   else
1056    op << "      " << next->label->charstar() << "_end(";
1057   generateCall(op, *stateVars);
1058   op << ");\n";
1059   op << "    }\n";
1060   // end actual code
1061   op << "  }\n";
1062   // inlined end function
1063   // trace
1064   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1065   strcat(nameStr,"_end");
1066   op << "  void " << label->charstar() << "_end(";
1067   generatePrototype(op, *stateVarsChildren);
1068   op << ") {\n";
1069 #if CMK_BLUEGENE_CHARM
1070   generateBeginTime(op);
1071 #endif
1072   // actual code here 
1073   op << con3->text->charstar() << ";\n";
1074   op << "    if (" << con2->text->charstar() << ") {\n";
1075   op << "      " << constructs->front()->label->charstar() <<
1076         "(";
1077   generateCall(op, *stateVarsChildren);
1078   op << ");\n";
1079   op << "    } else {\n";
1080 #if CMK_BLUEGENE_CHARM
1081   generateEventBracket(op,SFOR_END);
1082 #endif
1083   if(nextBeginOrEnd == 1)
1084    op << "      " << next->label->charstar() << "(";
1085   else
1086    op << "      " << next->label->charstar() << "_end(";
1087    generateCall(op, *stateVars);
1088   op << ");\n";
1089   op << "    }\n";
1090   // end actual code
1091   op << "  }\n";
1092 }
1093
1094 void SdagConstruct::generateIf(XStr& op)
1095 {
1096   // inlined start function
1097   strcpy(nameStr,label->charstar());
1098   op << "  void " << label->charstar() << "(";
1099   generatePrototype(op, *stateVars);
1100   op << ") {\n";
1101 #if CMK_BLUEGENE_CHARM
1102   generateBeginTime(op);
1103   generateEventBracket(op,SIF);
1104 #endif
1105   // actual code here 
1106   op << "    if (" << con1->text->charstar() << ") {\n";
1107   op << "      " << constructs->front()->label->charstar() <<
1108         "(";
1109   generateCall(op, *stateVarsChildren);
1110   op << ");\n";
1111   op << "    } else {\n";
1112   if (con2 != 0) {
1113     op << "      " << con2->label->charstar() << "(";
1114     generateCall(op, *stateVarsChildren);
1115     op << ");\n";
1116   } else {
1117     op << "      " << label->charstar() << "_end(";
1118     generateCall(op, *stateVarsChildren);
1119     op << ");\n";
1120   }
1121   op << "    }\n";
1122   // end actual code
1123   op << "  }\n\n";
1124   // inlined end function
1125   strcpy(nameStr,label->charstar());
1126   strcat(nameStr,"_end");
1127   op << "  void " << label->charstar() << "_end(";
1128   generatePrototype(op, *stateVarsChildren);
1129   op << ") {\n";
1130 #if CMK_BLUEGENE_CHARM
1131   generateBeginTime(op);
1132   generateEventBracket(op,SIF_END);
1133 #endif
1134   // actual code here 
1135   if(nextBeginOrEnd == 1)
1136    op << "      " << next->label->charstar() << "(";
1137   else
1138    op << "      " << next->label->charstar() << "_end(";
1139   generateCall(op, *stateVars);
1140   op << ");\n";
1141   // end actual code
1142   op << "  }\n\n";
1143 }
1144
1145 void SdagConstruct::generateElse(XStr& op)
1146 {
1147   // inlined start function
1148   strcpy(nameStr,label->charstar());
1149   op << "  void " << label->charstar() << "(";
1150   generatePrototype(op, *stateVars);
1151   op << ") {\n";
1152   // trace
1153   generateBeginTime(op);
1154   generateEventBracket(op,SELSE);
1155   // actual code here 
1156   op << "    " << constructs->front()->label->charstar() << 
1157         "(";
1158   generateCall(op, *stateVarsChildren);
1159   op << ");\n";
1160   // end actual code
1161   op << "  }\n\n";
1162   // inlined end function
1163   // trace
1164   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1165   strcat(nameStr,"_end");
1166   op << "  void " << label->charstar() << "_end(";
1167   generatePrototype(op, *stateVarsChildren);
1168   op << ") {\n";
1169 #if CMK_BLUEGENE_CHARM
1170   generateBeginTime(op);
1171   generateEventBracket(op,SELSE_END);
1172 #endif
1173   // actual code here 
1174   if(nextBeginOrEnd == 1)
1175    op << "      " << next->label->charstar() << "(";
1176   else
1177    op << "      " << next->label->charstar() << "_end(";
1178   generateCall(op, *stateVars);
1179   op << ");\n";
1180   // end actual code
1181   op << "  }\n\n";
1182 }
1183
1184 void SdagConstruct::generateForall(XStr& op)
1185 {
1186   // inlined start function
1187   op << "  void " << label->charstar() << "(";
1188   generatePrototype(op, *stateVars);
1189   op << ") {\n";
1190   // actual code here 
1191   op << "    int __first = (" << con2->text->charstar() <<
1192         "), __last = (" << con3->text->charstar() << 
1193         "), __stride = (" << con4->text->charstar() << ");\n";
1194   op << "    if (__first > __last) {\n";
1195   op << "      int __tmp=__first; __first=__last; __last=__tmp;\n";
1196   op << "      __stride = -__stride;\n";
1197   op << "    }\n";
1198   op << "    CCounter *" << counter->charstar() << 
1199         " = new CCounter(__first,__last,__stride);\n"; 
1200   op << "    for(int " << con1->text->charstar() << 
1201         "=__first;" << con1->text->charstar() <<
1202         "<=__last;" << con1->text->charstar() << "+=__stride) {\n";
1203   op << "      " << constructs->front()->label->charstar() <<
1204         "(";
1205   generateCall(op, *stateVarsChildren);
1206   op << ");\n";
1207   op << "    }\n";
1208   // end actual code
1209   op << "  }\n\n";
1210   // inlined end function
1211   op << "  void " << label->charstar() << "_end(";
1212   generatePrototype(op, *stateVarsChildren);
1213   op << ") {\n";
1214   // actual code here 
1215   op << "    " << counter->charstar() << "->decrement(); /* DECREMENT 1 */ \n";
1216   op << "    if (" << counter->charstar() << "->isDone()) {\n";
1217   op << "      delete " << counter->charstar() << ";\n";
1218   if(nextBeginOrEnd == 1)
1219    op << "      " << next->label->charstar() << "(";
1220   else
1221    op << "      " << next->label->charstar() << "_end(";
1222   generateCall(op, *stateVars);
1223   op << ");\n";
1224   // end actual code
1225   op << "    }\n  }\n\n";
1226 }
1227
1228 void SdagConstruct::generateOlist(XStr& op)
1229 {
1230   SdagConstruct *cn;
1231   // inlined start function
1232   op << "  void " << label->charstar() << "(";
1233   generatePrototype(op, *stateVars);
1234   op << ") {\n";
1235   // actual code here 
1236   op << "    CCounter *" << counter->charstar() << "= new CCounter(" <<
1237         constructs->length() << ");\n";
1238   for(cn=constructs->begin(); 
1239                      !constructs->end(); cn=constructs->next()) {
1240     op << "    " << cn->label->charstar() << "(";
1241     generateCall(op, *stateVarsChildren);
1242     op << ");\n";
1243   }
1244   // end actual code
1245   op << "  }\n";
1246
1247   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1248   strcat(nameStr,"_end");
1249 #if CMK_BLUEGENE_CHARM
1250   op << "  CkVec<void*> " <<label->charstar() << "_bgLogList;\n";
1251 #endif
1252
1253   // inlined end function
1254   op << "  void " << label->charstar() << "_end(";
1255   generatePrototype(op, *stateVarsChildren);
1256   op << ") {\n";
1257 #if CMK_BLUEGENE_CHARM
1258   generateBeginTime(op);
1259   op << "    " <<label->charstar() << "_bgLogList.insertAtEnd(_bgParentLog);\n";
1260 #endif
1261   // actual code here 
1262   //Accumulate all the bgParent pointers that the calling when_end functions give
1263   op << "    " << counter->charstar() << "->decrement();\n";
1264  
1265 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1266  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";
1267 #endif
1268
1269   op << "    if (" << counter->charstar() << "->isDone()) {\n";
1270
1271 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1272   op << "      currentlyExecutingPath = olist_" << counter->charstar() << "_PathMergePoint; /* Critical Path Detection */ \n";
1273   op << "      olist_" << counter->charstar() << "_PathMergePoint.reset(); /* Critical Path Detection */ \n";
1274 #endif
1275
1276   op << "      delete " << counter->charstar() << ";\n";
1277
1278 #if CMK_BLUEGENE_CHARM
1279   generateListEventBracket(op,SOLIST_END);
1280   op << "       "<< label->charstar() <<"_bgLogList.length()=0;\n";
1281 #endif
1282
1283   if(nextBeginOrEnd == 1)
1284    op << "      " << next->label->charstar() << "(";
1285   else
1286    op << "      " << next->label->charstar() << "_end(";
1287   generateCall(op, *stateVars);
1288   op << ");\n";
1289   // end actual code
1290   op << "    }\n";
1291   op << "  }\n";
1292 }
1293
1294 void SdagConstruct::generateOverlap(XStr& op)
1295 {
1296   // inlined start function
1297   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1298   op << "  void " << label->charstar() << "(";
1299   generatePrototype(op, *stateVars);
1300   op << ") {\n";
1301 #if CMK_BLUEGENE_CHARM
1302   generateBeginTime(op);
1303   generateEventBracket(op,SOVERLAP);
1304 #endif
1305   // actual code here 
1306   op << "    " << constructs->front()->label->charstar() <<
1307         "(";
1308   generateCall(op, *stateVarsChildren);
1309   op << ");\n";
1310   // end actual code
1311   op << "  }\n";
1312   // trace
1313   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1314   strcat(nameStr,"_end");
1315   // inlined end function
1316   op << "  void " << label->charstar() << "_end(";
1317   generatePrototype(op, *stateVarsChildren);
1318   op << ") {\n";
1319 #if CMK_BLUEGENE_CHARM
1320   generateBeginTime(op);
1321   generateEventBracket(op,SOVERLAP_END);
1322 #endif
1323   // actual code here 
1324   if(nextBeginOrEnd == 1)
1325    op << "    " << next->label->charstar() << "(";
1326   else
1327    op << "    " << next->label->charstar() << "_end(";
1328   generateCall(op, *stateVars);
1329   op << ");\n";
1330   // end actual code
1331   op << "  }\n";
1332 }
1333
1334 void SdagConstruct::generateSlist(XStr& op)
1335 {
1336   // inlined start function
1337   op << "  void " << label->charstar() << "(";
1338   generatePrototype(op, *stateVars);
1339   op << ") {\n";
1340   // actual code here 
1341   op << "    " << constructs->front()->label->charstar() <<
1342         "(";
1343   generateCall(op, *stateVarsChildren);
1344   op << ");\n";
1345   // end actual code
1346   op << "  }\n";
1347   // inlined end function
1348   op << "  void " << label->charstar() << "_end(";
1349   generatePrototype(op, *stateVarsChildren); 
1350   op << ") {\n";
1351   // actual code here 
1352   if(nextBeginOrEnd == 1)
1353    op << "    " << next->label->charstar() << "(";
1354   else
1355    op << "    " << next->label->charstar() << "_end(";
1356   generateCall(op, *stateVars);
1357   op << ");\n";
1358   // end actual code
1359   op << "  }\n";
1360 }
1361
1362 void SdagConstruct::generateSdagEntry(XStr& op)
1363 {
1364   // header file
1365   op << "public:\n";
1366   op << "  void " << con1->text->charstar() << "(";
1367   generatePrototype(op, *stateVars);
1368   op << ") {\n";
1369   SdagConstruct *sc;
1370   SdagConstruct *sc1;
1371   for(sc =publishesList->begin(); !publishesList->end(); sc=publishesList->next()) {
1372      for(sc1=sc->constructs->begin(); !sc->constructs->end(); sc1 = sc->constructs->next())
1373         op << "    _connect_" << sc1->text->charstar() <<"();\n";
1374   }
1375 #if CMK_BLUEGENE_CHARM
1376   generateEndSeq(op);
1377 #endif
1378   // actual code here 
1379   op << "    " << constructs->front()->label->charstar() <<
1380         "(";
1381   generateCall(op, *stateVarsChildren);
1382   op << ");\n";
1383 #if CMK_BLUEGENE_CHARM
1384   generateTlineEndCall(op);
1385   generateBeginExec(op, "spaceholder");
1386 #endif
1387   generateDummyBeginExecute(op);
1388   // end actual code
1389   op << "  }\n\n";
1390   op << "private:\n";
1391   op << "  void " << con1->text->charstar() << "_end(";
1392 #if CMK_BLUEGENE_CHARM
1393   generatePrototype(op, *stateVarsChildren);
1394 #else
1395   generatePrototype(op, *stateVars);
1396 #endif
1397   op << ") {\n";
1398   op << "  }\n\n";
1399 }
1400
1401 void SdagConstruct::generateAtomic(XStr& op)
1402
1403   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1404   op << "  void " << label->charstar() << "(";
1405   generatePrototype(op, *stateVars);
1406   op << ") {\n";
1407 #if CMK_BLUEGENE_CHARM
1408   generateBeginExec(op, nameStr);
1409 #endif
1410   generateTraceBeginCall(op);
1411   op << "    " << text->charstar() << "\n";
1412   // trace
1413   generateTraceEndCall(op);
1414 #if CMK_BLUEGENE_CHARM
1415   generateEndExec(op);
1416 #endif
1417   SdagConstruct *cn;
1418   if(nextBeginOrEnd == 1)
1419     op << "    " << next->label->charstar() << "(";
1420   else
1421     op << "    " << next->label->charstar() << "_end(";
1422   generateCall(op, *stateVars);
1423   op << ");\n";
1424   op << "  }\n\n";
1425 }
1426
1427 void SdagConstruct::generatePrototype(XStr& op, ParamList *list)
1428 {
1429    ParamList *pl = list;
1430    int count = 0;
1431    int i, numStars;
1432    if (pl->isVoid() == 1) {
1433      op << "void"; 
1434    }
1435    else if (pl->isMessage() == 1){
1436      op << pl->getBaseName() <<" *" <<pl->getGivenName() ;
1437    }
1438    else {
1439      while(pl != NULL) {
1440        if (count > 0)
1441           op <<", ";
1442        if (pl->isPointer() == 1) {
1443          op <<pl->getBaseName(); 
1444          numStars = pl->getNumStars();
1445          for(i=0; i< numStars; i++)
1446            op <<"*";
1447          op <<" "<<pl->getGivenName();
1448        }
1449        else if (pl->isReference() == 1) 
1450          op <<pl->getBaseName() <<"& " <<pl->getGivenName();
1451        else if (pl->isArray() == 1) 
1452          op <<pl->getBaseName() <<"* " <<pl->getGivenName();
1453        else if ((pl->isBuiltin() == 1) || (pl->isNamed() == 1))
1454          op <<pl->getBaseName() <<" " <<pl->getGivenName();
1455        pl = pl->next;
1456        count++;
1457      }
1458    }
1459 }
1460
1461
1462 void SdagConstruct::generatePrototype(XStr& op, TList<CStateVar*>& list)
1463 {
1464   CStateVar *sv;
1465   int isVoid;
1466   int count;
1467   count = 0;
1468   for(sv=list.begin(); !list.end(); ) {
1469     isVoid = sv->isVoid;
1470     if ((count != 0) && (isVoid != 1))
1471        op << ", ";
1472     if (sv->isVoid != 1) {
1473       if (sv->type != 0) 
1474          op <<sv->type->charstar() <<" ";
1475       if (sv->byRef != 0)
1476          op <<" &";
1477       if (sv->arrayLength != NULL) 
1478          op <<"*";
1479       else if (sv->numPtrs != 0) {
1480         for (int i=0; i<sv->numPtrs; i++) 
1481           op <<"*";
1482          op <<" ";
1483       }
1484       if (sv->name != 0)
1485          op <<sv->name->charstar();
1486     }
1487     if (sv->isVoid != 1)
1488        count++;
1489     sv = list.next();
1490   }
1491 }
1492
1493 void SdagConstruct::generateCall(XStr& op, TList<CStateVar*>& list) {
1494   CStateVar *sv;
1495   int isVoid;
1496   int count;
1497   count = 0;
1498   for(sv=list.begin(); !list.end(); ) {
1499      isVoid = sv->isVoid;
1500      if ((count != 0) && (isVoid != 1))
1501         op << ", ";
1502      if (sv->name != 0) 
1503        op << sv->name->charstar();
1504     if (sv->isVoid != 1)
1505        count++;
1506     sv = list.next();
1507   }
1508 }
1509
1510 // boe = 1, if the next call is to begin construct
1511 // boe = 0, if the next call is to end a contruct
1512 void SdagConstruct::setNext(SdagConstruct *n, int boe)
1513 {
1514   switch(type) {
1515     case SSLIST:
1516       next = n;
1517       nextBeginOrEnd = boe;
1518       {
1519         SdagConstruct *notConnectNode = this;
1520         SdagConstruct *cn=constructs->begin();
1521         if (cn==0) // empty slist
1522           return;
1523         else if (cn->type != SCONNECT)
1524           notConnectNode = cn;
1525         int flag = 1;
1526         SdagConstruct *nextNode=constructs->next();
1527         for(; nextNode != 0;) {
1528           if (nextNode->type != SCONNECT)
1529             notConnectNode = nextNode;
1530           flag = 1;
1531           while ((flag == 1) && (nextNode->type == SCONNECT)) {
1532             nextNode = constructs->next();
1533             if (nextNode == 0)
1534               flag = 0;
1535           }
1536           if (nextNode != 0) {
1537             cn->setNext(nextNode, 1);
1538             cn = nextNode;
1539             nextNode = constructs->next();
1540           }
1541         }
1542         cn->setNext(this, 0);
1543       }
1544       return;
1545     case SSDAGENTRY:
1546     case SOVERLAP:
1547     case SOLIST:
1548     case SFORALL:
1549     case SWHEN:
1550     case SFOR:
1551     case SWHILE:
1552     case SATOMIC:
1553     case SFORWARD:
1554     case SELSE:
1555       next = n;
1556       nextBeginOrEnd = boe;
1557       n = this; boe = 0; break;
1558     case SIF:
1559       next = n;
1560       nextBeginOrEnd = boe;
1561       if(con2 != 0)
1562         con2->setNext(n, boe);
1563       n = this;
1564       boe = 0;
1565       break;
1566     default:
1567       break;
1568   }
1569   SdagConstruct *cn;
1570   if (constructs != 0) {
1571     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1572       cn->setNext(n, boe);
1573     }
1574   }
1575 }
1576
1577
1578 // for trace
1579
1580 void SdagConstruct::generateTrace()
1581 {
1582   char text[1024];
1583   switch(type) {
1584   case SATOMIC:
1585     if (traceName) {
1586       sprintf(text, "%s_%s", CParsedFile::className->charstar(), traceName->charstar());
1587       // remove blanks
1588       for (int i=0; i<strlen(text); i++)
1589         if (text[i]==' '||text[i]=='\t') text[i]='_';
1590     }
1591     else {
1592       sprintf(text, "%s%s", CParsedFile::className->charstar(), label->charstar());
1593     }
1594     traceName = new XStr(text);
1595     break;
1596   default:
1597     break;
1598   }
1599
1600   SdagConstruct *cn;
1601   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1602     cn->generateTrace();
1603   }
1604   if (con1) con1->generateTrace();
1605   if (con2) con2->generateTrace();
1606   if (con3) con3->generateTrace();
1607 }
1608
1609 void SdagConstruct::generateTraceBeginCall(XStr& op)          // for trace
1610 {
1611   if(traceName)
1612     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, " << "__idx_" << traceName->charstar() << ", CkMyPe(), 0, NULL); \n";
1613 }
1614
1615 void SdagConstruct::generateDummyBeginExecute(XStr& op)
1616 {
1617     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, _dummyEP, CkMyPe(), 0, NULL); \n";
1618 }
1619
1620 void SdagConstruct::generateTraceEndCall(XStr& op)          // for trace
1621 {
1622   op << "    " << "_TRACE_END_EXECUTE(); \n";
1623 }
1624
1625 void SdagConstruct::generateBeginExec(XStr& op, const char *name){
1626   op << "     " << "_TRACE_BG_BEGIN_EXECUTE_NOMSG(\""<<name<<"\",&_bgParentLog,1);\n"; 
1627 }
1628
1629 void SdagConstruct::generateEndExec(XStr& op){
1630   op << "     " << "_TRACE_BG_END_EXECUTE(0);\n";
1631 }
1632
1633 void SdagConstruct::generateBeginTime(XStr& op)
1634 {
1635   //Record begin time for tracing
1636   op << "    double __begintime = CkVTimer(); \n";
1637 }
1638
1639 void SdagConstruct::generateTlineEndCall(XStr& op)
1640 {
1641   //Trace this event
1642   op <<"    _TRACE_BG_TLINE_END(&_bgParentLog);\n";
1643 }
1644
1645 void SdagConstruct::generateEndSeq(XStr& op)
1646 {
1647   op <<  "    void* _bgParentLog = NULL;\n";
1648   op <<  "    CkElapse(0.01e-6);\n";
1649   //op<<  "    BgElapse(1e-6);\n";
1650   generateTlineEndCall(op);
1651   generateTraceEndCall(op);
1652   generateEndExec(op);
1653 }
1654
1655 void SdagConstruct::generateEventBracket(XStr& op, int eventType)
1656 {
1657   //Trace this event
1658   op << "     _TRACE_BG_USER_EVENT_BRACKET(\"" << nameStr
1659      << "\", __begintime, CkVTimer(),&_bgParentLog); \n";
1660 }
1661
1662 void SdagConstruct::generateListEventBracket(XStr& op, int eventType)
1663 {
1664   op << "    _TRACE_BGLIST_USER_EVENT_BRACKET(\"" << nameStr
1665      << "\",__begintime,CkVTimer(),&_bgParentLog, " << label->charstar()
1666      << "_bgLogList);\n";
1667 }
1668
1669 void SdagConstruct::generateRegisterEp(XStr& op)          // for trace
1670 {
1671   if (traceName) {
1672     op << "    __idx_" << traceName->charstar()
1673        << " = CkRegisterEp(\"" << traceName->charstar()
1674        << "(void)\", NULL, 0, CkIndex_" << CParsedFile::className->charstar()
1675        << "::__idx, 0);\n";
1676   }
1677
1678   SdagConstruct *cn;
1679   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1680     cn->generateRegisterEp(op);
1681   }
1682   if (con1) con1->generateRegisterEp(op);
1683   if (con2) con2->generateRegisterEp(op);
1684   if (con3) con3->generateRegisterEp(op);
1685 }
1686
1687 void SdagConstruct::generateTraceEpDecl(XStr& op)          // for trace
1688 {
1689   if (traceName) {
1690     op << "  static int __idx_" << traceName->charstar() << ";\n"; 
1691   }
1692   SdagConstruct *cn;
1693   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1694     cn->generateTraceEpDecl(op);
1695   }
1696   if (con1) con1->generateTraceEpDecl(op);
1697   if (con2) con2->generateTraceEpDecl(op);
1698   if (con3) con3->generateTraceEpDecl(op);
1699 }
1700
1701
1702 void SdagConstruct::generateTraceEpDef(XStr& op)          // for trace
1703 {
1704   if (traceName) {
1705     op << "  int " << CParsedFile::className->charstar()
1706        << "::__idx_" << traceName->charstar() << "=0;\\\n";
1707   }
1708   SdagConstruct *cn;
1709   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1710     cn->generateTraceEpDef(op);
1711   }
1712   if (con1) con1->generateTraceEpDef(op);
1713   if (con2) con2->generateTraceEpDef(op);
1714   if (con3) con3->generateTraceEpDef(op);
1715 }
1716
1717
1718 void RemoveSdagComments(char *str)
1719 {
1720   char *ptr = str;
1721   while (ptr = strstr(ptr, "//")) {
1722     char *lend = strstr(ptr, "\n");
1723     if (lend==NULL) break;
1724     while (ptr != lend) *ptr++=' ';
1725   }
1726 }
1727
1728 }