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