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