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