fix the HACK when dealing with WhenTrigger data structure.
[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        op <<"       tr->args[" <<iArgs++ <<"] = (size_t)0xFF;\n";
836     }
837     else {
838       if (sv->isMsg == 1) {
839          op << "       tr->args["<<iArgs++ <<"] = (size_t) " <<sv->name->charstar()<<";\n";
840       }
841       else {
842          numParamsNeedingMarshalling++;
843          if (numParamsNeedingMarshalling == 1) {
844            op << "       int impl_off=0;\n";
845            paramIndex = iArgs;
846            iArgs++;
847          }
848       }
849       if (sv->arrayLength !=NULL) {
850          hasArray++;
851          if (hasArray == 1)
852            op<< "       int impl_arrstart=0;\n";
853          op <<"       int impl_off_"<<sv->name->charstar()<<", impl_cnt_"<<sv->name->charstar()<<";\n";
854          op <<"       impl_off_"<<sv->name->charstar()<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<sv->type->charstar()<<"));\n";
855          op <<"       impl_off+=(impl_cnt_"<<sv->name->charstar()<<"=sizeof("<<sv->type->charstar()<<")*("<<sv->arrayLength->charstar()<<"));\n";
856       }
857     }
858   }
859   if (numParamsNeedingMarshalling > 0) {
860      op << "       { \n";
861      op << "         PUP::sizer implP;\n";
862      for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
863        if (sv->arrayLength !=NULL)
864          op << "         implP|impl_off_" <<sv->name->charstar() <<";\n";
865        else if ((sv->isMsg != 1) && (sv->isVoid !=1)) 
866          op << "         implP|" <<sv->name->charstar() <<";\n";
867      }
868      if (hasArray > 0) {
869         op <<"         impl_arrstart=CK_ALIGN(implP.size(),16);\n";
870         op <<"         impl_off+=impl_arrstart;\n";
871      }
872      else {
873         op << "         impl_off+=implP.size();\n";
874      }
875      op << "       }\n";
876      op << "       CkMarshallMsg *impl_msg;\n";
877      op << "       impl_msg = CkAllocateMarshallMsg(impl_off,NULL);\n";
878      op << "       {\n";
879      op << "         PUP::toMem implP((void *)impl_msg->msgBuf);\n";
880      for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
881        if (sv->arrayLength !=NULL)
882           op << "         implP|impl_off_" <<sv->name->charstar() <<";\n";
883        else if ((sv->isMsg != 1) && (sv->isVoid != 1))  
884           op << "         implP|" <<sv->name->charstar() <<";\n";
885      }
886      op << "       }\n";
887      if (hasArray > 0) {
888         op <<"       char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
889         for(sv=stateVars->begin();!stateVars->end();sv=stateVars->next()) {
890            if (sv->arrayLength !=NULL)
891               op << "       memcpy(impl_buf+impl_off_"<<sv->name->charstar()<<
892                          ","<<sv->name->charstar()<<",impl_cnt_"<<sv->name->charstar()<<");\n";
893         }  
894      }
895   op << "       tr->args[" <<paramIndex <<"] = (size_t) impl_msg;\n";
896   }
897   int iRef=0, iAny=0;
898
899   el = elist;
900   while (el != NULL) {
901     e = el->entry;
902     if(e->intExpr == 0) {
903       op << "       tr->anyEntries[" << iAny++ << "] = " <<
904             e->entryPtr->entryNum << ";\n";
905     } else {
906       op << "       tr->entries[" << iRef << "] = " << 
907             e->entryPtr->entryNum << ";\n";
908       op << "       tr->refnums[" << iRef++ << "] = " <<
909             e->intExpr << ";\n";
910     }
911     el = el->next;
912   }
913
914 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
915   // max(current,merge) --> current
916   op << "       " << label->charstar()  << "_PathMergePoint.updateMax(currentlyExecutingPath); /* Critical Path Detection */ \n";
917   op << "       currentlyExecutingPath = " << label->charstar()  << "_PathMergePoint; /* Critical Path Detection */ \n";
918 #endif
919
920   op << "       __cDep->Register(tr);\n";
921   op << "       return 0;\n";
922   op << "    }\n";
923
924   // end actual code
925   op << "  }\n\n";
926
927   // trace
928   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
929   strcat(nameStr,"_end");
930
931   // end function
932   op << "  void " << label->charstar() << "_end(";
933   generatePrototype(op, *stateVarsChildren);
934   op << ") {\n";
935 #if CMK_BIGSIM_CHARM
936   generateBeginTime(op);
937   generateEventBracket(op,SWHEN_END);
938 #endif
939   // actual code here 
940   if(nextBeginOrEnd == 1)
941    op << "    " << next->label->charstar();
942   else 
943     op << "    " << next->label->charstar() << "_end";
944
945   op << "(";
946
947   generateCall(op, *stateVars); 
948   
949   op << ");\n";
950
951   el = elist;
952   while (el) {
953     e = el->entry;
954     if (e->param->isMessage() == 1) {
955       sv = e->stateVars->begin();
956       op << "    CmiFree(UsrToEnv(" << sv->name->charstar() << "));\n";
957     }
958
959     el = el->next;
960   }
961
962   // end actual code
963   op << "  }\n\n";
964 }
965
966 void SdagConstruct::generateWhile(XStr& op)
967 {
968   // inlined start function
969   op << "  void " << label->charstar() << "(";
970   generatePrototype(op, *stateVars);
971   op << ") {\n";
972   // actual code here 
973   op << "    if (" << con1->text->charstar() << ") {\n";
974   op << "      " << constructs->front()->label->charstar() << 
975         "(";
976   generateCall(op, *stateVarsChildren);
977   op << ");\n";
978   op << "    } else {\n";
979   if(nextBeginOrEnd == 1)
980    op << "      " << next->label->charstar() << "(";
981   else
982    op << "      " << next->label->charstar() << "_end(";
983   generateCall(op, *stateVars);
984   op << ");\n";
985   op << "    }\n";
986   // end actual code
987   op << "  }\n\n";
988   // inlined end function
989   op << "  void " << label->charstar() << "_end(";
990   generatePrototype(op, *stateVarsChildren);
991   op << ") {\n";
992   // actual code here 
993   op << "    if (" << con1->text->charstar() << ") {\n";
994   op << "      " << constructs->front()->label->charstar() <<
995         "(";
996   generateCall(op, *stateVarsChildren);
997   op << ");\n";
998   op << "    } else {\n";
999   if(nextBeginOrEnd == 1)
1000    op << "      " <<  next->label->charstar() << "(";
1001   else
1002    op << "      " << next->label->charstar() << "_end(";
1003   generateCall(op, *stateVars);
1004   op << ");\n";
1005   op << "    }\n";
1006   // end actual code
1007   op << "  }\n\n";
1008 }
1009
1010 void SdagConstruct::generateFor(XStr& op)
1011 {
1012   // inlined start function
1013   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1014   op << "  void " << label->charstar() << "(";
1015   generatePrototype(op, *stateVars);
1016   op << ") {\n";
1017 #if CMK_BIGSIM_CHARM
1018   // actual code here 
1019   generateBeginTime(op);
1020 #endif
1021   op << "    " << con1->text->charstar() << ";\n";
1022   //Record only the beginning for FOR
1023 #if CMK_BIGSIM_CHARM
1024   generateEventBracket(op,SFOR);
1025 #endif
1026   op << "    if (" << con2->text->charstar() << ") {\n";
1027   op << "      " << constructs->front()->label->charstar() <<
1028         "(";
1029   generateCall(op, *stateVarsChildren);
1030   op << ");\n";
1031   op << "    } else {\n";
1032   if(nextBeginOrEnd == 1)
1033    op << "      " << next->label->charstar() << "(";
1034   else
1035    op << "      " << next->label->charstar() << "_end(";
1036   generateCall(op, *stateVars);
1037   op << ");\n";
1038   op << "    }\n";
1039   // end actual code
1040   op << "  }\n";
1041   // inlined end function
1042   // trace
1043   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1044   strcat(nameStr,"_end");
1045   op << "  void " << label->charstar() << "_end(";
1046   generatePrototype(op, *stateVarsChildren);
1047   op << ") {\n";
1048 #if CMK_BIGSIM_CHARM
1049   generateBeginTime(op);
1050 #endif
1051   // actual code here 
1052   op << con3->text->charstar() << ";\n";
1053   op << "    if (" << con2->text->charstar() << ") {\n";
1054   op << "      " << constructs->front()->label->charstar() <<
1055         "(";
1056   generateCall(op, *stateVarsChildren);
1057   op << ");\n";
1058   op << "    } else {\n";
1059 #if CMK_BIGSIM_CHARM
1060   generateEventBracket(op,SFOR_END);
1061 #endif
1062   if(nextBeginOrEnd == 1)
1063    op << "      " << next->label->charstar() << "(";
1064   else
1065    op << "      " << next->label->charstar() << "_end(";
1066    generateCall(op, *stateVars);
1067   op << ");\n";
1068   op << "    }\n";
1069   // end actual code
1070   op << "  }\n";
1071 }
1072
1073 void SdagConstruct::generateIf(XStr& op)
1074 {
1075   // inlined start function
1076   strcpy(nameStr,label->charstar());
1077   op << "  void " << label->charstar() << "(";
1078   generatePrototype(op, *stateVars);
1079   op << ") {\n";
1080 #if CMK_BIGSIM_CHARM
1081   generateBeginTime(op);
1082   generateEventBracket(op,SIF);
1083 #endif
1084   // actual code here 
1085   op << "    if (" << con1->text->charstar() << ") {\n";
1086   op << "      " << constructs->front()->label->charstar() <<
1087         "(";
1088   generateCall(op, *stateVarsChildren);
1089   op << ");\n";
1090   op << "    } else {\n";
1091   if (con2 != 0) {
1092     op << "      " << con2->label->charstar() << "(";
1093     generateCall(op, *stateVarsChildren);
1094     op << ");\n";
1095   } else {
1096     op << "      " << label->charstar() << "_end(";
1097     generateCall(op, *stateVarsChildren);
1098     op << ");\n";
1099   }
1100   op << "    }\n";
1101   // end actual code
1102   op << "  }\n\n";
1103   // inlined end function
1104   strcpy(nameStr,label->charstar());
1105   strcat(nameStr,"_end");
1106   op << "  void " << label->charstar() << "_end(";
1107   generatePrototype(op, *stateVarsChildren);
1108   op << ") {\n";
1109 #if CMK_BIGSIM_CHARM
1110   generateBeginTime(op);
1111   generateEventBracket(op,SIF_END);
1112 #endif
1113   // actual code here 
1114   if(nextBeginOrEnd == 1)
1115    op << "      " << next->label->charstar() << "(";
1116   else
1117    op << "      " << next->label->charstar() << "_end(";
1118   generateCall(op, *stateVars);
1119   op << ");\n";
1120   // end actual code
1121   op << "  }\n\n";
1122 }
1123
1124 void SdagConstruct::generateElse(XStr& op)
1125 {
1126   // inlined start function
1127   strcpy(nameStr,label->charstar());
1128   op << "  void " << label->charstar() << "(";
1129   generatePrototype(op, *stateVars);
1130   op << ") {\n";
1131   // trace
1132   generateBeginTime(op);
1133   generateEventBracket(op,SELSE);
1134   // actual code here 
1135   op << "    " << constructs->front()->label->charstar() << 
1136         "(";
1137   generateCall(op, *stateVarsChildren);
1138   op << ");\n";
1139   // end actual code
1140   op << "  }\n\n";
1141   // inlined end function
1142   // trace
1143   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1144   strcat(nameStr,"_end");
1145   op << "  void " << label->charstar() << "_end(";
1146   generatePrototype(op, *stateVarsChildren);
1147   op << ") {\n";
1148 #if CMK_BIGSIM_CHARM
1149   generateBeginTime(op);
1150   generateEventBracket(op,SELSE_END);
1151 #endif
1152   // actual code here 
1153   if(nextBeginOrEnd == 1)
1154    op << "      " << next->label->charstar() << "(";
1155   else
1156    op << "      " << next->label->charstar() << "_end(";
1157   generateCall(op, *stateVars);
1158   op << ");\n";
1159   // end actual code
1160   op << "  }\n\n";
1161 }
1162
1163 void SdagConstruct::generateForall(XStr& op)
1164 {
1165   // inlined start function
1166   op << "  void " << label->charstar() << "(";
1167   generatePrototype(op, *stateVars);
1168   op << ") {\n";
1169   // actual code here 
1170   op << "    int __first = (" << con2->text->charstar() <<
1171         "), __last = (" << con3->text->charstar() << 
1172         "), __stride = (" << con4->text->charstar() << ");\n";
1173   op << "    if (__first > __last) {\n";
1174   op << "      int __tmp=__first; __first=__last; __last=__tmp;\n";
1175   op << "      __stride = -__stride;\n";
1176   op << "    }\n";
1177   op << "    CCounter *" << counter->charstar() << 
1178         " = new CCounter(__first,__last,__stride);\n"; 
1179   op << "    for(int " << con1->text->charstar() << 
1180         "=__first;" << con1->text->charstar() <<
1181         "<=__last;" << con1->text->charstar() << "+=__stride) {\n";
1182   op << "      " << constructs->front()->label->charstar() <<
1183         "(";
1184   generateCall(op, *stateVarsChildren);
1185   op << ");\n";
1186   op << "    }\n";
1187   // end actual code
1188   op << "  }\n\n";
1189   // inlined end function
1190   op << "  void " << label->charstar() << "_end(";
1191   generatePrototype(op, *stateVarsChildren);
1192   op << ") {\n";
1193   // actual code here 
1194   op << "    " << counter->charstar() << "->decrement(); /* DECREMENT 1 */ \n";
1195   op << "    if (" << counter->charstar() << "->isDone()) {\n";
1196   op << "      delete " << counter->charstar() << ";\n";
1197   if(nextBeginOrEnd == 1)
1198    op << "      " << next->label->charstar() << "(";
1199   else
1200    op << "      " << next->label->charstar() << "_end(";
1201   generateCall(op, *stateVars);
1202   op << ");\n";
1203   // end actual code
1204   op << "    }\n  }\n\n";
1205 }
1206
1207 void SdagConstruct::generateOlist(XStr& op)
1208 {
1209   SdagConstruct *cn;
1210   // inlined start function
1211   op << "  void " << label->charstar() << "(";
1212   generatePrototype(op, *stateVars);
1213   op << ") {\n";
1214   // actual code here 
1215   op << "    CCounter *" << counter->charstar() << "= new CCounter(" <<
1216         constructs->length() << ");\n";
1217   for(cn=constructs->begin(); 
1218                      !constructs->end(); cn=constructs->next()) {
1219     op << "    " << cn->label->charstar() << "(";
1220     generateCall(op, *stateVarsChildren);
1221     op << ");\n";
1222   }
1223   // end actual code
1224   op << "  }\n";
1225
1226   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1227   strcat(nameStr,"_end");
1228 #if CMK_BIGSIM_CHARM
1229   op << "  CkVec<void*> " <<label->charstar() << "_bgLogList;\n";
1230 #endif
1231
1232   // inlined end function
1233   op << "  void " << label->charstar() << "_end(";
1234   generatePrototype(op, *stateVarsChildren);
1235   op << ") {\n";
1236 #if CMK_BIGSIM_CHARM
1237   generateBeginTime(op);
1238   op << "    " <<label->charstar() << "_bgLogList.insertAtEnd(_bgParentLog);\n";
1239 #endif
1240   // actual code here 
1241   //Accumulate all the bgParent pointers that the calling when_end functions give
1242   op << "    " << counter->charstar() << "->decrement();\n";
1243  
1244 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1245  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";
1246 #endif
1247
1248   op << "    if (" << counter->charstar() << "->isDone()) {\n";
1249
1250 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
1251   op << "      currentlyExecutingPath = olist_" << counter->charstar() << "_PathMergePoint; /* Critical Path Detection */ \n";
1252   op << "      olist_" << counter->charstar() << "_PathMergePoint.reset(); /* Critical Path Detection */ \n";
1253 #endif
1254
1255   op << "      delete " << counter->charstar() << ";\n";
1256
1257 #if CMK_BIGSIM_CHARM
1258   generateListEventBracket(op,SOLIST_END);
1259   op << "       "<< label->charstar() <<"_bgLogList.length()=0;\n";
1260 #endif
1261
1262   if(nextBeginOrEnd == 1)
1263    op << "      " << next->label->charstar() << "(";
1264   else
1265    op << "      " << next->label->charstar() << "_end(";
1266   generateCall(op, *stateVars);
1267   op << ");\n";
1268   // end actual code
1269   op << "    }\n";
1270   op << "  }\n";
1271 }
1272
1273 void SdagConstruct::generateOverlap(XStr& op)
1274 {
1275   // inlined start function
1276   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1277   op << "  void " << label->charstar() << "(";
1278   generatePrototype(op, *stateVars);
1279   op << ") {\n";
1280 #if CMK_BIGSIM_CHARM
1281   generateBeginTime(op);
1282   generateEventBracket(op,SOVERLAP);
1283 #endif
1284   // actual code here 
1285   op << "    " << constructs->front()->label->charstar() <<
1286         "(";
1287   generateCall(op, *stateVarsChildren);
1288   op << ");\n";
1289   // end actual code
1290   op << "  }\n";
1291   // trace
1292   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1293   strcat(nameStr,"_end");
1294   // inlined end function
1295   op << "  void " << label->charstar() << "_end(";
1296   generatePrototype(op, *stateVarsChildren);
1297   op << ") {\n";
1298 #if CMK_BIGSIM_CHARM
1299   generateBeginTime(op);
1300   generateEventBracket(op,SOVERLAP_END);
1301 #endif
1302   // actual code here 
1303   if(nextBeginOrEnd == 1)
1304    op << "    " << next->label->charstar() << "(";
1305   else
1306    op << "    " << next->label->charstar() << "_end(";
1307   generateCall(op, *stateVars);
1308   op << ");\n";
1309   // end actual code
1310   op << "  }\n";
1311 }
1312
1313 void SdagConstruct::generateSlist(XStr& op)
1314 {
1315   // inlined start function
1316   op << "  void " << label->charstar() << "(";
1317   generatePrototype(op, *stateVars);
1318   op << ") {\n";
1319   // actual code here 
1320   op << "    " << constructs->front()->label->charstar() <<
1321         "(";
1322   generateCall(op, *stateVarsChildren);
1323   op << ");\n";
1324   // end actual code
1325   op << "  }\n";
1326   // inlined end function
1327   op << "  void " << label->charstar() << "_end(";
1328   generatePrototype(op, *stateVarsChildren); 
1329   op << ") {\n";
1330   // actual code here 
1331   if(nextBeginOrEnd == 1)
1332    op << "    " << next->label->charstar() << "(";
1333   else
1334    op << "    " << next->label->charstar() << "_end(";
1335   generateCall(op, *stateVars);
1336   op << ");\n";
1337   // end actual code
1338   op << "  }\n";
1339 }
1340
1341 void SdagConstruct::generateSdagEntry(XStr& op)
1342 {
1343   // header file
1344   op << "public:\n";
1345   op << "  void " << con1->text->charstar() << "(";
1346   generatePrototype(op, *stateVars);
1347   op << ") {\n";
1348   SdagConstruct *sc;
1349   SdagConstruct *sc1;
1350   for(sc =publishesList->begin(); !publishesList->end(); sc=publishesList->next()) {
1351      for(sc1=sc->constructs->begin(); !sc->constructs->end(); sc1 = sc->constructs->next())
1352         op << "    _connect_" << sc1->text->charstar() <<"();\n";
1353   }
1354 #if CMK_BIGSIM_CHARM
1355   generateEndSeq(op);
1356 #endif
1357   // actual code here 
1358   op << "    " << constructs->front()->label->charstar() <<
1359         "(";
1360   generateCall(op, *stateVarsChildren);
1361   op << ");\n";
1362 #if CMK_BIGSIM_CHARM
1363   generateTlineEndCall(op);
1364   generateBeginExec(op, "spaceholder");
1365 #endif
1366   generateDummyBeginExecute(op);
1367   // end actual code
1368   op << "  }\n\n";
1369   op << "private:\n";
1370   op << "  void " << con1->text->charstar() << "_end(";
1371 #if CMK_BIGSIM_CHARM
1372   generatePrototype(op, *stateVarsChildren);
1373 #else
1374   generatePrototype(op, *stateVars);
1375 #endif
1376   op << ") {\n";
1377   op << "  }\n\n";
1378 }
1379
1380 void SdagConstruct::generateAtomic(XStr& op)
1381
1382   sprintf(nameStr,"%s%s", CParsedFile::className->charstar(),label->charstar());
1383   op << "  void " << label->charstar() << "(";
1384   generatePrototype(op, *stateVars);
1385   op << ") {\n";
1386 #if CMK_BIGSIM_CHARM
1387   generateBeginExec(op, nameStr);
1388 #endif
1389   generateTraceBeginCall(op);
1390   op << "    " << text->charstar() << "\n";
1391   // trace
1392   generateTraceEndCall(op);
1393 #if CMK_BIGSIM_CHARM
1394   generateEndExec(op);
1395 #endif
1396   if(nextBeginOrEnd == 1)
1397     op << "    " << next->label->charstar() << "(";
1398   else
1399     op << "    " << next->label->charstar() << "_end(";
1400   generateCall(op, *stateVars);
1401   op << ");\n";
1402   op << "  }\n\n";
1403 }
1404
1405 void SdagConstruct::generatePrototype(XStr& op, ParamList *list)
1406 {
1407    ParamList *pl = list;
1408    int count = 0;
1409    int i, numStars;
1410    if (pl->isVoid() == 1) {
1411      op << "void"; 
1412    }
1413    else if (pl->isMessage() == 1){
1414      op << pl->getBaseName() <<" *" <<pl->getGivenName() ;
1415    }
1416    else {
1417      while(pl != NULL) {
1418        if (count > 0)
1419           op <<", ";
1420        if (pl->isPointer() == 1) {
1421          op <<pl->getBaseName(); 
1422          numStars = pl->getNumStars();
1423          for(i=0; i< numStars; i++)
1424            op <<"*";
1425          op <<" "<<pl->getGivenName();
1426        }
1427        else if (pl->isReference() == 1) 
1428          op <<pl->getBaseName() <<"& " <<pl->getGivenName();
1429        else if (pl->isArray() == 1) 
1430          op <<pl->getBaseName() <<"* " <<pl->getGivenName();
1431        else if ((pl->isBuiltin() == 1) || (pl->isNamed() == 1))
1432          op <<pl->getBaseName() <<" " <<pl->getGivenName();
1433        pl = pl->next;
1434        count++;
1435      }
1436    }
1437 }
1438
1439
1440 void SdagConstruct::generatePrototype(XStr& op, TList<CStateVar*>& list)
1441 {
1442   CStateVar *sv;
1443   int isVoid;
1444   int count;
1445   count = 0;
1446   for(sv=list.begin(); !list.end(); ) {
1447     isVoid = sv->isVoid;
1448     if ((count != 0) && (isVoid != 1))
1449        op << ", ";
1450     if (sv->isVoid != 1) {
1451       if (sv->type != 0) 
1452          op <<sv->type->charstar() <<" ";
1453       if (sv->byRef != 0)
1454          op <<" &";
1455       if (sv->arrayLength != NULL) 
1456          op <<"*";
1457       else if (sv->numPtrs != 0) {
1458         for (int i=0; i<sv->numPtrs; i++) 
1459           op <<"*";
1460          op <<" ";
1461       }
1462       if (sv->name != 0)
1463          op <<sv->name->charstar();
1464     }
1465     if (sv->isVoid != 1)
1466        count++;
1467     sv = list.next();
1468   }
1469 }
1470
1471 void SdagConstruct::generateCall(XStr& op, TList<CStateVar*>& list) {
1472   CStateVar *sv;
1473   int isVoid;
1474   int count;
1475   count = 0;
1476   for(sv=list.begin(); !list.end(); ) {
1477      isVoid = sv->isVoid;
1478      if ((count != 0) && (isVoid != 1))
1479         op << ", ";
1480      if (sv->name != 0) 
1481        op << sv->name->charstar();
1482     if (sv->isVoid != 1)
1483        count++;
1484     sv = list.next();
1485   }
1486 }
1487
1488 // boe = 1, if the next call is to begin construct
1489 // boe = 0, if the next call is to end a contruct
1490 void SdagConstruct::setNext(SdagConstruct *n, int boe)
1491 {
1492   switch(type) {
1493     case SSLIST:
1494       next = n;
1495       nextBeginOrEnd = boe;
1496       {
1497         SdagConstruct *cn=constructs->begin();
1498         if (cn==0) // empty slist
1499           return;
1500
1501         for(SdagConstruct *nextNode=constructs->next(); nextNode != 0; nextNode = constructs->next()) {
1502           if (nextNode->type == SCONNECT)
1503             continue;
1504
1505           cn->setNext(nextNode, 1);
1506           cn = nextNode;
1507         }
1508         cn->setNext(this, 0);
1509       }
1510       return;
1511     case SSDAGENTRY:
1512     case SOVERLAP:
1513     case SOLIST:
1514     case SFORALL:
1515     case SWHEN:
1516     case SFOR:
1517     case SWHILE:
1518     case SATOMIC:
1519     case SFORWARD:
1520     case SELSE:
1521       next = n;
1522       nextBeginOrEnd = boe;
1523       n = this; boe = 0; break;
1524     case SIF:
1525       next = n;
1526       nextBeginOrEnd = boe;
1527       if(con2 != 0)
1528         con2->setNext(n, boe);
1529       n = this;
1530       boe = 0;
1531       break;
1532     default:
1533       break;
1534   }
1535   SdagConstruct *cn;
1536   if (constructs != 0) {
1537     for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1538       cn->setNext(n, boe);
1539     }
1540   }
1541 }
1542
1543
1544 // for trace
1545
1546 void SdagConstruct::generateTrace()
1547 {
1548   char text[1024];
1549   switch(type) {
1550   case SATOMIC:
1551     if (traceName) {
1552       sprintf(text, "%s_%s", CParsedFile::className->charstar(), traceName->charstar());
1553       // remove blanks
1554       for (unsigned int i=0; i<strlen(text); i++)
1555         if (text[i]==' '||text[i]=='\t') text[i]='_';
1556     }
1557     else {
1558       sprintf(text, "%s%s", CParsedFile::className->charstar(), label->charstar());
1559     }
1560     traceName = new XStr(text);
1561     break;
1562   default:
1563     break;
1564   }
1565
1566   SdagConstruct *cn;
1567   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1568     cn->generateTrace();
1569   }
1570   if (con1) con1->generateTrace();
1571   if (con2) con2->generateTrace();
1572   if (con3) con3->generateTrace();
1573 }
1574
1575 void SdagConstruct::generateTraceBeginCall(XStr& op)          // for trace
1576 {
1577   if(traceName)
1578     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, " << "__idx_" << traceName->charstar() << ", CkMyPe(), 0, NULL); \n";
1579 }
1580
1581 void SdagConstruct::generateDummyBeginExecute(XStr& op)
1582 {
1583     op << "    " << "_TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, _dummyEP, CkMyPe(), 0, NULL); \n";
1584 }
1585
1586 void SdagConstruct::generateTraceEndCall(XStr& op)          // for trace
1587 {
1588   op << "    " << "_TRACE_END_EXECUTE(); \n";
1589 }
1590
1591 void SdagConstruct::generateBeginExec(XStr& op, const char *name){
1592   op << "     " << "_TRACE_BG_BEGIN_EXECUTE_NOMSG(\""<<name<<"\",&_bgParentLog,1);\n"; 
1593 }
1594
1595 void SdagConstruct::generateEndExec(XStr& op){
1596   op << "     " << "_TRACE_BG_END_EXECUTE(0);\n";
1597 }
1598
1599 void SdagConstruct::generateBeginTime(XStr& op)
1600 {
1601   //Record begin time for tracing
1602   op << "    double __begintime = CkVTimer(); \n";
1603 }
1604
1605 void SdagConstruct::generateTlineEndCall(XStr& op)
1606 {
1607   //Trace this event
1608   op <<"    _TRACE_BG_TLINE_END(&_bgParentLog);\n";
1609 }
1610
1611 void SdagConstruct::generateEndSeq(XStr& op)
1612 {
1613   op <<  "    void* _bgParentLog = NULL;\n";
1614   op <<  "    CkElapse(0.01e-6);\n";
1615   //op<<  "    BgElapse(1e-6);\n";
1616   generateTlineEndCall(op);
1617   generateTraceEndCall(op);
1618   generateEndExec(op);
1619 }
1620
1621 void SdagConstruct::generateEventBracket(XStr& op, int eventType)
1622 {
1623   (void) eventType;
1624   //Trace this event
1625   op << "     _TRACE_BG_USER_EVENT_BRACKET(\"" << nameStr
1626      << "\", __begintime, CkVTimer(),&_bgParentLog); \n";
1627 }
1628
1629 void SdagConstruct::generateListEventBracket(XStr& op, int eventType)
1630 {
1631   (void) eventType;
1632   op << "    _TRACE_BGLIST_USER_EVENT_BRACKET(\"" << nameStr
1633      << "\",__begintime,CkVTimer(),&_bgParentLog, " << label->charstar()
1634      << "_bgLogList);\n";
1635 }
1636
1637 void SdagConstruct::generateRegisterEp(XStr& op)          // for trace
1638 {
1639   if (traceName) {
1640     op << "    __idx_" << traceName->charstar()
1641        << " = CkRegisterEp(\"" << traceName->charstar()
1642        << "(void)\", NULL, 0, CkIndex_" << CParsedFile::className->charstar()
1643        << "::__idx, 0);\n";
1644   }
1645
1646   SdagConstruct *cn;
1647   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1648     cn->generateRegisterEp(op);
1649   }
1650   if (con1) con1->generateRegisterEp(op);
1651   if (con2) con2->generateRegisterEp(op);
1652   if (con3) con3->generateRegisterEp(op);
1653 }
1654
1655 void SdagConstruct::generateTraceEpDecl(XStr& op)          // for trace
1656 {
1657   if (traceName) {
1658     op << "  static int __idx_" << traceName->charstar() << ";\n"; 
1659   }
1660   SdagConstruct *cn;
1661   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1662     cn->generateTraceEpDecl(op);
1663   }
1664   if (con1) con1->generateTraceEpDecl(op);
1665   if (con2) con2->generateTraceEpDecl(op);
1666   if (con3) con3->generateTraceEpDecl(op);
1667 }
1668
1669
1670 void SdagConstruct::generateTraceEpDef(XStr& op)          // for trace
1671 {
1672   if (traceName) {
1673     op << "  int " << CParsedFile::className->charstar()
1674        << "::__idx_" << traceName->charstar() << "=0;\\\n";
1675   }
1676   SdagConstruct *cn;
1677   for(cn=constructs->begin(); !constructs->end(); cn=constructs->next()) {
1678     cn->generateTraceEpDef(op);
1679   }
1680   if (con1) con1->generateTraceEpDef(op);
1681   if (con2) con2->generateTraceEpDef(op);
1682   if (con3) con3->generateTraceEpDef(op);
1683 }
1684
1685
1686 void RemoveSdagComments(char *str)
1687 {
1688   char *ptr = str;
1689   while ((ptr = strstr(ptr, "//"))) {
1690     char *lend = strstr(ptr, "\n");
1691     if (lend==NULL) break;
1692     while (ptr != lend) *ptr++=' ';
1693   }
1694 }
1695
1696 }