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