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