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