fix the HACK when dealing with WhenTrigger data structure.
[charm.git] / src / xlat-i / sdag / CEntry.C
1 #include "CEntry.h"
2 #include "xi-symbol.h"
3
4 namespace xi {
5
6 void CEntry::generateDeps(XStr& op)
7 {
8   SdagConstruct *cn;
9   for(cn=whenList.begin(); !whenList.end(); cn=whenList.next()) {
10     op << "    __cDep->addDepends("<<cn->nodeNum<<","<<entryNum<<");\n";
11   }
12 }
13
14 void CEntry::generateCode(XStr& op)
15 {
16   CStateVar *sv;
17   int i;
18   int isVoid = 1;
19   int lastWasVoid;
20   sv = (CStateVar *)myParameters->begin();
21   i = 0;
22   op << "  void " << *entry <<"(";
23   for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
24     isVoid = sv->isVoid;
25     if ((sv->isMsg != 1) && (sv->isVoid != 1)) {
26        if (i >0)
27          op <<", ";
28        op << sv->type->charstar() << " ";
29        if (sv->arrayLength != 0)
30          op << "*";
31        else if (sv->byRef != 0) {
32          op <<"&";
33        }
34        if (sv->numPtrs != 0) {
35          for(int k = 0; k< sv->numPtrs; k++)
36             op<<"*";
37        }
38        if (sv->name != 0)
39          op << sv->name->charstar();
40     }
41     else if (sv->isVoid != 1){
42       if (i < 1) 
43          op << sv->type->charstar() <<" *"<<sv->name->charstar() <<"_msg";
44       else
45          printf("ERROR: A message must be the only parameter in an entry function\n");
46     }
47     else
48       op <<"void";
49   }
50   op <<  ") {\n";
51   op << "    CWhenTrigger *tr;\n";
52   op<<  "    void* _bgParentLog = NULL;\n";
53 #if CMK_BIGSIM_CHARM
54   op<<  "    CkElapse(0.01e-6);\n";
55   SdagConstruct::generateTlineEndCall(op);
56 #endif
57
58   op << "    CMsgBuffer* cmsgbuf;\n";
59
60   int hasArrays = 0;
61   int paramMarshalling = 0;
62   int count = 0;
63   sv = (CStateVar *)myParameters->begin();
64   i = 0;
65   if (isVoid == 1) {
66      op << "   __cDep->bufferMessage("<<entryNum<<", (void *) CkAllocSysMsg(), 0);\n";
67      op << "    tr = __cDep->getTrigger("<<entryNum<<", 0);\n";
68   }
69   else {
70      for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
71         if ((i==0) && (sv->isMsg !=1)) {
72            op <<"    int impl_off=0; int impl_arrstart=0;\n";
73            paramMarshalling = 1;
74         }
75         if(sv->arrayLength != 0) {
76            hasArrays++ ;
77            if (sv->numPtrs > 0)
78               printf("ERROR: can't pass pointers across processors \n -- Indicate the array length with []'s, or pass a reference\n");
79            op <<"    int impl_off_"<<sv->name->charstar()<<", impl_cnt_"<<sv->name->charstar()<<";\n";
80            op <<"    impl_off_"<<sv->name->charstar()<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<sv->type->charstar()<<"));\n";
81            op <<"    impl_off+=(impl_cnt_"<<sv->name->charstar()<<"=sizeof("<<sv->type->charstar()<<")*("<<sv->arrayLength->charstar()<<"));\n";
82         }
83         if (paramMarshalling ==0) {
84            op << "    CmiReference(UsrToEnv(" << sv->name->charstar() << "_msg));\n";
85            if(refNumNeeded) {
86               op << "    int refnum = CkGetRefNum(" <<sv->name->charstar() <<"_msg);\n";
87               op << "    cmsgbuf = __cDep->bufferMessage("<<entryNum<<",(void *) "<<sv->name->charstar() <<"_msg , (void *) _bgParentLog, refnum);\n";
88               op << "    tr = __cDep->getTrigger("<<entryNum<<", refnum);\n";
89            } else {
90               op << "    cmsgbuf = __cDep->bufferMessage("<<entryNum<<", (void *) "<<sv->name->charstar() <<"_msg,  (void *) _bgParentLog, 0);\n";
91               op << "    tr = __cDep->getTrigger("<<entryNum<<", 0);\n";
92            } 
93         }
94         count++;
95      }
96    }
97    if (paramMarshalling == 1) {
98      op <<"    {\n";
99      op <<"      PUP::sizer implP1;\n";
100      sv = (CStateVar *)myParameters->begin();
101      i = 0;
102  
103      for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
104         if(sv->arrayLength != 0)
105            op <<"      implP1|impl_off_"<<sv->name->charstar()<<";\n";
106         else if(sv->byRef != 0)
107            op <<"      implP1|(" <<sv->type->charstar() <<" &)" <<sv->name->charstar() <<";\n";
108         else   
109            op <<"      implP1|"<<sv->name->charstar()<<";\n";
110      }
111  
112      if (hasArrays > 0)
113      { //round up pup'd data length--that's the first array
114         op <<"      impl_arrstart=CK_ALIGN(implP1.size(),16);\n";
115         op <<"      impl_off+=impl_arrstart;\n";
116      }
117      else  //No arrays--no padding
118         op <<"      impl_off+=implP1.size();\n";
119   
120      op <<"    }\n";
121
122      //Now that we know the size, allocate the packing buffer
123      op <<"    CkMarshallMsg *impl_msg1=CkAllocateMarshallMsg(impl_off,NULL);\n";
124      //Second pass: write the data
125      op <<"    {\n";
126      op <<"      PUP::toMem implP1((void *)impl_msg1->msgBuf);\n";
127      sv = (CStateVar *)myParameters->begin();
128      i = 0;
129  
130      for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
131         if(sv->arrayLength != 0)
132            op <<"      implP1|impl_off_"<<sv->name->charstar()<<";\n";
133         else if(sv->byRef != 0)
134            op <<"      implP1|(" <<sv->type->charstar() <<" &)" <<sv->name->charstar() <<";\n";
135         else   
136            op <<"      implP1|"<<sv->name->charstar()<<";\n";
137      }
138      op <<"    }\n";
139      if (hasArrays > 0)
140      { //Marshall each array
141        op <<"    char *impl_buf1=impl_msg1->msgBuf+impl_arrstart;\n";
142        sv = (CStateVar *)myParameters->begin();
143        i = 0;
144        for(; i<(myParameters->length());i++, sv=(CStateVar *)myParameters->next()) {
145          if(sv->arrayLength != 0) {
146            op <<"    memcpy(impl_buf1+impl_off_"<<sv->name->charstar()<<","<<sv->name->charstar()<<",impl_cnt_"<<sv->name->charstar()<<");\n";
147          }
148        }
149      }
150      
151      if(refNumNeeded) {
152      // When a reference number is needed and there are parameters that need marshalling 
153      // (in other words the parameters of the entry method are not messages) 
154      // then the first parameter of the entry method is an integer that specifies the 
155      // reference number
156           sv = (CStateVar *)myParameters->begin();
157           op << "   cmsgbuf = __cDep->bufferMessage("<<entryNum<<",(void *) impl_msg1, (void*) _bgParentLog,"<<sv->name->charstar()<<");\n";
158           op << "    tr = __cDep->getTrigger("<<entryNum<<","<<sv->name->charstar()<<");\n"; 
159      } else {
160        op << "    cmsgbuf = __cDep->bufferMessage("<<entryNum<<", (void *) impl_msg1, (void*) _bgParentLog, 0);\n";
161        op << "    tr = __cDep->getTrigger("<<entryNum<<", 0);\n";
162      }
163    }
164
165   op << "    if (tr == 0)\n";
166   op << "      return;\n"; 
167
168   SdagConstruct::generateTraceEndCall(op);
169 #if CMK_BIGSIM_CHARM
170   SdagConstruct::generateEndExec(op);
171 #endif
172
173   XStr *whenParams; 
174   int iArgs = 0;
175   if(whenList.length() == 1) {
176     SdagConstruct *cn;
177     cn = whenList.begin();
178     whenParams = new XStr("");
179     sv = (CStateVar *)cn->stateVars->begin();
180     i = 0; iArgs = 0;
181     lastWasVoid = 0;
182     sv = (CStateVar *)cn->stateVars->begin();
183     i = 0;
184     paramMarshalling = 0;
185     lastWasVoid = 0;
186
187 #if CMK_BIGSIM_CHARM
188     op <<"    cmsgbuf->bgLog2 = (void*)tr->args[1];\n";
189     //op << "    " << cn->label->charstar() << "(";    
190 #endif
191
192     for( i=0; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
193       if ((sv->isMsg == 0) && (paramMarshalling == 0) && (sv->isVoid ==0)){
194           paramMarshalling =1;
195           op << "    CkMarshallMsg *impl_msg = (CkMarshallMsg *) tr->args[" <<iArgs <<"];\n"; 
196           op << "    char *impl_buf=((CkMarshallMsg *)impl_msg)->msgBuf;\n";
197           op << "    PUP::fromMem implP(impl_buf);\n";
198           iArgs++;
199       }
200       if (sv->isMsg == 1) {
201           if((i!=0) && (lastWasVoid == 0))
202              whenParams->append(", ");
203 #if CMK_BIGSIM_CHARM
204           if(i==1){   
205             whenParams->append("NULL");
206             lastWasVoid=0;
207             iArgs++;
208             continue;
209           }
210 #endif
211           whenParams->append("(");
212           whenParams->append(sv->type->charstar());
213           whenParams->append(" *) tr->args[");
214           *whenParams<<iArgs;
215           whenParams->append("]");
216           iArgs++;
217        }
218        else if (sv->isVoid == 1) 
219            // op <<"    CkFreeSysMsg((void  *)tr->args[" <<iArgs++ <<"]);\n";
220            op <<"    tr->args[" <<iArgs++ <<"] = 0;\n";
221        else if ((sv->isMsg == 0) && (sv->isVoid == 0)) {
222           if((i > 0) &&(lastWasVoid == 0)) 
223              whenParams->append(", ");
224           whenParams->append(*(sv->name));
225           if (sv->arrayLength != 0) 
226              op<<"    int impl_off_"<<sv->name->charstar()<<"; implP|impl_off_"<<sv->name->charstar()<<";\n";
227           else
228              op<<"    "<<sv->type->charstar()<<" "<<sv->name->charstar()<<"; implP|"<<sv->name->charstar()<<";\n";
229        }
230        lastWasVoid = sv->isVoid;
231       
232     } 
233     if (paramMarshalling == 1) 
234         op<<"     impl_buf+=CK_ALIGN(implP.size(),16);\n";
235     i = 0;
236     sv = (CStateVar *)cn->stateVars->begin();
237     for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
238        if (sv->arrayLength != 0) 
239           op<<"    "<<sv->type->charstar()<<" *"<<sv->name->charstar()<<"=("<<sv->type->charstar()<<" *)(impl_buf+impl_off_"<<sv->name->charstar()<<");\n";
240     }
241
242     if (paramMarshalling == 1) 
243        op << "    delete (CkMarshallMsg *)impl_msg;\n";
244     op << "    " << cn->label->charstar() << "(" << whenParams->charstar();
245     op << ");\n";
246   
247     op << "    delete tr;\n";
248 #if CMK_BIGSIM_CHARM
249     cn->generateTlineEndCall(op);
250     cn->generateBeginExec(op, "sdagholder");
251 #endif
252     cn->generateDummyBeginExecute(op);
253     op << "    return;\n";
254   }
255   else {   
256     op << "    switch(tr->whenID) {\n";
257     for(SdagConstruct *cn=whenList.begin(); !whenList.end(); cn=whenList.next())
258     {
259       whenParams = new XStr("");
260       i = 0; iArgs = 0;
261       op << "      case " << cn->nodeNum << ":\n";
262       op << "      {\n";
263       
264 #if CMK_BIGSIM_CHARM
265       // bgLog2 stores the parent dependence of when, e.g. for, olist
266       op <<"  cmsgbuf->bgLog2 = (void*)tr->args[1];\n";  
267 #endif
268       sv = (CStateVar *)cn->stateVars->begin();
269       i = 0;
270       paramMarshalling = 0;
271       lastWasVoid = 0;
272
273       for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
274          if ((sv->isMsg == 0) && (paramMarshalling == 0) && (sv->isVoid ==0)){
275             paramMarshalling =1;
276             op << "        CkMarshallMsg *impl_msg" <<cn->nodeNum <<" = (CkMarshallMsg *) tr->args["<<iArgs++<<"];\n"; 
277             op << "        char *impl_buf" <<cn->nodeNum <<"=((CkMarshallMsg *)impl_msg" <<cn->nodeNum <<")->msgBuf;\n";
278             op << "        PUP::fromMem implP" <<cn->nodeNum <<"(impl_buf" <<cn->nodeNum <<");\n";
279          }
280          if (sv->isMsg == 1) {
281             if((i!=0) && (lastWasVoid == 0))
282               whenParams->append(", ");
283 #if CMK_BIGSIM_CHARM
284             if(i==1) {
285                whenParams->append(" NULL ");
286                lastWasVoid=0;
287                // skip this arg which is supposed to be _bgParentLog
288                iArgs++;
289                continue;
290             }
291 #endif
292             whenParams->append("(");
293             whenParams->append(sv->type->charstar());
294             whenParams->append(" *) tr->args[");
295             *whenParams<<iArgs;
296             whenParams->append("]");
297             iArgs++;
298          }
299          else if (sv->isVoid == 1) 
300             // op <<"    CkFreeSysMsg((void  *)tr->args[" <<iArgs++ <<"]);\n";
301             op <<"    tr->args[" <<iArgs++ <<"] = 0;\n";
302          else if ((sv->isMsg == 0) && (sv->isVoid == 0)) {
303             if((i > 0) && (lastWasVoid == 0))
304                whenParams->append(", ");
305             whenParams->append(*(sv->name));
306             if (sv->arrayLength != 0) 
307                op<<"        int impl_off"<<cn->nodeNum <<"_"<<sv->name->charstar()<<"; implP"
308                  <<cn->nodeNum <<"|impl_off" <<cn->nodeNum <<"_"<<sv->name->charstar()<<";\n";
309             else
310                op<<"        "<<sv->type->charstar()<<" "<<sv->name->charstar()<<"; implP"
311                  <<cn->nodeNum <<"|"<<sv->name->charstar()<<";\n";
312          }
313          lastWasVoid = sv->isVoid;
314       } 
315       if (paramMarshalling == 1) 
316           op<<"        impl_buf"<<cn->nodeNum <<"+=CK_ALIGN(implP" <<cn->nodeNum <<".size(),16);\n";
317       i = 0;
318       sv = (CStateVar *)cn->stateVars->begin();
319       for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
320          if (sv->arrayLength != 0) 
321             op<<"        "<<sv->type->charstar()<<" *"<<sv->name->charstar()<<"=("<<sv->type->charstar()<<" *)(impl_buf" <<cn->nodeNum
322               <<"+impl_off" <<cn->nodeNum <<"_"<<sv->name->charstar()<<");\n";
323       }
324       if (paramMarshalling == 1) 
325          op << "        delete (CkMarshallMsg *)impl_msg" <<cn->nodeNum <<";\n";
326       op << "        " << cn->label->charstar() << "(" << whenParams->charstar();
327       op << ");\n";
328       op << "        delete tr;\n";
329
330 #if CMK_BIGSIM_CHARM
331       cn->generateTlineEndCall(op);
332       cn->generateBeginExec(op, "sdagholder");
333 #endif
334       cn->generateDummyBeginExecute(op);
335
336       op << "        return;\n";
337       op << "      }\n";
338     }
339   op << "    }\n";
340   } 
341
342   // actual code ends
343   op << "  }\n\n";
344 }
345
346 }