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