charmxi: convert SdagConstruct::constructs 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 TList<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 TList<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 TList<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 TList<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, TList<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.append(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, TList<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     el->entry->stateVars = new TList<CStateVar*>();
447     if (pl->isVoid()) {
448       sv = new CStateVar(1, NULL, 0, NULL, 0, NULL, 0);
449       //stateVars->push_back(sv);
450       stateVarsChildren->push_back(sv);
451       whensEntryMethodStateVars.push_back(sv);
452       el->entry->addEStateVar(sv);
453     }
454     else {
455       while(pl != NULL) {
456         sv = new CStateVar(pl);
457         stateVarsChildren->push_back(sv);
458         whensEntryMethodStateVars.push_back(sv);
459         el->entry->addEStateVar(sv);
460
461         pl = pl->next;
462       }
463     }
464     el = el->next;
465
466   }
467
468   propagateStateToChildren(*stateVarsChildren, whensEntryMethodStateVars, publist, uniqueVarNum);
469 }
470
471 void SdagConstruct::propagateStateToChildren(list<CStateVar*>& stateVarsChildren, list<CStateVar*>& wlist, TList<SdagConstruct*>& publist, int uniqueVarNum) {
472   if (constructs != 0) {
473     for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
474          ++it)
475       (*it)->propagateState(stateVarsChildren, wlist, publist, uniqueVarNum);
476   }
477 }
478
479 void SdagConstruct::generateCode(XStr& decls, XStr& defs, Entry *entry)
480 {
481   switch(type) {
482     case SSDAGENTRY:
483       generateSdagEntry(decls, defs, entry);
484       break;
485     case SSLIST:
486       generateSlist(decls, defs, entry);
487       break;
488     case SOLIST:
489       generateOlist(decls, defs, entry);
490       break;
491     case SFORALL:
492       generateForall(decls, defs, entry);
493       break;
494     case SATOMIC:
495       generateAtomic(decls, defs, entry);
496       break;
497     case SIF:
498       generateIf(decls, defs, entry);
499       if(con2 != 0)
500         con2->generateCode(decls, defs, entry);
501       break;
502     case SELSE:
503       generateElse(decls, defs, entry);
504       break;
505     case SWHILE:
506       generateWhile(decls, defs, entry);
507       break;
508     case SFOR:
509       generateFor(decls, defs, entry);
510       break;
511     case SOVERLAP:
512       generateOverlap(decls, defs, entry);
513       break;
514     case SFORWARD:
515       generateForward(decls, defs, entry);
516       break;
517     case SCONNECT:
518       generateConnect(decls, defs, entry);
519       break;
520     default:
521       break;
522   }
523   generateChildrenCode(decls, defs, entry);
524 }
525
526 void SdagConstruct::generateChildrenCode(XStr& decls, XStr& defs, Entry* entry) {
527   if (constructs != 0) {
528     for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
529          ++it)
530       (*it)->generateCode(decls, defs, entry);
531   }
532 }
533
534 void SdagConstruct::generateWhenCode(XStr& op)
535 {
536   SdagConstruct *cn = this;
537   XStr whenParams = "";
538   int i = 0;
539   int iArgs = 0;
540   bool lastWasVoid = false;
541   bool paramMarshalling = false;
542
543 #if CMK_BIGSIM_CHARM
544   // bgLog2 stores the parent dependence of when, e.g. for, olist
545   op <<"  cmsgbuf->bgLog2 = (void*)tr->args[1];\n";
546 #endif
547
548   for (list<CStateVar*>::iterator iter = stateVars->begin();
549        iter != stateVars->end();
550        ++iter, ++i) {
551     CStateVar *sv = *iter;
552     if ((sv->isMsg == 0) && (paramMarshalling == 0) && (sv->isVoid ==0)){
553       paramMarshalling =1;
554       op << "        CkMarshallMsg *impl_msg" <<cn->nodeNum <<" = (CkMarshallMsg *) tr->args["<<iArgs++<<"];\n";
555       op << "        char *impl_buf" <<cn->nodeNum <<"=((CkMarshallMsg *)impl_msg" <<cn->nodeNum <<")->msgBuf;\n";
556       op << "        PUP::fromMem implP" <<cn->nodeNum <<"(impl_buf" <<cn->nodeNum <<");\n";
557     }
558     if (sv->isMsg == 1) {
559       if((i!=0) && (lastWasVoid == 0))
560         whenParams.append(", ");
561 #if CMK_BIGSIM_CHARM
562       if(i==1) {
563         whenParams.append(" NULL ");
564         lastWasVoid=0;
565         // skip this arg which is supposed to be _bgParentLog
566         iArgs++;
567         continue;
568       }
569 #endif
570       whenParams.append("(");
571       whenParams.append(sv->type->charstar());
572       whenParams.append(") tr->args[");
573       whenParams<<iArgs;
574       whenParams.append("]");
575       iArgs++;
576     }
577     else if (sv->isVoid == 1)
578       // op <<"    CkFreeSysMsg((void  *)tr->args[" <<iArgs++ <<"]);\n";
579       op <<"        tr->args[" <<iArgs++ <<"] = 0;\n";
580     else if ((sv->isMsg == 0) && (sv->isVoid == 0)) {
581       if((i > 0) && (lastWasVoid == 0))
582         whenParams.append(", ");
583       whenParams.append(*(sv->name));
584       if (sv->arrayLength != 0)
585         op << "        int impl_off" << cn->nodeNum << "_" << sv->name << "; implP"
586           <<cn->nodeNum << "|impl_off" <<cn->nodeNum  << "_" << sv->name << ";\n";
587       else
588         op << "        " << sv->type << " " << sv->name << "; implP"
589           <<cn->nodeNum << "|" << sv->name << ";\n";
590     }
591     lastWasVoid = sv->isVoid;
592   }
593   if (paramMarshalling == 1)
594     op << "        impl_buf"<<cn->nodeNum << "+=CK_ALIGN(implP" <<cn->nodeNum <<".size(),16);\n";
595   for (list<CStateVar*>::iterator iter = stateVars->begin();
596        iter != stateVars->end();
597        ++iter) {
598     CStateVar *sv = *iter;
599     if (sv->arrayLength != 0)
600       op << "        " << sv->type << " *" << sv->name << "=(" << sv->type << " *)(impl_buf" <<cn->nodeNum
601         << "+impl_off" <<cn->nodeNum << "_" << sv->name << ");\n";
602   }
603   if (paramMarshalling == 1)
604     op << "        delete (CkMarshallMsg *)impl_msg" <<cn->nodeNum <<";\n";
605   op << "        " << cn->label << "(" << whenParams;
606   op << ");\n";
607   op << "        delete tr;\n";
608
609 #if CMK_BIGSIM_CHARM
610   cn->generateTlineEndCall(op);
611   cn->generateBeginExec(op, "sdagholder");
612 #endif
613   op << "    ";
614   cn->generateDummyBeginExecute(op);
615
616   op << "        return;\n";
617 }
618
619 void SdagConstruct::generateConnect(XStr& decls, XStr& defs, Entry* entry) {
620   generateSignature(decls, defs, entry, false, "void", label, false, NULL);
621   defs << "    int index;\n";
622   if ((param->isVoid() == 0) && (param->isMessage() == 0)) {
623      defs << "    CkMarshallMsg *x;\n";
624      defs << "    index = CkIndex_Ar1::" <<connectEntry <<"(x);\n";  //replace
625      defs << "    CkCallback cb(index, CkArrayIndex1D(thisIndex), a1);\n";  // replace
626   }
627   else if (param->isVoid() == 1) {
628      defs << "    index = CkIndex_Ar1::" <<connectEntry <<"(void);\n";  //replace
629      defs << "    CkCallback cb(index, CkArrayIndex1D(thisIndex), a1);\n";  // replace
630   }
631   else {
632      defs << "    " << param->getBaseName() <<" *x;\n";  // replace
633      defs << "    index = CkIndex_Ar1::" <<connectEntry <<"(x);\n";  //replace
634      defs << "    CkCallback cb(index, CkArrayIndex1D(thisIndex), a1);\n";  // replace
635   }
636   defs << "    myPublish->get_" <<connectEntry <<"(cb);\n";  //replace - myPublish
637
638   endMethod(defs);
639 }
640
641 void SdagConstruct::generateForward(XStr& decls, XStr& defs, Entry* entry) {
642   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
643   for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
644        ++it) {
645     defs << "    { ";
646     generateCall(defs, *stateVarsChildren, (*it)->text);
647     defs<<" }\n";
648   }
649   generateCall(defs, *stateVarsChildren, next->label, nextBeginOrEnd ? 0 : "_end");
650   endMethod(defs);
651 }
652
653
654 void WhenConstruct::generateCode(XStr& decls, XStr& defs, Entry* entry)
655 {
656   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
657   generateSignature(decls, defs, entry, false, "int", label, false, stateVars);
658 #if CMK_BIGSIM_CHARM
659   generateBeginTime(defs);
660 #endif
661
662   CStateVar *sv;
663
664   Entry *e;
665   EntryList *el;
666   el = elist;
667   while (el != NULL){
668     e = el->entry;
669     if (e->param->isVoid() == 1)
670         defs << "    CMsgBuffer *"<<e->getEntryName()<<"_buf;\n";
671     else if (e->paramIsMarshalled() == 1) {
672
673         defs << "    CMsgBuffer *"<<e->getEntryName()<<"_buf;\n";
674         defs << "    CkMarshallMsg *" <<
675                         e->getEntryName() << "_msg;\n";
676     }
677     else {
678         for(sv=e->stateVars->begin(); !e->stateVars->end(); e->stateVars->next()) {
679           defs << "    CMsgBuffer *"<<sv->name<<"_buf;\n";
680           defs << "    " << sv->type << " " <<
681                           sv->name << ";\n";
682         } 
683     }
684     el = el->next;
685   }
686
687   defs << "\n";
688   el = elist;
689   while (el != NULL) {
690      e = el->entry;
691
692      defs << "    ";
693      if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() == 1))
694        defs << e->getEntryName();
695      else
696        defs << sv->name;
697      defs << "_buf = __cDep->getMessage(" << e->entryPtr->entryNum;
698      if (e->intExpr)
699        defs << ", " << e->intExpr;
700      defs << ");\n";
701
702     el = el->next;
703   }
704
705   defs << "\n";
706   defs << "    if (";
707   el = elist;
708   while (el != NULL)  {
709      e = el->entry;
710      if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() ==1)) {
711         defs << "(" << e->getEntryName() << "_buf != 0)";
712      }
713      else {
714         sv = e->stateVars->begin();
715         defs << "(" << sv->name << "_buf != 0)";
716      }
717      el = el->next;
718      if (el != NULL)
719         defs << "&&";
720   }
721   defs << ") {\n";
722
723 #if CMK_BIGSIM_CHARM
724   // for tracing
725   //TODO: instead of this, add a length field to EntryList
726   int elen=0;
727   for(el=elist; el!=NULL; el=elist->next) elen++;
728  
729   defs << "         void * logs1["<< elen << "]; \n";
730   defs << "         void * logs2["<< elen + 1<< "]; \n";
731   int localnum = 0;
732   for(el=elist; el!=NULL; el=elist->next) {
733     e = el->entry;
734        if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() ==1)) {
735         defs << "       logs1[" << localnum << "] = " << /*el->con4->text sv->type*/e->getEntryName() << "_buf->bgLog1; \n";
736         defs << "       logs2[" << localnum << "] = " << /*el->con4->text sv->type*/e->getEntryName() << "_buf->bgLog2; \n";
737         localnum++;
738       }
739       else{
740         defs << "       logs1[" << localnum << "] = " << /*el->con4->text*/ sv->name<< "_buf->bgLog1; \n";
741         defs << "       logs2[" << localnum << "] = " << /*el->con4->text*/ sv->name << "_buf->bgLog2; \n";
742         localnum++;
743       }
744   }
745       
746   defs << "       logs2[" << localnum << "] = " << "_bgParentLog; \n";
747   generateEventBracket(defs,SWHEN);
748   defs << "       _TRACE_BG_FORWARD_DEPS(logs1,logs2,"<< localnum << ",_bgParentLog);\n";
749 #endif
750
751   el = elist;
752   while (el != NULL) {
753      e = el->entry;
754      if (e->param->isVoid() == 1) {
755         defs <<"       CkFreeSysMsg((void *) "<<e->getEntryName() <<"_buf->msg);\n";
756         defs << "       __cDep->removeMessage(" << e->getEntryName() <<
757               "_buf);\n";
758         defs << "      delete " << e->getEntryName() << "_buf;\n";
759      }
760      else if (e->paramIsMarshalled() == 1) {
761         defs << "       " << e->getEntryName() << "_msg = (CkMarshallMsg *)"
762                << e->getEntryName() << "_buf->msg;\n";
763         defs << "       char *"<<e->getEntryName() <<"_impl_buf=((CkMarshallMsg *)"
764            <<e->getEntryName() <<"_msg)->msgBuf;\n";
765         defs <<"       PUP::fromMem " <<e->getEntryName() <<"_implP("
766            <<e->getEntryName() <<"_impl_buf);\n";
767
768         for(sv=e->stateVars->begin(); !e->stateVars->end(); sv=e->stateVars->next()) {
769            if (sv->arrayLength != NULL)
770               defs <<"       int impl_off_"<<sv->name
771                  <<"; "<<e->getEntryName() <<"_implP|impl_off_"
772                  <<sv->name<<";\n";
773            else
774                defs <<"       "<<sv->type<<" "<<sv->name
775                <<"; " <<e->getEntryName() <<"_implP|"
776                <<sv->name<<";\n";
777         }
778         defs << "       " <<e->getEntryName() <<"_impl_buf+=CK_ALIGN("
779            <<e->getEntryName() <<"_implP.size(),16);\n";
780         for(sv=e->stateVars->begin(); !e->stateVars->end(); sv=e->stateVars->next()) {
781            if (sv->arrayLength != NULL)
782               defs << "       "<<sv->type<< " *" <<sv->name <<"=(" <<sv->type
783                  <<" *)(" <<e->getEntryName() <<"_impl_buf+" <<"impl_off_"
784                  <<sv->name<<");\n";
785         }
786         defs << "       __cDep->removeMessage(" << e->getEntryName() <<
787               "_buf);\n";
788         defs << "       delete " << e->getEntryName() << "_buf;\n";
789      }
790      else {  // There was a message as the only parameter
791         sv = e->stateVars->begin();
792         defs << "       " << sv->name << " = (" <<
793               sv->type << ") " <<
794               sv->name << "_buf->msg;\n";
795         defs << "       __cDep->removeMessage(" << sv->name <<
796               "_buf);\n";
797         defs << "       delete " << sv->name << "_buf;\n";
798      }
799      el = el->next;
800   }
801
802   // max(current,merge) --> current, then reset the mergepath
803 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
804   defs << "       " << label  << "_PathMergePoint.updateMax(currentlyExecutingPath); /* Critical Path Detection */ \n";
805   defs << "       currentlyExecutingPath = " << label  << "_PathMergePoint; /* Critical Path Detection */ \n";
806   defs << "       " << label  << "_PathMergePoint.reset(); /* Critical Path Detection */ \n";
807 #endif
808
809   defs << "       ";
810
811   if (constructs && !constructs->empty()) {
812     generateCall(defs, *stateVarsChildren, constructs->front()->label);
813   } else {
814     generateCall(defs, *stateVarsChildren, label, "_end");
815   }
816
817   el = elist;
818   while (el != NULL){
819     e = el->entry;
820     if (e->paramIsMarshalled() == 1) {
821         defs << "       delete " << e->getEntryName() << "_msg;\n";
822     }
823     el = el->next;
824   }
825   defs << "       return 1;\n";
826   defs << "    } else {\n";
827
828   int nRefs=0, nAny=0;
829   el = elist;
830   while (el != NULL) {
831     e = el->entry;
832     if(e->intExpr == 0)
833       nAny++;
834     else
835       nRefs++;
836     el = el->next;
837   }
838 // keep these consts consistent with sdag.h in runtime
839
840 #define MAXARG 8
841 #define MAXANY 8
842 #define MAXREF 8
843
844   if(stateVars->size() > MAXARG) {
845     fprintf(stderr, "numStateVars more that %d, contact developers.\n",
846                      MAXARG);
847     exit(1);
848   }
849   if(nRefs > MAXREF) {
850     fprintf(stderr, "numDepends more that %d, contact developers.\n",
851                      MAXREF);
852     exit(1);
853   }
854   if(nAny > MAXANY) {
855     fprintf(stderr, "numDepends more that %d, contact developers.\n",
856                      MAXANY);
857     exit(1);
858   }
859   defs << "       CWhenTrigger *tr;\n";
860   defs << "       tr = new CWhenTrigger(" << nodeNum << ", " <<
861     (int)(stateVars->size()) << ", " << nRefs << ", " << nAny << ");\n";
862   int iArgs=0;
863  
864 //  defs << "       int impl_off=0;\n";
865   int hasArray = 0;
866   int numParamsNeedingMarshalling = 0;
867   int paramIndex =0;
868   for (list<CStateVar*>::iterator iter = stateVars->begin();
869        iter != stateVars->end();
870        ++iter) {
871     CStateVar *sv = *iter;
872     if (sv->isVoid == 1) {
873        // defs <<"       tr->args[" <<iArgs++ <<"] = (size_t) CkAllocSysMsg();\n";
874        defs <<"       tr->args[" <<iArgs++ <<"] = (size_t)0xFF;\n";
875     }
876     else {
877       if (sv->isMsg == 1) {
878          defs << "       tr->args["<<iArgs++ <<"] = (size_t) " <<sv->name<<";\n";
879       }
880       else {
881          numParamsNeedingMarshalling++;
882          if (numParamsNeedingMarshalling == 1) {
883            defs << "       int impl_off=0;\n";
884            paramIndex = iArgs;
885            iArgs++;
886          }
887       }
888       if (sv->arrayLength !=NULL) {
889          hasArray++;
890          if (hasArray == 1)
891            defs<< "       int impl_arrstart=0;\n";
892          defs <<"       int impl_off_"<<sv->name<<", impl_cnt_"<<sv->name<<";\n";
893          defs <<"       impl_off_"<<sv->name<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<sv->type<<"));\n";
894          defs <<"       impl_off+=(impl_cnt_"<<sv->name<<"=sizeof("<<sv->type<<")*("<<sv->arrayLength<<"));\n";
895       }
896     }
897   }
898   if (numParamsNeedingMarshalling > 0) {
899      defs << "       { \n";
900      defs << "         PUP::sizer implP;\n";
901      for (list<CStateVar*>::iterator iter = stateVars->begin();
902           iter != stateVars->end();
903           ++iter) {
904        CStateVar *sv = *iter;
905        if (sv->arrayLength !=NULL)
906          defs << "         implP|impl_off_" <<sv->name <<";\n";
907        else if ((sv->isMsg != 1) && (sv->isVoid !=1)) 
908          defs << "         implP|" <<sv->name <<";\n";
909      }
910      if (hasArray > 0) {
911         defs <<"         impl_arrstart=CK_ALIGN(implP.size(),16);\n";
912         defs <<"         impl_off+=impl_arrstart;\n";
913      }
914      else {
915         defs << "         impl_off+=implP.size();\n";
916      }
917      defs << "       }\n";
918      defs << "       CkMarshallMsg *impl_msg;\n";
919      defs << "       impl_msg = CkAllocateMarshallMsg(impl_off,NULL);\n";
920      defs << "       {\n";
921      defs << "         PUP::toMem implP((void *)impl_msg->msgBuf);\n";
922      for (list<CStateVar*>::iterator iter = stateVars->begin();
923           iter != stateVars->end();
924           ++iter) {
925        CStateVar *sv = *iter;
926        if (sv->arrayLength !=NULL)
927           defs << "         implP|impl_off_" <<sv->name <<";\n";
928        else if ((sv->isMsg != 1) && (sv->isVoid != 1))  
929           defs << "         implP|" <<sv->name <<";\n";
930      }
931      defs << "       }\n";
932      if (hasArray > 0) {
933         defs <<"       char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
934         for (list<CStateVar*>::iterator iter = stateVars->begin();
935              iter != stateVars->end();
936              ++iter) {
937           CStateVar *sv = *iter;
938           if (sv->arrayLength !=NULL)
939             defs << "       memcpy(impl_buf+impl_off_" << sv->name <<
940               "," << sv->name << ",impl_cnt_" << sv->name << ");\n";
941         }  
942      }
943   defs << "       tr->args[" <<paramIndex <<"] = (size_t) impl_msg;\n";
944   }
945   int iRef=0, iAny=0;
946
947   el = elist;
948   while (el != NULL) {
949     e = el->entry;
950     if(e->intExpr == 0) {
951       defs << "       tr->anyEntries[" << iAny++ << "] = " <<
952             e->entryPtr->entryNum << ";\n";
953     } else {
954       defs << "       tr->entries[" << iRef << "] = " <<
955             e->entryPtr->entryNum << ";\n";
956       defs << "       tr->refnums[" << iRef++ << "] = " <<
957             e->intExpr << ";\n";
958     }
959     el = el->next;
960   }
961
962 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
963   // max(current,merge) --> current
964   defs << "       " << label  << "_PathMergePoint.updateMax(currentlyExecutingPath); /* Critical Path Detection */ \n";
965   defs << "       currentlyExecutingPath = " << label  << "_PathMergePoint; /* Critical Path Detection */ \n";
966 #endif
967
968   defs << "       __cDep->Register(tr);\n";
969   defs << "       return 0;\n";
970   defs << "    }\n";
971
972   endMethod(defs);
973
974   // trace
975   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
976   strcat(nameStr,"_end");
977
978   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
979 #if CMK_BIGSIM_CHARM
980   generateBeginTime(defs);
981   generateEventBracket(defs, SWHEN_END);
982 #endif
983   defs << "    ";
984   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
985   
986   el = elist;
987   while (el) {
988     e = el->entry;
989     if (e->param->isMessage() == 1) {
990       sv = e->stateVars->begin();
991       defs << "    CmiFree(UsrToEnv(" << sv->name << "));\n";
992     }
993
994     el = el->next;
995   }
996
997   endMethod(defs);
998
999   generateChildrenCode(decls, defs, entry);
1000 }
1001
1002 void SdagConstruct::generateWhile(XStr& decls, XStr& defs, Entry* entry)
1003 {
1004   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1005   defs << "    if (" << con1->text << ") {\n";
1006   defs << "      ";
1007   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1008   defs << "    } else {\n";
1009   defs << "      ";
1010   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1011   defs << "    }\n";
1012   endMethod(defs);
1013
1014   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1015   defs << "    if (" << con1->text << ") {\n";
1016   defs << "      ";
1017   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1018   defs << "    } else {\n";
1019   defs << "      ";
1020   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1021   defs << "    }\n";
1022   endMethod(defs);
1023 }
1024
1025 void SdagConstruct::generateFor(XStr& decls, XStr& defs, Entry* entry)
1026 {
1027   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1028
1029   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1030 #if CMK_BIGSIM_CHARM
1031   generateBeginTime(defs);
1032 #endif
1033   defs << "    " << con1->text << ";\n";
1034   //Record only the beginning for FOR
1035 #if CMK_BIGSIM_CHARM
1036   generateEventBracket(defs, SFOR);
1037 #endif
1038   defs << "    if (" << con2->text << ") {\n";
1039   defs << "      ";
1040   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1041   defs << "    } else {\n";
1042   defs << "      ";
1043   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1044   defs << "    }\n";
1045   endMethod(defs);
1046
1047   // trace
1048   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1049   strcat(nameStr,"_end");
1050
1051   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1052 #if CMK_BIGSIM_CHARM
1053   generateBeginTime(defs);
1054 #endif
1055   defs << "   " << con3->text << ";\n";
1056   defs << "    if (" << con2->text << ") {\n";
1057   defs << "      ";
1058   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1059   defs << "    } else {\n";
1060 #if CMK_BIGSIM_CHARM
1061   generateEventBracket(defs, SFOR_END);
1062 #endif
1063   defs << "      ";
1064   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1065   defs << "    }\n";
1066   endMethod(defs);
1067 }
1068
1069 void SdagConstruct::generateIf(XStr& decls, XStr& defs, Entry* entry)
1070 {
1071   strcpy(nameStr,label->charstar());
1072   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1073 #if CMK_BIGSIM_CHARM
1074   generateBeginTime(defs);
1075   generateEventBracket(defs, SIF);
1076 #endif
1077   defs << "    if (" << con1->text << ") {\n";
1078   defs << "      ";
1079   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1080   defs << "    } else {\n";
1081   defs << "      ";
1082   if (con2 != 0) {
1083     generateCall(defs, *stateVarsChildren, con2->label);
1084   } else {
1085     generateCall(defs, *stateVarsChildren, label, "_end");
1086   }
1087   defs << "    }\n";
1088   endMethod(defs);
1089
1090   strcpy(nameStr,label->charstar());
1091   strcat(nameStr,"_end");
1092   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1093 #if CMK_BIGSIM_CHARM
1094   generateBeginTime(defs);
1095   generateEventBracket(defs,SIF_END);
1096 #endif
1097   defs << "    ";
1098   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1099   endMethod(defs);
1100 }
1101
1102 void SdagConstruct::generateElse(XStr& decls, XStr& defs, Entry* entry)
1103 {
1104   strcpy(nameStr,label->charstar());
1105   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1106   // trace
1107   generateBeginTime(defs);
1108   generateEventBracket(defs, SELSE);
1109   defs << "    ";
1110   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1111   endMethod(defs);
1112
1113   // trace
1114   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1115   strcat(nameStr,"_end");
1116   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1117 #if CMK_BIGSIM_CHARM
1118   generateBeginTime(defs);
1119   generateEventBracket(defs,SELSE_END);
1120 #endif
1121   defs << "      ";
1122   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1123   endMethod(defs);
1124 }
1125
1126 void SdagConstruct::generateForall(XStr& decls, XStr& defs, Entry* entry)
1127 {
1128   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1129   defs << "    int __first = (" << con2->text <<
1130         "), __last = (" << con3->text << 
1131         "), __stride = (" << con4->text << ");\n";
1132   defs << "    if (__first > __last) {\n";
1133   defs << "      int __tmp=__first; __first=__last; __last=__tmp;\n";
1134   defs << "      __stride = -__stride;\n";
1135   defs << "    }\n";
1136   defs << "    CCounter *" << counter <<
1137         " = new CCounter(__first,__last,__stride);\n"; 
1138   defs << "    for(int " << con1->text <<
1139         "=__first;" << con1->text <<
1140         "<=__last;" << con1->text << "+=__stride) {\n";
1141   defs << "      ";
1142   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1143   defs << "    }\n";
1144   endMethod(defs);
1145
1146   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1147   defs << "    " << counter << "->decrement(); /* DECREMENT 1 */ \n";
1148   defs << "    if (" << counter << "->isDone()) {\n";
1149   defs << "      delete " << counter << ";\n";
1150   defs << "      ";
1151   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1152   defs << "    }\n";
1153   endMethod(defs);
1154 }
1155
1156 void SdagConstruct::generateOlist(XStr& decls, XStr& defs, Entry* entry)
1157 {
1158   SdagConstruct *cn;
1159   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1160   defs << "    CCounter *" << counter << "= new CCounter(" <<
1161     (int)constructs->size() << ");\n";
1162   for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
1163        ++it) {
1164     defs << "    ";
1165     generateCall(defs, *stateVarsChildren, (*it)->label);
1166   }
1167   endMethod(defs);
1168
1169   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1170   strcat(nameStr,"_end");
1171 #if CMK_BIGSIM_CHARM
1172   defs << "  CkVec<void*> " <<label << "_bgLogList;\n";
1173 #endif
1174
1175   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1176 #if CMK_BIGSIM_CHARM
1177   generateBeginTime(defs);
1178   defs << "    " <<label << "_bgLogList.insertAtEnd(_bgParentLog);\n";
1179 #endif
1180   //Accumulate all the bgParent pointers that the calling when_end functions give
1181   defs << "    " << counter << "->decrement();\n";
1182  
1183 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1184  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";
1185 #endif
1186
1187   defs << "    if (" << counter << "->isDone()) {\n";
1188
1189 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1190   defs << "      currentlyExecutingPath = olist_" << counter << "_PathMergePoint; /* Critical Path Detection */ \n";
1191   defs << "      olist_" << counter << "_PathMergePoint.reset(); /* Critical Path Detection */ \n";
1192 #endif
1193
1194   defs << "      delete " << counter << ";\n";
1195
1196 #if CMK_BIGSIM_CHARM
1197   generateListEventBracket(defs, SOLIST_END);
1198   defs << "       "<< label <<"_bgLogList.length()=0;\n";
1199 #endif
1200
1201   defs << "      ";
1202   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1203   defs << "    }\n";
1204   endMethod(defs);
1205 }
1206
1207 void SdagConstruct::generateOverlap(XStr& decls, XStr& defs, Entry* entry)
1208 {
1209   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1210   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1211 #if CMK_BIGSIM_CHARM
1212   generateBeginTime(defs);
1213   generateEventBracket(defs, SOVERLAP);
1214 #endif
1215   defs << "    ";
1216   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1217   endMethod(defs);
1218
1219   // trace
1220   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1221   strcat(nameStr,"_end");
1222   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1223 #if CMK_BIGSIM_CHARM
1224   generateBeginTime(defs);
1225   generateEventBracket(defs, SOVERLAP_END);
1226 #endif
1227   defs << "    ";
1228   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1229   endMethod(defs);
1230 }
1231
1232 void SdagConstruct::generateSlist(XStr& decls, XStr& defs, Entry* entry)
1233 {
1234   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1235   defs << "    ";
1236   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1237   endMethod(defs);
1238
1239   generateSignature(decls, defs, entry, false, "void", label, true, stateVarsChildren);
1240   defs << "    ";
1241   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1242   endMethod(defs);
1243 }
1244
1245 void SdagConstruct::generateSdagEntry(XStr& decls, XStr& defs, Entry *entry)
1246 {
1247   if (entry->isConstructor()) {
1248     std::cerr << cur_file << ":" << entry->getLine()
1249               << ": Chare constructor cannot be defined with SDAG code" << std::endl;
1250     exit(1);
1251   }
1252
1253   decls << "public:\n";
1254   generateSignature(decls, defs, entry, false, "void", con1->text, false, stateVars);
1255   SdagConstruct *sc;
1256   SdagConstruct *sc1;
1257   for(sc =publishesList->begin(); !publishesList->end(); sc=publishesList->next()) {
1258     for (list<SdagConstruct*>::iterator it = sc->constructs->begin();
1259          it != sc->constructs->end();
1260          ++it)
1261        defs << "    _connect_" << (*it)->text <<"();\n";
1262   }
1263
1264 #if CMK_BIGSIM_CHARM
1265   generateEndSeq(defs);
1266 #endif
1267   if (!entry->getContainer()->isGroup() || !entry->isConstructor())
1268     generateTraceEndCall(defs);
1269
1270   defs << "    ";
1271   generateCall(defs, *stateVarsChildren, constructs->front()->label);
1272
1273 #if CMK_BIGSIM_CHARM
1274   generateTlineEndCall(defs);
1275   generateBeginExec(defs, "spaceholder");
1276 #endif
1277   if (!entry->getContainer()->isGroup() || !entry->isConstructor())
1278     generateDummyBeginExecute(defs);
1279
1280   endMethod(defs);
1281
1282   decls << "private:\n";
1283   generateSignature(decls, defs, entry, false, "void", con1->text, true,
1284 #if CMK_BIGSIM_CHARM
1285   stateVarsChildren
1286 #else
1287   stateVars
1288 #endif
1289 );
1290   endMethod(defs);
1291 }
1292
1293 void SdagConstruct::generateAtomic(XStr& decls, XStr& defs, Entry* entry)
1294 {
1295   generateSignature(decls, defs, entry, false, "void", label, false, stateVars);
1296
1297 #if CMK_BIGSIM_CHARM
1298   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1299   generateBeginExec(defs, nameStr);
1300 #endif
1301   generateTraceBeginCall(defs);
1302
1303   defs << "    " << text << "\n";
1304
1305   generateTraceEndCall(defs);
1306 #if CMK_BIGSIM_CHARM
1307   generateEndExec(defs);
1308 #endif
1309
1310   defs << "    ";
1311   generateCall(defs, *stateVars, next->label, nextBeginOrEnd ? 0 : "_end");
1312   endMethod(defs);
1313 }
1314
1315 void generateSignature(XStr& str,
1316                        const XStr* name, const char* suffix,
1317                        list<CStateVar*>* params)
1318 {
1319
1320 }
1321 void generateSignature(XStr& decls, XStr& defs,
1322                        const Entry* entry, bool declareStatic, const char* returnType,
1323                        const XStr* name, bool isEnd,
1324                        list<CStateVar*>* params)
1325 {
1326   generateSignature(decls, defs, entry->getContainer(), declareStatic, returnType,
1327                     name, isEnd, params);
1328 }
1329 void generateSignature(XStr& decls, XStr& defs,
1330                        const Chare* chare, bool declareStatic, const char* returnType,
1331                        const XStr* name, bool isEnd,
1332                        list<CStateVar*>* params)
1333 {
1334   decls << "  " << (declareStatic ? "static " : "") << returnType << " ";
1335
1336   templateGuardBegin(false, defs);
1337   defs << chare->tspec() << returnType << " " << chare->baseName() << "::";
1338
1339   XStr op;
1340
1341   op << name;
1342   if (isEnd)
1343     op << "_end";
1344   op << "(";
1345
1346   if (params) {
1347     CStateVar *sv;
1348     int count = 0;
1349     for (list<CStateVar*>::iterator iter = params->begin();
1350          iter != params->end();
1351          ++iter) {
1352       CStateVar *sv = *iter;
1353       if (sv->isVoid != 1) {
1354         if (count != 0)
1355           op << ", ";
1356
1357         if (sv->type != 0) 
1358           op <<sv->type <<" ";
1359         if (sv->byRef != 0)
1360           op <<" &";
1361         if (sv->arrayLength != NULL) 
1362           op <<"* ";
1363         if (sv->name != 0)
1364           op <<sv->name;
1365
1366         count++;
1367       }
1368     }
1369   }
1370
1371   op << ")";
1372
1373   decls << op << ";\n";
1374   defs << op << " {\n";
1375 }
1376 void endMethod(XStr& op)
1377 {
1378   op << "}\n";
1379   templateGuardEnd(op);
1380   op << "\n\n";
1381 }
1382
1383 void SdagConstruct::generateCall(XStr& op, list<CStateVar*>& alist,
1384                                  const XStr* name, const char* nameSuffix) {
1385   op << name << (nameSuffix ? nameSuffix : "") << "(";
1386
1387   CStateVar *sv;
1388   int isVoid;
1389   int count;
1390   count = 0;
1391   for (list<CStateVar*>::iterator iter = alist.begin(); iter != alist.end(); ++iter) {
1392     CStateVar *sv = *iter;
1393     isVoid = sv->isVoid;
1394     if ((count != 0) && (isVoid != 1))
1395       op << ", ";
1396     if (sv->name != 0) 
1397       op << sv->name;
1398     if (sv->isVoid != 1)
1399       count++;
1400   }
1401
1402   op << ");\n";
1403 }
1404
1405 // boe = 1, if the next call is to begin construct
1406 // boe = 0, if the next call is to end a contruct
1407 void SdagConstruct::setNext(SdagConstruct *n, int boe)
1408 {
1409   switch(type) {
1410     case SSLIST:
1411       next = n;
1412       nextBeginOrEnd = boe;
1413       {
1414         if (constructs->empty())
1415           return;
1416
1417         list<SdagConstruct*>::iterator it = constructs->begin();
1418         SdagConstruct *cn = *it;
1419         ++it;
1420
1421         for(; it != constructs->end(); ++it) {
1422           if ((*it)->type == SCONNECT)
1423             continue;
1424
1425           cn->setNext(*it, 1);
1426           cn = *it;
1427         }
1428         cn->setNext(this, 0);
1429       }
1430       return;
1431     case SSDAGENTRY:
1432     case SOVERLAP:
1433     case SOLIST:
1434     case SFORALL:
1435     case SWHEN:
1436     case SFOR:
1437     case SWHILE:
1438     case SATOMIC:
1439     case SFORWARD:
1440     case SELSE:
1441       next = n;
1442       nextBeginOrEnd = boe;
1443       n = this; boe = 0; break;
1444     case SIF:
1445       next = n;
1446       nextBeginOrEnd = boe;
1447       if(con2 != 0)
1448         con2->setNext(n, boe);
1449       n = this;
1450       boe = 0;
1451       break;
1452     default:
1453       break;
1454   }
1455   SdagConstruct *cn;
1456   if (constructs != 0) {
1457     for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
1458          ++it) {
1459       (*it)->setNext(n, boe);
1460     }
1461   }
1462 }
1463
1464
1465 // for trace
1466
1467 void SdagConstruct::generateTrace()
1468 {
1469   char text[1024];
1470   switch(type) {
1471   case SATOMIC:
1472     if (traceName) {
1473       sprintf(text, "%s_%s", CParsedFile::className->charstar(), traceName->charstar());
1474       // remove blanks
1475       for (unsigned int i=0; i<strlen(text); i++)
1476         if (text[i]==' '||text[i]=='\t') text[i]='_';
1477     }
1478     else {
1479       sprintf(text, "%s%s", CParsedFile::className->charstar(), label->charstar());
1480     }
1481     traceName = new XStr(text);
1482     break;
1483   default:
1484     break;
1485   }
1486
1487   for_each(constructs->begin(), constructs->end(), mem_fun(&SdagConstruct::generateTrace));
1488   if (con1) con1->generateTrace();
1489   if (con2) con2->generateTrace();
1490   if (con3) con3->generateTrace();
1491 }
1492
1493 void SdagConstruct::generateTraceBeginCall(XStr& op)          // for trace
1494 {
1495   if(traceName)
1496     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, (" << "_sdag_idx_" << traceName << "()), CkMyPe(), 0, NULL); \n";
1497 }
1498
1499 void SdagConstruct::generateDummyBeginExecute(XStr& op)
1500 {
1501     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, _dummyEP, CkMyPe(), 0, NULL); \n";
1502 }
1503
1504 void SdagConstruct::generateTraceEndCall(XStr& op)          // for trace
1505 {
1506   op << "    " << "_TRACE_END_EXECUTE(); \n";
1507 }
1508
1509 void SdagConstruct::generateBeginExec(XStr& op, const char *name){
1510   op << "     " << "_TRACE_BG_BEGIN_EXECUTE_NOMSG(\""<<name<<"\",&_bgParentLog,1);\n"; 
1511 }
1512
1513 void SdagConstruct::generateEndExec(XStr& op){
1514   op << "     " << "_TRACE_BG_END_EXECUTE(0);\n";
1515 }
1516
1517 void SdagConstruct::generateBeginTime(XStr& op)
1518 {
1519   //Record begin time for tracing
1520   op << "    double __begintime = CkVTimer(); \n";
1521 }
1522
1523 void SdagConstruct::generateTlineEndCall(XStr& op)
1524 {
1525   //Trace this event
1526   op <<"    _TRACE_BG_TLINE_END(&_bgParentLog);\n";
1527 }
1528
1529 void SdagConstruct::generateEndSeq(XStr& op)
1530 {
1531   op <<  "    void* _bgParentLog = NULL;\n";
1532   op <<  "    CkElapse(0.01e-6);\n";
1533   //op<<  "    BgElapse(1e-6);\n";
1534   generateTlineEndCall(op);
1535   generateTraceEndCall(op);
1536   generateEndExec(op);
1537 }
1538
1539 void SdagConstruct::generateEventBracket(XStr& op, int eventType)
1540 {
1541   (void) eventType;
1542   //Trace this event
1543   op << "     _TRACE_BG_USER_EVENT_BRACKET(\"" << nameStr
1544      << "\", __begintime, CkVTimer(),&_bgParentLog); \n";
1545 }
1546
1547 void SdagConstruct::generateListEventBracket(XStr& op, int eventType)
1548 {
1549   (void) eventType;
1550   op << "    _TRACE_BGLIST_USER_EVENT_BRACKET(\"" << nameStr
1551      << "\",__begintime,CkVTimer(),&_bgParentLog, " << label
1552      << "_bgLogList);\n";
1553 }
1554
1555 void SdagConstruct::generateRegisterEp(XStr& defs)
1556 {
1557   if (traceName) {
1558     defs << "    (void)_sdag_idx_" << traceName << "();\n";
1559   }
1560
1561   for_each(constructs->begin(), constructs->end(),
1562            bind2nd(mem_fun(&SdagConstruct::generateRegisterEp), defs));
1563   if (con1) con1->generateRegisterEp(defs);
1564   if (con2) con2->generateRegisterEp(defs);
1565   if (con3) con3->generateRegisterEp(defs);
1566 }
1567
1568 void SdagConstruct::generateTraceEp(XStr& decls, XStr& defs, Chare* chare)
1569 {
1570   if (traceName) {
1571     XStr regName, idxName;
1572
1573     idxName << "_sdag_idx_" << traceName;
1574     regName << "_sdag_reg_" << traceName;
1575     generateSignature(decls, defs, chare, true, "int", &idxName, false, NULL);
1576     defs << "  static int epidx = " << regName << "();\n"
1577          << "  return epidx;\n";
1578     endMethod(defs);
1579
1580     generateSignature(decls, defs, chare, true, "int", &regName, false, NULL);
1581     defs << "  return CkRegisterEp(\""
1582          << traceName << "\", NULL, 0, " << chare->indexName() << "::__idx, 0"
1583          << ");\n";
1584     endMethod(defs);
1585   }
1586
1587   for (list<SdagConstruct*>::iterator it = constructs->begin(); it != constructs->end();
1588        ++it) {
1589     (*it)->generateTraceEp(decls, defs, chare);
1590   }
1591   if (con1) con1->generateTraceEp(decls, defs, chare);
1592   if (con2) con2->generateTraceEp(decls, defs, chare);
1593   if (con3) con3->generateTraceEp(decls, defs, chare);
1594 }
1595
1596
1597 void RemoveSdagComments(char *str)
1598 {
1599   char *ptr = str;
1600   while ((ptr = strstr(ptr, "//"))) {
1601     char *lend = strstr(ptr, "\n");
1602     if (lend==NULL) break;
1603     while (ptr != lend) *ptr++=' ';
1604   }
1605 }
1606
1607 }