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