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