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