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