50f54f9d9807f772dabb8e6ebfdd957a1bf1d19e
[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        else if ((sv->isMsg == 0) && (sv->isVoid == 0)) {
221           if((i > 0) &&(lastWasVoid == 0)) 
222              whenParams->append(", ");
223           whenParams->append(*(sv->name));
224           if (sv->arrayLength != 0) 
225              op<<"    int impl_off_"<<sv->name->charstar()<<"; implP|impl_off_"<<sv->name->charstar()<<";\n";
226           else
227              op<<"    "<<sv->type->charstar()<<" "<<sv->name->charstar()<<"; implP|"<<sv->name->charstar()<<";\n";
228        }
229        lastWasVoid = sv->isVoid;
230       
231     } 
232     if (paramMarshalling == 1) 
233         op<<"     impl_buf+=CK_ALIGN(implP.size(),16);\n";
234     i = 0;
235     sv = (CStateVar *)cn->stateVars->begin();
236     for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
237        if (sv->arrayLength != 0) 
238           op<<"    "<<sv->type->charstar()<<" *"<<sv->name->charstar()<<"=("<<sv->type->charstar()<<" *)(impl_buf+impl_off_"<<sv->name->charstar()<<");\n";
239     }
240
241     if (paramMarshalling == 1) 
242        op << "    delete (CkMarshallMsg *)impl_msg;\n";
243     op << "    " << cn->label->charstar() << "(" << whenParams->charstar();
244     op << ");\n";
245   
246     op << "    delete tr;\n";
247 #if CMK_BIGSIM_CHARM
248     cn->generateTlineEndCall(op);
249     cn->generateBeginExec(op, "sdagholder");
250 #endif
251     cn->generateDummyBeginExecute(op);
252     op << "    return;\n";
253   }
254   else {   
255     op << "    switch(tr->whenID) {\n";
256     for(SdagConstruct *cn=whenList.begin(); !whenList.end(); cn=whenList.next())
257     {
258       whenParams = new XStr("");
259       i = 0; iArgs = 0;
260       op << "      case " << cn->nodeNum << ":\n";
261       op << "      {\n";
262       
263 #if CMK_BIGSIM_CHARM
264       // bgLog2 stores the parent dependence of when, e.g. for, olist
265       op <<"  cmsgbuf->bgLog2 = (void*)tr->args[1];\n";  
266 #endif
267       sv = (CStateVar *)cn->stateVars->begin();
268       i = 0;
269       paramMarshalling = 0;
270       lastWasVoid = 0;
271
272       for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
273          if ((sv->isMsg == 0) && (paramMarshalling == 0) && (sv->isVoid ==0)){
274             paramMarshalling =1;
275             op << "        CkMarshallMsg *impl_msg" <<cn->nodeNum <<" = (CkMarshallMsg *) tr->args["<<iArgs++<<"];\n"; 
276             op << "        char *impl_buf" <<cn->nodeNum <<"=((CkMarshallMsg *)impl_msg" <<cn->nodeNum <<")->msgBuf;\n";
277             op << "        PUP::fromMem implP" <<cn->nodeNum <<"(impl_buf" <<cn->nodeNum <<");\n";
278          }
279          if (sv->isMsg == 1) {
280             if((i!=0) && (lastWasVoid == 0))
281               whenParams->append(", ");
282 #if CMK_BIGSIM_CHARM
283             if(i==1) {
284                whenParams->append(" NULL ");
285                lastWasVoid=0;
286                // skip this arg which is supposed to be _bgParentLog
287                iArgs++;
288                continue;
289             }
290 #endif
291             whenParams->append("(");
292             whenParams->append(sv->type->charstar());
293             whenParams->append(" *) tr->args[");
294             *whenParams<<iArgs;
295             whenParams->append("]");
296             iArgs++;
297          }
298          else if (sv->isVoid == 1) 
299             op <<"    CkFreeSysMsg((void  *)tr->args[" <<iArgs++ <<"]);\n";
300          else if ((sv->isMsg == 0) && (sv->isVoid == 0)) {
301             if((i > 0) && (lastWasVoid == 0))
302                whenParams->append(", ");
303             whenParams->append(*(sv->name));
304             if (sv->arrayLength != 0) 
305                op<<"        int impl_off"<<cn->nodeNum <<"_"<<sv->name->charstar()<<"; implP"
306                  <<cn->nodeNum <<"|impl_off" <<cn->nodeNum <<"_"<<sv->name->charstar()<<";\n";
307             else
308                op<<"        "<<sv->type->charstar()<<" "<<sv->name->charstar()<<"; implP"
309                  <<cn->nodeNum <<"|"<<sv->name->charstar()<<";\n";
310          }
311          lastWasVoid = sv->isVoid;
312       } 
313       if (paramMarshalling == 1) 
314           op<<"        impl_buf"<<cn->nodeNum <<"+=CK_ALIGN(implP" <<cn->nodeNum <<".size(),16);\n";
315       i = 0;
316       sv = (CStateVar *)cn->stateVars->begin();
317       for(; i<(cn->stateVars->length());i++, sv=(CStateVar *)cn->stateVars->next()) {
318          if (sv->arrayLength != 0) 
319             op<<"        "<<sv->type->charstar()<<" *"<<sv->name->charstar()<<"=("<<sv->type->charstar()<<" *)(impl_buf" <<cn->nodeNum
320               <<"+impl_off" <<cn->nodeNum <<"_"<<sv->name->charstar()<<");\n";
321       }
322       if (paramMarshalling == 1) 
323          op << "        delete (CkMarshallMsg *)impl_msg" <<cn->nodeNum <<";\n";
324       op << "        " << cn->label->charstar() << "(" << whenParams->charstar();
325       op << ");\n";
326       op << "        delete tr;\n";
327
328 #if CMK_BIGSIM_CHARM
329       cn->generateTlineEndCall(op);
330       cn->generateBeginExec(op, "sdagholder");
331 #endif
332       cn->generateDummyBeginExecute(op);
333
334       op << "        return;\n";
335       op << "      }\n";
336     }
337   op << "    }\n";
338   } 
339
340   // actual code ends
341   op << "  }\n\n";
342 }
343
344 }