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