00001 #include "xi-Chare.h"
00002 #include "xi-Entry.h"
00003 #include "xi-Parameter.h"
00004 #include "xi-SdagCollection.h"
00005 #include "xi-Value.h"
00006 
00007 #include "sdag/constructs/When.h"
00008 
00009 #include <list>
00010 using std::list;
00011 
00012 namespace xi {
00013 
00014 extern int fortranMode;
00015 extern int internalMode;
00016 const char* python_doc;
00017 
00018 XStr Entry::proxyName(void) { return container->proxyName(); }
00019 XStr Entry::indexName(void) { return container->indexName(); }
00020 
00021 void Entry::print(XStr& str) {
00022   if (isThreaded()) str << "threaded ";
00023   if (isSync()) str << "sync ";
00024   if (retType) {
00025     retType->print(str);
00026     str << " ";
00027   }
00028   str << name << "(";
00029   if (param) param->print(str);
00030   str << ")";
00031   if (stacksize) {
00032     str << " stacksize = ";
00033     stacksize->print(str);
00034   }
00035   str << ";\n";
00036 }
00037 
00038 void Entry::check() {
00039   if (!external) {
00040     if (isConstructor() && retType && !retType->isVoid())
00041       XLAT_ERROR_NOCOL("constructors cannot return a value", first_line_);
00042 
00043     if (!isConstructor() && !retType)
00044       XLAT_ERROR_NOCOL(
00045           "non-constructor entry methods must specify a return type (probably void)",
00046           first_line_);
00047 
00048     if (isConstructor() && (isSync() || isIget())) {
00049       XLAT_ERROR_NOCOL("constructors cannot have the 'sync' attribute", first_line_);
00050       attribs ^= SSYNC;
00051     }
00052 
00053     if (param->isCkArgMsgPtr() && (!isConstructor() || !container->isMainChare()))
00054       XLAT_ERROR_NOCOL("CkArgMsg can only be used in mainchare's constructor",
00055                        first_line_);
00056 
00057     if (isExclusive() && isConstructor())
00058       XLAT_ERROR_NOCOL("constructors cannot be 'exclusive'", first_line_);
00059 
00060     if (isImmediate() && !container->isNodeGroup())
00061       XLAT_ERROR_NOCOL("[immediate] entry methods are only allowed on 'nodegroup' types",
00062                        first_line_);
00063 
00064     if (isLocal() && (container->isChare() || container->isNodeGroup()))
00065       XLAT_ERROR_NOCOL(
00066           "[local] entry methods are only allowed on 'array' and 'group' types",
00067           first_line_);
00068   }
00069 
00070   if (!isThreaded() && stacksize)
00071     XLAT_ERROR_NOCOL(
00072         "the 'stacksize' attribute is only applicable to methods declared 'threaded'",
00073         first_line_);
00074 
00075   if (retType && !isSync() && !isIget() && !isLocal() && !retType->isVoid())
00076     XLAT_ERROR_NOCOL(
00077         "non-void return type in a non-sync/non-local entry method\n"
00078         "To return non-void, you need to declare the method as [sync], which means it "
00079         "has blocking semantics,"
00080         " or [local].",
00081         first_line_);
00082 
00083   if (!isLocal() && param) param->checkParamList();
00084 
00085   if (isPython() && !container->isPython())
00086     XLAT_ERROR_NOCOL("python entry method declared in non-python chare", first_line_);
00087 
00088   
00089   if (isPython() && (!param || param->next || !param->param->getType()->isBuiltin() ||
00090                      !((BuiltinType*)param->param->getType())->isInt()))
00091     XLAT_ERROR_NOCOL(
00092         "python entry methods take only one parameter, which is of type 'int'",
00093         first_line_);
00094 
00095   if (isExclusive() && !container->isNodeGroup())
00096     XLAT_ERROR_NOCOL("only nodegroup methods can be 'exclusive'", first_line_);
00097 
00098   
00099   
00100   if (isSdag()) {
00101     list<CEntry*> whenEntryList;
00102     sdagCon->generateEntryList(whenEntryList, NULL);
00103     
00104     containsWhenConstruct = !whenEntryList.empty();
00105 
00106     for (list<CEntry*>::iterator en = whenEntryList.begin(); en != whenEntryList.end();
00107          ++en) {
00108       container->lookforCEntry(*en);
00109       (*en)->check();
00110     }
00111   }
00112 
00113   if (isTramTarget()) {
00114     if (param && (!param->isMarshalled() || param->isVoid() || param->next != NULL))
00115       XLAT_ERROR_NOCOL(
00116           "'aggregate' entry methods must be parameter-marshalled "
00117           "and take a single argument",
00118           first_line_);
00119 
00120     if (!external && !((container->isGroup() && !container->isNodeGroup()) || container->isArray()))
00121       XLAT_ERROR_NOCOL(
00122           "'aggregate' entry methods can only be used in regular groups and chare arrays",
00123           first_line_);
00124   }
00125 }
00126 
00127 void Entry::lookforCEntry(CEntry* centry) {
00128   
00129   if (strcmp(name, *centry->entry) != 0) return;
00130 
00131   centry->addCandidate(this);
00132 
00133   
00134   if (param && !centry->paramlist) return;
00135   if (!param && centry->paramlist) return;
00136   if (param && !(*param == *centry->paramlist)) return;
00137 
00138   isWhenEntry = 1;
00139   centry->decl_entry = this;
00140 }
00141 
00142 Entry::Entry(int l, int a, Type* r, const char* n, ParamList* p, Value* sz,
00143              SdagConstruct* sc, const char* e, int fl, int ll)
00144     : attribs(a),
00145       retType(r),
00146       stacksize(sz),
00147       sdagCon(sc),
00148       name((char*)n),
00149       targs(0),
00150       intExpr(e),
00151       param(p),
00152       genClosureTypeName(0),
00153       genClosureTypeNameProxy(0),
00154       genClosureTypeNameProxyTemp(0),
00155       entryPtr(0),
00156       first_line_(fl),
00157       last_line_(ll),
00158       numRdmaSendParams(0),
00159       numRdmaRecvParams(0) {
00160   line = l;
00161   container = NULL;
00162   entryCount = -1;
00163   isWhenEntry = 0;
00164   containsWhenConstruct = false;
00165   if (param && param->isMarshalled() && !isThreaded()) attribs |= SNOKEEP;
00166 
00167   if (isPython()) pythonDoc = python_doc;
00168   ParamList* plist = p;
00169   while (plist != NULL) {
00170     plist->entry = this;
00171     if (plist->param) {
00172       plist->param->entry = this;
00173       if (plist->param->getRdma() == CMK_ZC_P2P_SEND_MSG)
00174         numRdmaSendParams++; 
00175       if (plist->param->getRdma() == CMK_ZC_P2P_RECV_MSG)
00176         numRdmaRecvParams++; 
00177     }
00178     plist = plist->next;
00179   }
00180 }
00181 
00182 void Entry::setChare(Chare* c) {
00183   Member::setChare(c);
00184   
00185   
00186 
00187 
00188 
00189 
00190 
00191 
00192   if (isConstructor() && param->isVoid()) {
00193     if (container->isMainChare()) {
00194       
00195       Type* t = new PtrType(new NamedType("CkArgMsg"));
00196       param = new ParamList(new Parameter(line, t));
00197       std::cerr << "Charmxi> " << line
00198                 << ": Deprecation warning: mainchare constructors should explicitly take "
00199                    "CkArgMsg* if that's how they're implemented.\n";
00200     }
00201     if (container->isArray()) {
00202       Array* a = dynamic_cast<Array*>(c);
00203       a->hasVoidConstructor = true;
00204     }
00205   }
00206 
00207   entryCount = c->nextEntry();
00208 
00209   
00210   hasCallMarshall = param->isMarshalled() && !isThreaded() && !isSync() &&
00211                     !isExclusive() && !fortranMode;
00212   if (isSdag()) {
00213     container->setSdag(1);
00214 
00215     list<CEntry*> whenEntryList;
00216     sdagCon->generateEntryList(whenEntryList, NULL);
00217 
00218     for (list<CEntry*>::iterator i = whenEntryList.begin(); i != whenEntryList.end();
00219          ++i) {
00220       container->lookforCEntry(*i);
00221     }
00222   }
00223 }
00224 
00225 void Entry::preprocessSDAG() {
00226   if (isSdag() || isWhenEntry) {
00227     if (container->isNodeGroup()) {
00228       attribs |= SLOCKED;  
00229                            
00230     }
00231   }
00232 }
00233 
00234 
00235 
00236 XStr Entry::paramType(int withDefaultVals, int withEO, int useConst, int rValue) {
00237   XStr str;
00238   param->print(str, withDefaultVals, useConst, rValue);
00239   if (withEO) str << eo(withDefaultVals, !param->isVoid());
00240   return str;
00241 }
00242 
00243 
00244 
00245 XStr Entry::paramComma(int withDefaultVals, int withEO) {
00246   XStr str;
00247   if (!param->isVoid()) {
00248     str << paramType(withDefaultVals, withEO);
00249     str << ", ";
00250   }
00251   return str;
00252 }
00253 XStr Entry::eo(int withDefaultVals, int priorComma) {
00254   XStr str;
00255   
00256   
00257   if (!param->isMessage()) {
00258     if (priorComma) str << ", ";
00259     str << "const CkEntryOptions *impl_e_opts";
00260     if (withDefaultVals) str << "=NULL";
00261   }
00262   return str;
00263 }
00264 
00265 void Entry::collectSdagCode(SdagCollection* sc) {
00266   if (isSdag()) {
00267     sc->addNode(this);
00268   }
00269 }
00270 
00271 XStr Entry::marshallMsg(void) {
00272   XStr ret;
00273   XStr epName = epStr();
00274   param->marshall(ret, epName);
00275   return ret;
00276 }
00277 
00278 XStr Entry::epStr(bool isForRedn, bool templateCall) {
00279   XStr str;
00280   if (isForRedn) str << "redn_wrapper_";
00281   str << name << "_";
00282 
00283   if (param->isMessage()) {
00284     str << param->getBaseName();
00285     str.replace(':', '_');
00286   } else if (param->isVoid())
00287     str << "void";
00288   else
00289     str << "marshall" << entryCount;
00290 
00291   if (tspec && templateCall) {
00292     str << "<";
00293     tspec->genShort(str);
00294     str << ">";
00295   }
00296 
00297   return str;
00298 }
00299 
00300 XStr Entry::epIdx(int fromProxy, bool isForRedn) {
00301   XStr str;
00302   if (fromProxy) {
00303     str << indexName() << "::";
00304     
00305     if (tspec) str << "template ";
00306   }
00307   str << "idx_" << epStr(isForRedn, true) << "()";
00308   return str;
00309 }
00310 
00311 XStr Entry::epRegFn(int fromProxy, bool isForRedn) {
00312   XStr str;
00313   if (fromProxy) str << indexName() << "::";
00314   str << "reg_" << epStr(isForRedn, true) << "()";
00315   return str;
00316 }
00317 
00318 XStr Entry::chareIdx(int fromProxy) {
00319   XStr str;
00320   if (fromProxy) str << indexName() << "::";
00321   str << "__idx";
00322   return str;
00323 }
00324 
00325 XStr Entry::syncPreCall(void) {
00326   XStr str;
00327   if (retType->isVoid())
00328     str << "  void *impl_msg_typed_ret = ";
00329   else if (retType->isMessage())
00330     str << "  " << retType << " impl_msg_typed_ret = (" << retType << ")";
00331   else
00332     str << "  CkMarshallMsg *impl_msg_typed_ret = (CkMarshallMsg *)";
00333   return str;
00334 }
00335 
00336 XStr Entry::syncPostCall(void) {
00337   XStr str;
00338   if (retType->isVoid())
00339     str << "  CkFreeSysMsg(impl_msg_typed_ret); \n";
00340   else if (!retType->isMessage()) {
00341     str << "  char *impl_buf_ret=impl_msg_typed_ret->msgBuf; \n";
00342     str << "  PUP::fromMem implPS(impl_buf_ret); \n";
00343     str << "  " << retType << " retval; implPS|retval; \n";
00344     str << "  CkFreeMsg(impl_msg_typed_ret); \n";
00345     str << "  return retval; \n";
00346   } else {
00347     str << "  return impl_msg_typed_ret;\n";
00348   }
00349   return str;
00350 }
00351 
00352 
00353 
00354 void Entry::genChareDecl(XStr& str) {
00355   if (isConstructor()) {
00356     genChareStaticConstructorDecl(str);
00357   } else {
00358     
00359     str << "    " << generateTemplateSpec(tspec) << "\n"
00360         << "    " << retType << " " << name << "(" << paramType(1, 1) << ");\n";
00361   }
00362 }
00363 
00364 void Entry::genChareDefs(XStr& str) {
00365   if (isConstructor()) {
00366     genChareStaticConstructorDefs(str);
00367   } else {
00368     XStr params;
00369     params << epIdx() << ", impl_msg, &ckGetChareID()";
00370     
00371     XStr retStr;
00372     retStr << retType;
00373     str << makeDecl(retStr, 1) << "::" << name << "(" << paramType(0, 1) << ")\n";
00374     str << "{\n  ckCheck();\n";
00375     str << marshallMsg();
00376     if (isSync()) {
00377       str << syncPreCall() << "CkRemoteCall(" << params << ");\n";
00378       str << syncPostCall();
00379     } else {  
00380       str << "  if (ckIsDelegated()) {\n";
00381       if (param->hasRdma()) {
00382         str << "  CkAbort(\"Entry methods with nocopy parameters not supported when "
00383                "called with delegation managers\");\n";
00384       } else {
00385         str << "    int destPE=CkChareMsgPrep(" << params << ");\n";
00386         str << "    if (destPE!=-1) ckDelegatedTo()->ChareSend(ckDelegatedPtr(),"
00387             << params << ",destPE);\n";
00388       }
00389       str << "  } else {\n";
00390       XStr opts;
00391       opts << ",0";
00392       if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
00393       if (isInline()) opts << "+CK_MSG_INLINE";
00394       str << "    CkSendMsg(" << params << opts << ");\n";
00395       str << "  }\n";
00396     }
00397     str << "}\n";
00398   }
00399 }
00400 
00401 void Entry::genChareStaticConstructorDecl(XStr& str) {
00402   str << "    static CkChareID ckNew(" << paramComma(1) << "int onPE=CK_PE_ANY" << eo(1)
00403       << ");\n";
00404   str << "    static void ckNew(" << paramComma(1)
00405       << "CkChareID* pcid, int onPE=CK_PE_ANY" << eo(1) << ");\n";
00406   if (!param->isVoid())
00407     str << "    " << container->proxyName(0) << "(" << paramComma(1)
00408         << "int onPE=CK_PE_ANY" << eo(1) << ");\n";
00409 }
00410 
00411 void Entry::genChareStaticConstructorDefs(XStr& str) {
00412   str << makeDecl("CkChareID", 1) << "::ckNew(" << paramComma(0) << "int impl_onPE"
00413       << eo(0) << ")\n";
00414   str << "{\n";
00415   str << marshallMsg();
00416   str << "  CkChareID impl_ret;\n";
00417   str << "  CkCreateChare(" << chareIdx() << ", " << epIdx()
00418       << ", impl_msg, &impl_ret, impl_onPE);\n";
00419   str << "  return impl_ret;\n";
00420   str << "}\n";
00421 
00422   str << makeDecl("void", 1) << "::ckNew(" << paramComma(0)
00423       << "CkChareID* pcid, int impl_onPE" << eo(0) << ")\n";
00424   str << "{\n";
00425   str << marshallMsg();
00426   str << "  CkCreateChare(" << chareIdx() << ", " << epIdx()
00427       << ", impl_msg, pcid, impl_onPE);\n";
00428   str << "}\n";
00429 
00430   if (!param->isVoid()) {
00431     str << makeDecl(" ", 1) << "::" << container->proxyName(0) << "(" << paramComma(0)
00432         << "int impl_onPE" << eo(0) << ")\n";
00433     str << "{\n";
00434     str << marshallMsg();
00435     str << "  CkChareID impl_ret;\n";
00436     str << "  CkCreateChare(" << chareIdx() << ", " << epIdx()
00437         << ", impl_msg, &impl_ret, impl_onPE);\n";
00438     str << "  ckSetChareID(impl_ret);\n";
00439     str << "}\n";
00440   }
00441 }
00442 
00443 
00444 
00445 void Entry::genArrayDecl(XStr& str) {
00446   if (isConstructor()) {
00447     str << "    " << generateTemplateSpec(tspec) << "\n";
00448     genArrayStaticConstructorDecl(str);
00449   } else {
00450     if ((isSync() || isLocal()) && !container->isForElement())
00451       return;  
00452     if (isIget()) {
00453       str << "    " << generateTemplateSpec(tspec) << "\n";
00454       str << "    "
00455           << "CkFutureID"
00456           << " " << name << "(" << paramType(1, 1) << ") ;\n";  
00457     } else if ((isLocal() || isInline()) && container->isForElement()) {
00458       XStr fwdStr;
00459       int fwdNum = 1;
00460       ParamList *pl = param;
00461       while (pl) {
00462         Parameter *p = pl->param;
00463         if (!p->isRdma() && p->arrLen == NULL && !p->conditional && p->byReference) {
00464           if (fwdNum > 1)
00465             fwdStr << ", ";
00466           fwdStr << "typename Fwd" << fwdNum++ << " = " << p->type;
00467         }
00468         pl = pl->next;
00469       }
00470       const bool doFwd = fwdNum > 1;
00471       if (tspec || doFwd) {
00472         str << "    template <";
00473         if (tspec) {
00474           tspec->genLong(str);
00475           if (doFwd)
00476             str << ", ";
00477         }
00478         if (doFwd)
00479           str << fwdStr;
00480         str << ">\n";
00481       }
00482       str << "    " << retType << " " << name << "(" << paramType(1, 1, 0, 1) << ") ;\n";
00483     } else if (isLocal()) {
00484       str << "    " << generateTemplateSpec(tspec) << "\n";
00485       str << "    " << retType << " " << name << "(" << paramType(1, 1, 0) << ") ;\n";
00486     } else if (isTramTarget() && container->isForElement()) {
00487       str << "    " << generateTemplateSpec(tspec) << "\n";
00488       str << "    " << retType << " " << name << "(" << paramType(0, 1) << ") = delete;\n";
00489       str << "    " << retType << " " << name << "(" << paramType(1, 0) << ") ;\n";
00490     } else {
00491       str << "    " << generateTemplateSpec(tspec) << "\n";
00492       str << "    " << retType << " " << name << "(" << paramType(1, 1)
00493           << ") ;\n";  
00494     }
00495   }
00496 }
00497 
00498 void Entry::genArrayDefs(XStr& str) {
00499   if (isIget() && !container->isForElement()) return;
00500 
00501   if (isConstructor())
00502     genArrayStaticConstructorDefs(str);
00503   else {  
00504     const char* ifNot = "CkArray_IfNotThere_buffer";
00505     if (isCreateHere()) ifNot = "CkArray_IfNotThere_createhere";
00506     if (isCreateHome()) ifNot = "CkArray_IfNotThere_createhome";
00507 
00508     if ((isSync() || isLocal()) && !container->isForElement())
00509       return;  
00510 
00511     XStr retStr;
00512     retStr << retType;
00513     if (isIget())
00514       str << makeDecl("CkFutureID ", 1) << "::" << name << "(" << paramType(0, 1)
00515           << ") \n";  
00516     else if ((isLocal() || isInline()) && container->isForElement()) {
00517       XStr fwdStr;
00518       int fwdNum = 1;
00519       ParamList *pl = param;
00520       while (pl) {
00521         Parameter *p = pl->param;
00522         if (!p->isRdma() && p->arrLen == NULL && !p->conditional && p->byReference) {
00523           if (fwdNum > 1)
00524             fwdStr << ", ";
00525           fwdStr << "typename Fwd" << fwdNum++; 
00526         }
00527         pl = pl->next;
00528       }
00529       str << makeDecl(retStr, 1, false, fwdStr) << "::" << name << "(" << paramType(0, 1, 0, 1) << ") \n";
00530     } else if (isLocal())
00531       str << makeDecl(retStr, 1) << "::" << name << "(" << paramType(0, 1, 0) << ") \n";
00532     else
00533       str << makeDecl(retStr, 1) << "::" << name << "(" << paramType(0, 1)
00534           << ") \n";  
00535     str << "{\n";
00536     
00537     str << "  ckCheck();\n";
00538     XStr inlineCall;
00539     if (!isNoTrace())
00540       inlineCall
00541           << "    _TRACE_BEGIN_EXECUTE_DETAILED(0,ForArrayEltMsg,(" << epIdx()
00542           << "),CkMyPe(), 0, ((CkArrayIndex&)ckGetIndex()).getProjectionID(), obj);\n";
00543     if (isAppWork()) inlineCall << "    _TRACE_BEGIN_APPWORK();\n";
00544     inlineCall << "#if CMK_LBDB_ON\n"
00545                << "    LDObjHandle objHandle;\n"
00546                << "    int objstopped=0;\n"
00547                << "    objHandle = obj->timingBeforeCall(&objstopped);\n"
00548                << "#endif\n";
00549     inlineCall << "#if CMK_CHARMDEBUG\n"
00550                   "    CpdBeforeEp("
00551                << epIdx()
00552                << ", obj, NULL);\n"
00553                   "#endif\n";
00554     inlineCall << "    ";
00555     if (!retType->isVoid()) inlineCall << retType << " retValue = ";
00556     inlineCall << "obj->" << (tspec ? "template " : "") << name;
00557     if (tspec) {
00558       inlineCall << "<";
00559       tspec->genShort(inlineCall);
00560       inlineCall << ">";
00561     }
00562     inlineCall << "(";
00563     param->unmarshallForward(inlineCall, true);
00564     inlineCall << ");\n";
00565     inlineCall << "#if CMK_CHARMDEBUG\n"
00566                   "    CpdAfterEp("
00567                << epIdx()
00568                << ");\n"
00569                   "#endif\n";
00570     inlineCall << "#if CMK_LBDB_ON\n    "
00571                   "obj->timingAfterCall(objHandle,&objstopped);\n#endif\n";
00572     if (isAppWork()) inlineCall << "    _TRACE_END_APPWORK();\n";
00573     if (!isNoTrace()) inlineCall << "    _TRACE_END_EXECUTE();\n";
00574     if (!retType->isVoid()) {
00575       inlineCall << "    return retValue;\n";
00576     } else {
00577       inlineCall << "    return;\n";
00578     }
00579 
00580     XStr prepareMsg;
00581     prepareMsg << marshallMsg();
00582     prepareMsg << "  UsrToEnv(impl_msg)->setMsgtype(ForArrayEltMsg);\n";
00583     prepareMsg << "  CkArrayMessage *impl_amsg=(CkArrayMessage *)impl_msg;\n";
00584     prepareMsg << "  impl_amsg->array_setIfNotThere(" << ifNot << ");\n";
00585 
00586     if (!isLocal()) {
00587       if (isInline() && container->isForElement()) {
00588         str << "  " << container->baseName() << " *obj = ckLocal();\n";
00589         str << "  if (obj) {\n" << inlineCall << "  }\n";
00590       }
00591       str << prepareMsg;
00592     } else {
00593       str << "  " << container->baseName() << " *obj = ckLocal();\n";
00594       str << "#if CMK_ERROR_CHECKING\n";
00595       str << "  if (obj==NULL) CkAbort(\"Trying to call a LOCAL entry method on a "
00596              "non-local element\");\n";
00597       str << "#endif\n";
00598       str << inlineCall;
00599     }
00600     if (isIget()) {
00601       str << "  CkFutureID f=CkCreateAttachedFutureSend(impl_amsg," << epIdx()
00602           << ",ckGetArrayID(),ckGetIndex(),&CProxyElement_ArrayBase::ckSendWrapper);"
00603           << "\n";
00604     }
00605 
00606     if (isSync()) {
00607       str << syncPreCall() << "ckSendSync(impl_amsg, " << epIdx() << ");\n";
00608       str << syncPostCall();
00609     } else if (!isLocal()) {
00610       XStr opts;
00611       opts << ",0";
00612       if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
00613       if (isInline()) opts << "+CK_MSG_INLINE";
00614       if (!isIget()) {
00615         if (container->isForElement() || container->isForSection()) {
00616           str << "  ckSend(impl_amsg, " << epIdx() << opts << ");\n";
00617         } else
00618           str << "  ckBroadcast(impl_amsg, " << epIdx() << opts << ");\n";
00619       }
00620     }
00621     if (isIget()) {
00622       str << "  return f;\n";
00623     }
00624     str << "}\n";
00625 
00626     if (!tspec && !container->isTemplated() && !isIget() && (isLocal() || isInline()) && container->isForElement()) {
00627       XStr fwdStr;
00628       int fwdNum = 1;
00629       ParamList *pl = param;
00630       while (pl) {
00631         Parameter *p = pl->param;
00632         if (!p->isRdma() && p->arrLen == NULL && !p->conditional && p->byReference) {
00633           if (fwdNum > 1)
00634             fwdStr << ", ";
00635           ++fwdNum;
00636           if (p->byConst) fwdStr << "const ";
00637           fwdStr << p->type << " &";
00638         }
00639         pl = pl->next;
00640       }
00641       const bool doFwd = fwdNum > 1;
00642       if (doFwd) {
00643         str << "// explicit instantiation for compatibility\n";
00644         str << "template " << makeDecl(retStr, 1) << "::" << name << "<" << fwdStr << ">(" << paramType(0, 1, 0) << ");\n";
00645       }
00646     }
00647   }
00648 }
00649 
00650 void Entry::genArrayStaticConstructorDecl(XStr& str) {
00651   if (!container->isArray())
00652     die("Internal error - array declarations called for on non-array Chare type");
00653 
00654   if (container->getForWhom() == forIndividual)
00655     str <<  
00656         "    void insert(" << paramComma(1, 0) << "int onPE=-1" << eo(1) << ");";
00657   else if (container->getForWhom() == forAll) {
00658     
00659     
00660     str << "    static CkArrayID ckNew(" << paramComma(1, 0)
00661         << "const CkArrayOptions &opts = CkArrayOptions()" << eo(1) << ");\n";
00662     str << "    static void      ckNew(" << paramComma(1, 0)
00663         << "const CkArrayOptions &opts, CkCallback _ck_array_creation_cb" << eo(1)
00664         << ");\n";
00665 
00666     XStr dim = ((Array*)container)->dim();
00667     if (dim == (const char*)"1D") {
00668       str << "    static CkArrayID ckNew(" << paramComma(1, 0) << "const int s1" << eo(1)
00669           << ");\n";
00670       str << "    static void ckNew(" << paramComma(1, 0)
00671           << "const int s1, CkCallback _ck_array_creation_cb" << eo(1) << ");\n";
00672     } else if (dim == (const char*)"2D") {
00673       str << "    static CkArrayID ckNew(" << paramComma(1, 0)
00674           << "const int s1, const int s2" << eo(1) << ");\n";
00675       str << "    static void ckNew(" << paramComma(1, 0)
00676           << "const int s1, const int s2, CkCallback _ck_array_creation_cb" << eo(1)
00677           << ");\n";
00678     } else if (dim == (const char*)"3D") {
00679       str << "    static CkArrayID ckNew(" << paramComma(1, 0)
00680           << "const int s1, const int s2, const int s3" << eo(1) << ");\n";
00681       str << "    static void ckNew(" << paramComma(1, 0)
00682           << "const int s1, const int s2, const int s3, CkCallback _ck_array_creation_cb"
00683           << eo(1) << ");\n";
00684       
00685 
00686 
00687 
00688 
00689 
00690 
00691 
00692     }
00693   } else if (container->getForWhom() == forSection) {
00694   }
00695 }
00696 
00697 void Entry::genArrayStaticConstructorDefs(XStr& str) {
00698   if (!container->isArray())
00699     die("Internal error - array definitions called for on non-array Chare type");
00700 
00701   if (container->getForWhom() == forIndividual)
00702     str << makeDecl("void", 1) << "::insert(" << paramComma(0, 0) << "int onPE" << eo(0)
00703         << ")\n"
00704            "{ \n "
00705         << marshallMsg()
00706         << "   UsrToEnv(impl_msg)->setMsgtype(ArrayEltInitMsg);\n"
00707            "   ckInsert((CkArrayMessage *)impl_msg,"
00708         << epIdx() << ",onPE);\n}\n";
00709   else if (container->getForWhom() == forAll) {
00710     XStr syncPrototype, asyncPrototype, head, syncTail, asyncTail;
00711     syncPrototype << makeDecl("CkArrayID", 1) << "::ckNew";
00712     asyncPrototype << makeDecl("void", 1) << "::ckNew";
00713 
00714     head << "{\n" << marshallMsg();
00715 
00716     syncTail << "  UsrToEnv(impl_msg)->setMsgtype(ArrayEltInitMsg);\n"
00717              << "  CkArrayID gId = ckCreateArray((CkArrayMessage *)impl_msg, " << epIdx()
00718              << ", opts);\n";
00719 
00720     genTramInstantiation(syncTail);
00721     syncTail << "  return gId;\n}\n";
00722 
00723     asyncTail << "  UsrToEnv(impl_msg)->setMsgtype(ArrayEltInitMsg);\n"
00724               << "  CkSendAsyncCreateArray(" << epIdx()
00725               << ", _ck_array_creation_cb, opts, impl_msg);\n"
00726               << "}\n";
00727 
00728     str << syncPrototype << "(" << paramComma(0) << "const CkArrayOptions &opts" << eo(0)
00729         << ")\n"
00730         << head << syncTail;
00731     str << asyncPrototype << "(" << paramComma(0)
00732         << "const CkArrayOptions &opts, CkCallback _ck_array_creation_cb" << eo(0)
00733         << ")\n"
00734         << head << asyncTail;
00735 
00736     XStr dim = ((Array*)container)->dim();
00737     XStr sizeParams, sizeArgs;
00738     bool emit = true;
00739 
00740     if (dim == (const char*)"1D") {
00741       sizeParams << "const int s1";
00742       sizeArgs << "s1";
00743     } else if (dim == (const char*)"2D") {
00744       sizeParams << "const int s1, const int s2";
00745       sizeArgs << "s1, s2";
00746     } else if (dim == (const char*)"3D") {
00747       sizeParams << "const int s1, const int s2, const int s3";
00748       sizeArgs << "s1, s2, s3";
00749     }
00750 #if 0
00751     else if (dim==(const char*)"4D") {
00752       sizeParams << "const short s1, const short s2, const short s3, const short s4";
00753       sizeArgs << "s1, s2, s3, s4";
00754     } else if (dim==(const char*)"5D") {
00755       sizeParams << "const short s1, const short s2, const short s3, const short s4, "
00756                  << "const short s5";
00757       sizeArgs << "s1, s2, s3, s4, s5";
00758     } else if (dim==(const char*)"6D") {
00759       sizeParams << "const short s1, const short s2, const short s3, const short s4, "
00760                  << "const short s5, const short s6";
00761       sizeArgs << "s1, s2, s3, s4, s5, s6";
00762     }
00763 #endif
00764     else {
00765       emit = false;
00766     }
00767 
00768     if (emit) {
00769       str << syncPrototype << "(" << paramComma(0) << sizeParams << eo(0) << ")\n"
00770           << head << "  CkArrayOptions opts(" << sizeArgs << ");\n"
00771           << syncTail;
00772       str << asyncPrototype << "(" << paramComma(0) << sizeParams
00773           << ", CkCallback _ck_array_creation_cb" << eo(0) << ")\n"
00774           << head << "  CkArrayOptions opts(" << sizeArgs << ");\n"
00775           << asyncTail;
00776     }
00777   }
00778 }
00779 
00780 
00781 
00782 void Entry::genGroupDecl(XStr& str) {
00783   if (isConstructor()) {
00784     str << "    " << generateTemplateSpec(tspec) << "\n";
00785     genGroupStaticConstructorDecl(str);
00786   } else {
00787     if ((isSync() || isLocal()) && !container->isForElement())
00788       return;  
00789     str << "    " << generateTemplateSpec(tspec) << "\n";
00790     if (isLocal()) {
00791       str << "    " << retType << " " << name << "(" << paramType(1, 1, 0) << ");\n";
00792     } else if (isTramTarget() && container->isForElement()) {
00793       str << "    " << retType << " " << name << "(" << paramType(0, 1) << ") = delete;\n";
00794       str << "    " << retType << " " << name << "(" << paramType(1, 0) << ");\n";
00795     } else {
00796       str << "    " << retType << " " << name << "(" << paramType(1, 1) << ");\n";
00797     }
00798     
00799     if (!container->isForElement() && !container->isForSection() && !isSync() &&
00800         !isLocal() && !container->isNodeGroup()) {
00801       str << "    " << generateTemplateSpec(tspec) << "\n";
00802       str << "    " << retType << " " << name << "(" << paramComma(0, 0)
00803           << "int npes, int *pes" << eo(1) << ");\n";
00804       str << "    " << generateTemplateSpec(tspec) << "\n";
00805       str << "    " << retType << " " << name << "(" << paramComma(0, 0)
00806           << "CmiGroup &grp" << eo(1) << ");\n";
00807     }
00808   }
00809 }
00810 
00811 void Entry::genGroupDefs(XStr& str) {
00812   if(isConstructor()) {
00813     genGroupStaticConstructorDefs(str);
00814     return;
00815   }
00816 
00817   
00818   char* node = (char*)(container->isNodeGroup() ? "Node" : "");
00819 
00820   int forElement = container->isForElement();
00821   XStr params;
00822   params << epIdx() << ", impl_msg";
00823   XStr paramg;
00824   paramg << epIdx() << ", impl_msg, ckGetGroupID()";
00825   XStr parampg;
00826   parampg << epIdx() << ", impl_msg, ckGetGroupPe(), ckGetGroupID()";
00827   
00828   XStr opts;
00829   opts << ",0";
00830   if (isImmediate()) opts << "+CK_MSG_IMMEDIATE";
00831   if (isInline()) opts << "+CK_MSG_INLINE";
00832   if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
00833 
00834   if ((isSync() || isLocal()) && !container->isForElement())
00835     return;  
00836 
00837   XStr retStr;
00838   retStr << retType;
00839   XStr msgTypeStr;
00840   if (isLocal())
00841     msgTypeStr << paramType(0, 1, 0);
00842   else
00843     msgTypeStr << paramType(0, 1);
00844   str << makeDecl(retStr, 1) << "::" << name << "(" << msgTypeStr << ")\n";
00845   str << "{\n";
00846   
00847     str << "  ckCheck();\n";
00848     if (!isLocal()) str << marshallMsg();
00849 
00850     if (isLocal()) {
00851       XStr unmarshallStr;
00852       param->unmarshall(unmarshallStr, true);
00853       str << "  " << container->baseName() << " *obj = ckLocalBranch();\n";
00854       str << "  CkAssert(obj);\n";
00855       if (!isNoTrace())
00856         
00857         
00858         str << "  envelope env;\n"
00859             << "  env.setMsgtype(ForBocMsg);\n"
00860             << "  env.setTotalsize(0);\n"
00861             << "  _TRACE_CREATION_DETAILED(&env, " << epIdx() << ");\n"
00862             << "  _TRACE_CREATION_DONE(1);\n"
00863             << "  _TRACE_BEGIN_EXECUTE_DETAILED(CpvAccess(curPeEvent),ForBocMsg,(" << epIdx()
00864             << "),CkMyPe(),0,NULL, NULL);\n";
00865       if (isAppWork()) str << " _TRACE_BEGIN_APPWORK();\n";
00866       str << "#if CMK_LBDB_ON\n"
00867              "  // if there is a running obj being measured, stop it temporarily\n"
00868              "  LDObjHandle objHandle;\n"
00869              "  int objstopped = 0;\n"
00870              "  LBDatabase *the_lbdb = (LBDatabase *)CkLocalBranch(_lbdb);\n"
00871              "  if (the_lbdb->RunningObject(&objHandle)) {\n"
00872              "    objstopped = 1;\n"
00873              "    the_lbdb->ObjectStop(objHandle);\n"
00874              "  }\n"
00875              "#endif\n";
00876       str << "#if CMK_CHARMDEBUG\n"
00877              "  CpdBeforeEp("
00878           << epIdx()
00879           << ", obj, NULL);\n"
00880              "#endif\n  ";
00881       if (!retType->isVoid()) str << retType << " retValue = ";
00882       str << "obj->" << name << "(" << unmarshallStr << ");\n";
00883       str << "#if CMK_CHARMDEBUG\n"
00884              "  CpdAfterEp("
00885           << epIdx()
00886           << ");\n"
00887              "#endif\n";
00888       str << "#if CMK_LBDB_ON\n"
00889              "  if (objstopped) the_lbdb->ObjectStart(objHandle);\n"
00890              "#endif\n";
00891       if (isAppWork()) str << " _TRACE_END_APPWORK();\n";
00892       if (!isNoTrace()) str << "  _TRACE_END_EXECUTE();\n";
00893       if (!retType->isVoid()) str << "  return retValue;\n";
00894     } else if (isSync()) {
00895       str << syncPreCall() << "CkRemote" << node << "BranchCall(" << paramg
00896           << ", ckGetGroupPe());\n";
00897       str << syncPostCall();
00898     } else {             
00899       if (forElement) {  
00900         str << "  if (ckIsDelegated()) {\n";
00901         if (param->hasRdma()) {
00902           str << "    CkAbort(\"Entry methods with nocopy parameters not supported "
00903                  "when called with delegation managers\");\n";
00904         } else {
00905           str << "     Ck" << node << "GroupMsgPrep(" << paramg << ");\n";
00906           str << "     ckDelegatedTo()->" << node << "GroupSend(ckDelegatedPtr(),"
00907               << parampg << ");\n";
00908         }
00909         str << "  } else {\n";
00910         str << "    CkSendMsg" << node << "Branch"
00911             << "(" << parampg << opts << ");\n";
00912         str << "  }\n";
00913       } else if (container->isForSection()) {  
00914         str << "  if (ckIsDelegated()) {\n";
00915         str << "     ckDelegatedTo()->" << node << "GroupSectionSend(ckDelegatedPtr(),"
00916             << params << ", ckGetNumSections(), ckGetSectionIDs());\n";
00917         str << "  } else {\n";
00918         str << "    void *impl_msg_tmp;\n";
00919         str << "    for (int i=0; i<ckGetNumSections(); ++i) {\n";
00920         str << "       impl_msg_tmp= (i<ckGetNumSections()-1) ? CkCopyMsg((void **) "
00921                "&impl_msg):impl_msg;\n";
00922         str << "       CkSendMsg" << node << "BranchMulti(" << epIdx()
00923             << ", impl_msg_tmp, ckGetGroupIDn(i), ckGetNumElements(i), ckGetElements(i)"
00924             << opts << ");\n";
00925         str << "    }\n";
00926         str << "  }\n";
00927       } else {  
00928         str << "  if (ckIsDelegated()) {\n";
00929         str << "     Ck" << node << "GroupMsgPrep(" << paramg << ");\n";
00930         str << "     ckDelegatedTo()->" << node << "GroupBroadcast(ckDelegatedPtr(),"
00931             << paramg << ");\n";
00932         str << "  } else CkBroadcastMsg" << node << "Branch(" << paramg << opts
00933             << ");\n";
00934       }
00935     }
00936   str << "}\n";
00937 
00938   
00939   if (!forElement && !container->isForSection() && !isSync() && !isLocal() &&
00940       !container->isNodeGroup()) {
00941     str << "" << makeDecl(retStr, 1) << "::" << name << "(" << paramComma(0, 0)
00942         << "int npes, int *pes" << eo(0) << ") {\n";
00943     str << marshallMsg();
00944     str << "  CkSendMsg" << node << "BranchMulti(" << paramg << ", npes, pes" << opts
00945         << ");\n";
00946     str << "}\n";
00947     str << "" << makeDecl(retStr, 1) << "::" << name << "(" << paramComma(0, 0)
00948         << "CmiGroup &grp" << eo(0) << ") {\n";
00949     str << marshallMsg();
00950     str << "  CkSendMsg" << node << "BranchGroup(" << paramg << ", grp" << opts
00951         << ");\n";
00952     str << "}\n";
00953   }
00954 }
00955 
00956 XStr Entry::aggregatorIndexType() {
00957   XStr indexType;
00958   if (container->isGroup()) {
00959     indexType << "int";
00960   } else if (container->isArray()) {
00961     XStr dim, arrayIndexType;
00962     dim << ((Array*)container)->dim();
00963      indexType << "CkArrayIndex";
00964   }
00965   return indexType;
00966 }
00967 
00968 XStr Entry::dataItemType() {
00969   XStr itemType;
00970   if (container->isGroup()) {
00971     itemType << param->param->type;
00972   } else if (container->isArray()) {
00973     itemType << "ArrayDataItem<" << param->param->type << ", " << aggregatorIndexType()
00974              << ">";
00975   }
00976   return itemType;
00977 }
00978 
00979 XStr Entry::aggregatorType() {
00980   XStr groupType;
00981   if (container->isGroup()) {
00982     groupType << "GroupMeshStreamer<" << param->param->type << ", "
00983               << container->baseName() << ", SimpleMeshRouter"
00984               << ", " << container->indexName() << "::_callmarshall_" << epStr() << ">";
00985   } else if (container->isArray()) {
00986     groupType << "ArrayMeshStreamer<" << param->param->type << ", "
00987               << aggregatorIndexType() << ", " << container->baseName() << ", "
00988               << "SimpleMeshRouter, " << container->indexName() << "::_callmarshall_"
00989               << epStr() << ">";
00990   }
00991   return groupType;
00992 }
00993 
00994 XStr Entry::aggregatorGlobalType(XStr& scope) {
00995   XStr groupType;
00996   if (container->isGroup()) {
00997     groupType << "GroupMeshStreamer<" << param->param->type << ", " << scope
00998               << container->baseName() << ", SimpleMeshRouter"
00999               << ", " << scope << container->indexName() << "::_callmarshall_" << epStr()
01000               << ">";
01001   } else if (container->isArray()) {
01002     groupType << "ArrayMeshStreamer<" << param->param->type << ", "
01003               << aggregatorIndexType() << ", " << scope << container->baseName() << ", "
01004               << "SimpleMeshRouter, " << scope << container->indexName()
01005               << "::_callmarshall_" << epStr() << ">";
01006   }
01007   return groupType;
01008 }
01009 
01010 XStr Entry::aggregatorName() {
01011   XStr aggregatorName;
01012   aggregatorName << epStr() << "TramAggregator";
01013   return aggregatorName;
01014 }
01015 
01016 void Entry::genTramTypes() {
01017   if (isTramTarget()) {
01018     XStr typeString, nameString, itemTypeString;
01019     typeString << aggregatorType();
01020     nameString << aggregatorName();
01021     itemTypeString << dataItemType();
01022 #if __cplusplus >= 201103L
01023     container->tramInstances.emplace_back(
01024         typeString.get_string(), nameString.get_string(), itemTypeString.get_string());
01025 #else
01026     container->tramInstances.push_back(TramInfo(
01027         typeString.get_string(), nameString.get_string(), itemTypeString.get_string()));
01028 #endif
01029     tramInstanceIndex = container->tramInstances.size();
01030   }
01031 }
01032 
01033 void Entry::genTramDefs(XStr& str) {
01034   XStr retStr;
01035   retStr << retType;
01036   XStr msgTypeStr;
01037 
01038   if (isLocal())
01039     msgTypeStr << paramType(0, 0, 0);
01040   else
01041     msgTypeStr << paramType(0, 0);
01042   str << makeDecl(retStr, 1) << "::" << name << "(" << msgTypeStr << ") {\n"
01043       << "  if (" << aggregatorName() << " == NULL) {\n";
01044 
01045   if (container->isGroup()) {
01046     str << "    CkGroupID gId = ckGetGroupID();\n";
01047   } else if (container->isArray()) {
01048     str << "    CkArray *aMgr = ckLocalBranch();\n"
01049         << "    CkGroupID gId = aMgr->getGroupID();\n";
01050   }
01051 
01052   str << "    CkGroupID tramGid;\n"
01053       << "    tramGid.idx = gId.idx + " << tramInstanceIndex << ";\n"
01054       << "    " << aggregatorName() << " = (" << aggregatorType() << "*)"
01055       << " CkLocalBranch(tramGid);\n  }\n";
01056 
01057   if (container->isGroup()) {
01058     str << "  " << aggregatorName() << "->insertData(" << param->param->name << ", "
01059         << "ckGetGroupPe());\n}\n";
01060   } else if (container->isArray()) {
01061     XStr dim;
01062     dim << ((Array*)container)->dim();
01063     str << "  const CkArrayIndex &myIndex = ckGetIndex();\n"
01064         << "  " << aggregatorName() << "->insertData<" << (isInline() ? "true" : "false")
01065         << ">(" << param->param->name;
01066     str << ", " << "myIndex);\n}\n";
01067   }
01068 }
01069 
01070 
01071 const static int tramBufferSize = 16384;
01072 
01073 void Entry::genTramInstantiation(XStr& str) {
01074   if (!container->tramInstances.empty()) {
01075     str << "  int pesPerNode = CkMyNodeSize();\n"
01076         << "  if (pesPerNode == 1) {\n"
01077         << "    pesPerNode = CmiNumCores();\n"
01078         << "  }\n"
01079         << "  const int nDims = 2;\n"
01080         << "  int dims[nDims];\n"
01081         << "  dims[0] = CkNumPes() / pesPerNode;\n"
01082         << "  dims[1] = pesPerNode;\n"
01083         << "  if (dims[0] * dims[1] != CkNumPes()) {\n"
01084         << "    dims[0] = CkNumPes();\n"
01085         << "    dims[1] = 1;\n"
01086         << "  }\n"
01087         << "  int tramBufferSize = " << tramBufferSize << ";\n";
01088     for (int i = 0; i < container->tramInstances.size(); i++) {
01089       str << "  {\n"
01090           << "    int itemsPerBuffer = tramBufferSize / sizeof("
01091           << container->tramInstances[i].itemType.c_str() << ");\n"
01092           << "    if (itemsPerBuffer == 0) {\n"
01093           << "      itemsPerBuffer = 1;\n"
01094           << "    }\n"
01095           << "    CProxy_" << container->tramInstances[i].type.c_str() << " tramProxy =\n"
01096           << "    CProxy_" << container->tramInstances[i].type.c_str()
01097           << "::ckNew(2, dims, gId, itemsPerBuffer, false, 10.0);\n"
01098           << "    tramProxy.enablePeriodicFlushing();\n"
01099           << "  }\n";
01100     }
01101   }
01102 }
01103 
01104 XStr Entry::tramBaseType() {
01105   XStr baseTypeString;
01106   baseTypeString << "MeshStreamer<" << dataItemType() << ", SimpleMeshRouter>";
01107 
01108   return baseTypeString;
01109 }
01110 
01111 void Entry::genTramRegs(XStr& str) {
01112   if (isTramTarget()) {
01113     XStr messageTypeString;
01114     messageTypeString << "MeshStreamerMessage<" << dataItemType() << ">";
01115 
01116     XStr baseTypeString = tramBaseType();
01117 
01118     NamedType messageType(messageTypeString.get_string());
01119     Message helper(-1, &messageType);
01120     helper.genReg(str);
01121 
01122     str << "\n  /* REG: group " << aggregatorType() << ": IrrGroup;\n  */\n"
01123         << "  CkIndex_" << aggregatorType() << "::__register(\"" << aggregatorType()
01124         << "\", sizeof(" << aggregatorType() << "));\n"
01125         << "  /* REG: group " << baseTypeString << ": IrrGroup;\n  */\n"
01126         << "  CkIndex_" << baseTypeString << "::__register(\"" << baseTypeString
01127         << "\", sizeof(" << baseTypeString << "));\n";
01128   }
01129 }
01130 
01131 void Entry::genTramPups(XStr& scope, XStr& decls, XStr& defs) {
01132   if (isTramTarget()) {
01133     XStr aggregatorTypeString = aggregatorGlobalType(scope);
01134     container->genRecursivePup(aggregatorTypeString, "template <>\n", decls, defs);
01135   }
01136 }
01137 
01138 void Entry::genGroupStaticConstructorDecl(XStr& str) {
01139   if (container->isForElement()) return;
01140   if (container->isForSection()) return;
01141 
01142   str << "    static CkGroupID ckNew(" << paramType(1, 1) << ");\n";
01143   if (!param->isVoid()) {
01144     str << "    " << container->proxyName(0) << "(" << paramType(1, 1) << ");\n";
01145   }
01146 }
01147 
01148 void Entry::genGroupStaticConstructorDefs(XStr& str) {
01149   if (container->isForElement()) return;
01150   if (container->isForSection()) return;
01151 
01152   
01153   char* node = (char*)(container->isNodeGroup() ? "Node" : "");
01154   str << makeDecl("CkGroupID", 1) << "::ckNew(" << paramType(0, 1) << ")\n";
01155   str << "{\n";
01156   str << marshallMsg();
01157   str << "  UsrToEnv(impl_msg)->setMsgtype(" << node << "BocInitMsg);\n";
01158   str << "  CkGroupID gId = CkCreate" << node << "Group(" << chareIdx() << ", " << epIdx()
01159       << ", impl_msg);\n";
01160 
01161   genTramInstantiation(str);
01162 
01163   str << "  return gId;\n";
01164   str << "}\n";
01165 
01166   if (!param->isVoid()) {
01167     str << makeDecl(" ", 1) << "::" << container->proxyName(0) << "(" << paramType(0, 1)
01168         << ")\n";
01169     str << "{\n";
01170     str << marshallMsg();
01171     str << "  UsrToEnv(impl_msg)->setMsgtype(" << node << "BocInitMsg);\n";
01172     str << "  ckSetGroupID(CkCreate" << node << "Group(" << chareIdx() << ", " << epIdx()
01173         << ", impl_msg));\n";
01174     str << "}\n";
01175   }
01176 }
01177 
01178 
01179 void Entry::genPythonDecls(XStr& str) {
01180   str << "/* STATIC DECLS: ";
01181   print(str);
01182   str << " */\n";
01183   if (isPython()) {
01184     str << "PyObject *_Python_" << container->baseName() << "_" << name
01185         << "(PyObject *self, PyObject *arg);\n";
01186   }
01187 }
01188 
01189 void Entry::genPythonDefs(XStr& str) {
01190   str << "/* DEFS: ";
01191   print(str);
01192   str << " */\n";
01193   if (isPython()) {
01194     str << "PyObject *_Python_" << container->baseName() << "_" << name
01195         << "(PyObject *self, PyObject *arg) {\n";
01196     str << "  PyObject *dict = PyModule_GetDict(PyImport_AddModule(\"__main__\"));\n";
01197     str << "  int pyNumber = "
01198            "PyInt_AsLong(PyDict_GetItemString(dict,\"__charmNumber__\"));\n";
01199     str << "  PythonObject *pythonObj = (PythonObject "
01200            "*)PyLong_AsVoidPtr(PyDict_GetItemString(dict,\"__charmObject__\"));\n";
01201     str << "  " << container->baseName() << " *object = static_cast<"
01202         << container->baseName() << "*>(pythonObj);\n";
01203     str << "  object->pyWorkers[pyNumber].arg=arg;\n";
01204     str << "  object->pyWorkers[pyNumber].result=&CtvAccess(pythonReturnValue);\n";
01205     str << "  object->pyWorkers[pyNumber].pythread=PyThreadState_Get();\n";
01206     str << "  CtvAccess(pythonReturnValue) = 0;\n";
01207 
01208     str << "  //pyWorker->thisProxy." << name << "(pyNumber);\n";
01209     str << "  object->" << name << "(pyNumber);\n";
01210 
01211     str << "  //CthSuspend();\n";
01212 
01213     str << "  if (CtvAccess(pythonReturnValue)) {\n";
01214     str << "    return CtvAccess(pythonReturnValue);\n";
01215     str << "  } else {\n";
01216     str << "    Py_INCREF(Py_None); return Py_None;\n";
01217     str << "  }\n";
01218     str << "}\n";
01219   }
01220 }
01221 
01222 void Entry::genPythonStaticDefs(XStr& str) {
01223   if (isPython()) {
01224     str << "  {\"" << name << "\",_Python_" << container->baseName() << "_" << name
01225         << ",METH_VARARGS},\n";
01226   }
01227 }
01228 
01229 void Entry::genPythonStaticDocs(XStr& str) {
01230   if (isPython()) {
01231     str << "\n  \"" << name << " -- \"";
01232     if (pythonDoc) str << (char*)pythonDoc;
01233     str << "\"\\\\n\"";
01234   }
01235 }
01236 
01237 
01238 
01239 void Entry::genAccelFullParamList(XStr& str, int makeRefs) {
01240   if (!isAccel()) return;
01241 
01242   ParamList* curParam = NULL;
01243   int isFirst = 1;
01244 
01245   
01246   curParam = param;
01247   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01248     curParam = curParam->next;
01249   }
01250   while (curParam != NULL) {
01251     if (!isFirst) {
01252       str << ", ";
01253     }
01254 
01255     Parameter* param = curParam->param;
01256 
01257     if (param->isArray()) {
01258       str << param->getType()->getBaseName() << "* " << param->getName();
01259     } else {
01260       str << param->getType()->getBaseName() << " " << param->getName();
01261     }
01262 
01263     isFirst = 0;
01264     curParam = curParam->next;
01265   }
01266 
01267   
01268   curParam = accelParam;
01269   while (curParam != NULL) {
01270     if (!isFirst) {
01271       str << ", ";
01272     }
01273 
01274     Parameter* param = curParam->param;
01275     int bufType = param->getAccelBufferType();
01276     int needWrite = makeRefs && ((bufType == Parameter::ACCEL_BUFFER_TYPE_READWRITE) ||
01277                                  (bufType == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY));
01278     if (param->isArray()) {
01279       str << param->getType()->getBaseName() << "* " << param->getName();
01280     } else {
01281       str << param->getType()->getBaseName() << ((needWrite) ? (" &") : (" "))
01282           << param->getName();
01283     }
01284 
01285     isFirst = 0;
01286     curParam = curParam->next;
01287   }
01288 
01289   
01290   if (!isFirst) {
01291     str << ", ";
01292   }
01293   str << container->baseName() << "* impl_obj";
01294 }
01295 
01296 void Entry::genAccelFullCallList(XStr& str) {
01297   if (!isAccel()) return;
01298 
01299   int isFirstFlag = 1;
01300 
01301   
01302   ParamList* curParam = param;
01303   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01304     curParam = curParam->next;
01305   }
01306   while (curParam != NULL) {
01307     if (!isFirstFlag) str << ", ";
01308     isFirstFlag = 0;
01309     str << curParam->param->getName();
01310     curParam = curParam->next;
01311   }
01312 
01313   
01314   
01315   curParam = accelParam;
01316   while (curParam != NULL) {
01317     if (!isFirstFlag) str << ", ";
01318     isFirstFlag = 0;
01319     str << (*(curParam->param->getAccelInstName()));
01320     curParam = curParam->next;
01321   }
01322 
01323   
01324   if (!isFirstFlag) str << ", ";
01325   isFirstFlag = 0;
01326   str << "impl_obj";
01327 }
01328 
01329 void Entry::genAccelIndexWrapperDecl_general(XStr& str) {
01330   str << "    static void _accelCall_general_" << epStr() << "(";
01331   genAccelFullParamList(str, 1);
01332   str << ");\n";
01333 }
01334 
01335 void Entry::genAccelIndexWrapperDef_general(XStr& str) {
01336   str << makeDecl("void") << "::_accelCall_general_" << epStr() << "(";
01337   genAccelFullParamList(str, 1);
01338   str << ") {\n\n";
01339 
01341   
01342   
01343   
01344   
01345 
01346   str << (*accelCodeBody);
01347 
01348   str << "\n\n";
01349   str << "  impl_obj->" << (*accelCallbackName) << "();\n";
01350   str << "}\n";
01351 }
01352 
01353 void Entry::genAccelIndexWrapperDecl_spe(XStr& str) {
01354   
01355   str << "    static void _accelCall_spe_" << epStr() << "(";
01356   genAccelFullParamList(str, 0);
01357   str << ");\n";
01358 
01359   
01360   str << "    static void _accelCall_spe_callback_" << epStr() << "(void* userPtr);\n";
01361 }
01362 
01363 
01364 #if CMK_CELL != 0
01365 #include "spert.h"
01366 #endif
01367 
01368 void Entry::genAccelIndexWrapperDef_spe(XStr& str) {
01369   XStr containerType = container->baseName();
01370 
01371   
01372   str << "\n\n";
01373 
01375 
01376   str << "typedef struct __spe_callback_struct_" << epStr() << " {\n"
01377       << "  " << containerType << "* impl_obj;\n"
01378       << "  WRHandle wrHandle;\n"
01379       << "  void* scalar_buf_ptr;\n";
01380 
01381   
01382   ParamList* curParam = param;
01383   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01384     curParam = curParam->next;
01385   }
01386   while (curParam != NULL) {
01387     if (curParam->param->isArray()) {
01388       str << "  void* param_buf_ptr_" << curParam->param->getName() << ";\n";
01389     }
01390     curParam = curParam->next;
01391   }
01392   curParam = accelParam;
01393   while (curParam != NULL) {
01394     if (curParam->param->isArray()) {
01395       str << "  void* accelParam_buf_ptr_" << curParam->param->getName() << ";\n";
01396     }
01397     curParam = curParam->next;
01398   }
01399 
01400   str << "} SpeCallbackStruct_" << epStr() << ";\n\n";
01401 
01403 
01404   str << "void _accelCall_spe_callback_" << container->baseName() << "_" << epStr()
01405       << "(void* userPtr) {\n"
01406       << "  " << container->indexName() << "::_accelCall_spe_callback_" << epStr()
01407       << "(userPtr);\n"
01408       << "}\n";
01409 
01410   str << makeDecl("void") << "::_accelCall_spe_callback_" << epStr()
01411       << "(void* userPtr) {\n";
01412   str << "  SpeCallbackStruct_" << epStr() << "* cbStruct = (SpeCallbackStruct_"
01413       << epStr() << "*)userPtr;\n";
01414   str << "  " << containerType << "* impl_obj = cbStruct->impl_obj;\n";
01415 
01416   
01417 
01418   if (accel_numScalars > 0) {
01419     
01420     int dmaList_scalarBufIndex = 0;
01421     if (accel_dmaList_scalarNeedsWrite) {
01422       dmaList_scalarBufIndex += accel_dmaList_numReadOnly;
01423     }
01424     str << "  char* __scalar_buf_offset = (char*)(cbStruct->scalar_buf_ptr);\n";
01425 
01426     
01427     curParam = param;
01428     if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01429       curParam = curParam->next;
01430     }
01431     while (curParam != NULL) {
01432       if (!(curParam->param->isArray())) {
01433         str << "  __scalar_buf_offset += sizeof("
01434             << curParam->param->getType()->getBaseName() << ");\n";
01435       }
01436       curParam = curParam->next;
01437     }
01438 
01439     
01440     curParam = accelParam;
01441     while (curParam != NULL) {
01442       if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01443                                               Parameter::ACCEL_BUFFER_TYPE_READONLY)) {
01444         str << "  __scalar_buf_offset += sizeof("
01445             << curParam->param->getType()->getBaseName() << ");\n";
01446       }
01447       curParam = curParam->next;
01448     }
01449 
01450     
01451     curParam = accelParam;
01452     while (curParam != NULL) {
01453       if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01454                                               Parameter::ACCEL_BUFFER_TYPE_READWRITE)) {
01455         str << "  " << (*(curParam->param->getAccelInstName())) << " = *(("
01456             << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01457         str << "  __scalar_buf_offset += sizeof("
01458             << curParam->param->getType()->getBaseName() << ");\n";
01459       }
01460       curParam = curParam->next;
01461     }
01462 
01463     
01464     curParam = accelParam;
01465     while (curParam != NULL) {
01466       if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01467                                               Parameter::ACCEL_BUFFER_TYPE_WRITEONLY)) {
01468         str << "  " << (*(curParam->param->getAccelInstName())) << " = *(("
01469             << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01470         str << "  __scalar_buf_offset += sizeof("
01471             << curParam->param->getType()->getBaseName() << ");\n";
01472       }
01473       curParam = curParam->next;
01474     }
01475   }
01476 
01477   
01478   str << "  (cbStruct->impl_obj)->" << (*accelCallbackName) << "();\n";
01479 
01480   
01481   str << "  if (cbStruct->scalar_buf_ptr != NULL) { "
01482          "free_aligned(cbStruct->scalar_buf_ptr); }\n";
01483   curParam = param;
01484   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01485     curParam = curParam->next;
01486   }
01487   while (curParam != NULL) {
01488     if (curParam->param->isArray()) {
01489       str << "  if (cbStruct->param_buf_ptr_" << curParam->param->getName()
01490           << " != NULL) { "
01491           << "free_aligned(cbStruct->param_buf_ptr_" << curParam->param->getName()
01492           << "); "
01493           << "}\n";
01494     }
01495     curParam = curParam->next;
01496   }
01497   str << "  delete cbStruct;\n";
01498 
01499   str << "}\n\n";
01500 
01502 
01503   str << makeDecl("void") << "::_accelCall_spe_" << epStr() << "(";
01504   genAccelFullParamList(str, 0);
01505   str << ") {\n\n";
01506 
01508   
01509   
01510   
01511   
01512   
01513 
01514   str << "  // Allocate a user structure to be passed to the callback function\n"
01515       << "  SpeCallbackStruct_" << epStr() << "* cbStruct = new SpeCallbackStruct_"
01516       << epStr() << ";\n"
01517       << "  cbStruct->impl_obj = impl_obj;\n"
01518       << "  cbStruct->wrHandle = INVALID_WRHandle;  // NOTE: Set actual value later...\n"
01519       << "  cbStruct->scalar_buf_ptr = NULL;\n";
01520   
01521   curParam = param;
01522   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01523     curParam = curParam->next;
01524   }
01525   while (curParam != NULL) {
01526     if (curParam->param->isArray()) {
01527       str << "  cbStruct->param_buf_ptr_" << curParam->param->getName() << " = NULL;\n";
01528     }
01529     curParam = curParam->next;
01530   }
01531   curParam = accelParam;
01532   while (curParam != NULL) {
01533     if (curParam->param->isArray()) {
01534       str << "  cbStruct->accelParam_buf_ptr_" << curParam->param->getName()
01535           << " = NULL;\n";
01536     }
01537     curParam = curParam->next;
01538   }
01539   str << "\n";
01540 
01541   
01542   int dmaList_curIndex = 0;
01543   int numDMAListEntries = accel_numArrays;
01544   if (accel_numScalars > 0) {
01545     numDMAListEntries++;
01546   }
01547   if (numDMAListEntries <= 0) {
01548     XLAT_ERROR_NOCOL("accel entry with no parameters", first_line_);
01549   }
01550 
01551 
01552 
01553 
01554 
01555 
01556 #if CMK_CELL != 0
01557   if (numDMAListEntries > SPE_DMA_LIST_LENGTH) {
01558     die("Accel entries do not support parameter lists of length > SPE_DMA_LIST_LENGTH "
01559         "yet... fix me...");
01560   }
01561 #endif
01562 
01563   
01564   if (accel_numScalars > 0) {
01565     str << "  // Create a single buffer to hold all the scalar values\n";
01566     str << "  int scalar_buf_len = 0;\n";
01567     curParam = param;
01568     if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01569       curParam = curParam->next;
01570     }
01571     while (curParam != NULL) {
01572       if (!(curParam->param->isArray())) {
01573         str << "  scalar_buf_len += sizeof(" << curParam->param->getType()->getBaseName()
01574             << ");\n";
01575       }
01576       curParam = curParam->next;
01577     }
01578     curParam = accelParam;
01579     while (curParam != NULL) {
01580       if (!(curParam->param->isArray())) {
01581         str << "  scalar_buf_len += sizeof(" << curParam->param->getType()->getBaseName()
01582             << ");\n";
01583       }
01584       curParam = curParam->next;
01585     }
01586     str << "  scalar_buf_len = ROUNDUP_128(scalar_buf_len);\n"
01587         << "  cbStruct->scalar_buf_ptr = malloc_aligned(scalar_buf_len, 128);\n"
01588         << "  char* scalar_buf_offset = (char*)(cbStruct->scalar_buf_ptr);\n\n";
01589   }
01590 
01591   
01592   str << "  // Declare and populate the DMA list for the work request\n";
01593   str << "  DMAListEntry dmaList[" << numDMAListEntries << "];\n\n";
01594 
01595   
01596   
01597   curParam = param;
01598   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01599     curParam = curParam->next;
01600   }
01601   while (curParam != NULL) {
01602     
01603     if (accel_numScalars > 0) {
01604       if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
01605           ((dmaList_curIndex == accel_dmaList_numReadOnly) &&
01606            (accel_dmaList_scalarNeedsWrite))) {
01607         str << "  /*** Scalar Buffer ***/\n"
01608             << "  dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
01609             << "  dmaList[" << dmaList_curIndex
01610             << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
01611         dmaList_curIndex++;
01612       }
01613     }
01614 
01615     
01616     str << "  /*** Param: '" << curParam->param->getName() << "' ***/\n";
01617     if (curParam->param->isArray()) {
01618       str << "  {\n"
01619           << "    int bufSize = sizeof(" << curParam->param->getType()->getBaseName()
01620           << ") * (" << curParam->param->getArrayLen() << ");\n"
01621           << "    bufSize = ROUNDUP_128(bufSize);\n"
01622           << "    cbStruct->param_buf_ptr_" << curParam->param->getName()
01623           << " = malloc_aligned(bufSize, 128);\n"
01624           << "    memcpy(cbStruct->param_buf_ptr_" << curParam->param->getName() << ", "
01625           << curParam->param->getName() << ", bufSize);\n"
01626           << "    dmaList[" << dmaList_curIndex << "].size = bufSize;\n"
01627           << "    dmaList[" << dmaList_curIndex
01628           << "].ea = (unsigned int)(cbStruct->param_buf_ptr_"
01629           << curParam->param->getName() << ");\n"
01630           << "  }\n";
01631       dmaList_curIndex++;
01632     } else {
01633       str << "  *((" << curParam->param->getType()->getBaseName()
01634           << "*)scalar_buf_offset) = " << curParam->param->getName() << ";\n"
01635           << "  scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName()
01636           << ");\n";
01637     }
01638     curParam = curParam->next;
01639     str << "\n";
01640   }
01641 
01642   
01643   curParam = accelParam;
01644   while (curParam != NULL) {
01645     
01646     if (accel_numScalars > 0) {
01647       if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
01648           ((dmaList_curIndex == accel_dmaList_numReadOnly) &&
01649            (accel_dmaList_scalarNeedsWrite))) {
01650         str << "  /*** Scalar Buffer ***/\n"
01651             << "  dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
01652             << "  dmaList[" << dmaList_curIndex
01653             << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
01654         dmaList_curIndex++;
01655       }
01656     }
01657 
01658     
01659     if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY) {
01660       str << "  /*** Accel Param: '" << curParam->param->getName() << " ("
01661           << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
01662       if (curParam->param->isArray()) {
01663         str << "  dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
01664             << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
01665             << "(" << curParam->param->getArrayLen() << "));\n"
01666             << "  dmaList[" << dmaList_curIndex << "].ea = (unsigned int)("
01667             << (*(curParam->param->getAccelInstName())) << ");\n";
01668         dmaList_curIndex++;
01669       } else {
01670         str << "  *((" << curParam->param->getType()->getBaseName()
01671             << "*)scalar_buf_offset) = " << (*(curParam->param->getAccelInstName()))
01672             << ";\n"
01673             << "  scalar_buf_offset += sizeof("
01674             << curParam->param->getType()->getBaseName() << ");\n";
01675       }
01676       str << "\n";
01677     }
01678 
01679     curParam = curParam->next;
01680   }
01681 
01682   
01683   curParam = accelParam;
01684   while (curParam != NULL) {
01685     
01686     if (accel_numScalars > 0) {
01687       if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
01688           ((dmaList_curIndex == accel_dmaList_numReadOnly) &&
01689            (accel_dmaList_scalarNeedsWrite))) {
01690         str << "  /*** Scalar Buffer ***/\n"
01691             << "  dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
01692             << "  dmaList[" << dmaList_curIndex
01693             << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
01694         dmaList_curIndex++;
01695       }
01696     }
01697 
01698     
01699     if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE) {
01700       str << "  /*** Accel Param: '" << curParam->param->getName() << " ("
01701           << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
01702       if (curParam->param->isArray()) {
01703         str << "  dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
01704             << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
01705             << "(" << curParam->param->getArrayLen() << "));\n"
01706             << "  dmaList[" << dmaList_curIndex << "].ea = (unsigned int)("
01707             << (*(curParam->param->getAccelInstName())) << ");\n";
01708         dmaList_curIndex++;
01709       } else {
01710         str << "  *((" << curParam->param->getType()->getBaseName()
01711             << "*)scalar_buf_offset) = " << (*(curParam->param->getAccelInstName()))
01712             << ";\n"
01713             << "  scalar_buf_offset += sizeof("
01714             << curParam->param->getType()->getBaseName() << ");\n";
01715       }
01716       str << "\n";
01717     }
01718 
01719     curParam = curParam->next;
01720   }
01721 
01722   
01723   curParam = accelParam;
01724   while (curParam != NULL) {
01725     
01726     if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY) {
01727       str << "  /*** Accel Param: '" << curParam->param->getName() << " ("
01728           << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
01729       if (curParam->param->isArray()) {
01730         str << "  dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
01731             << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
01732             << "(" << curParam->param->getArrayLen() << "));\n"
01733             << "  dmaList[" << dmaList_curIndex << "].ea = (unsigned int)("
01734             << (*(curParam->param->getAccelInstName())) << ");\n";
01735         dmaList_curIndex++;
01736       } else {
01737         str << "  *((" << curParam->param->getType()->getBaseName()
01738             << "*)scalar_buf_offset) = " << (*(curParam->param->getAccelInstName()))
01739             << ";\n"
01740             << "  scalar_buf_offset += sizeof("
01741             << curParam->param->getType()->getBaseName() << ");\n";
01742       }
01743       str << "\n";
01744     }
01745 
01746     curParam = curParam->next;
01747   }
01748 
01749   str << "  // Issue the work request\n";
01750   str << "  cbStruct->wrHandle = sendWorkRequest_list(accel_spe_func_index__" << epStr()
01751       << ",\n"
01752       << "                                            0,\n"
01753       << "                                            dmaList,\n"
01754       << "                                            " << accel_dmaList_numReadOnly
01755       << ",\n"
01756       << "                                            " << accel_dmaList_numReadWrite
01757       << ",\n"
01758       << "                                            " << accel_dmaList_numWriteOnly
01759       << ",\n"
01760       << "                                            cbStruct,\n"
01761       << "                                            WORK_REQUEST_FLAGS_NONE,\n"
01762       << "                                            _accelCall_spe_callback_"
01763       << container->baseName() << "_" << epStr() << "\n"
01764       << "                                           );\n";
01765 
01766   str << "}\n\n";
01767 
01768   
01769   str << "\n";
01770 }
01771 
01772 int Entry::genAccels_spe_c_funcBodies(XStr& str) {
01773   
01774   if (!isAccel()) {
01775     return 0;
01776   }
01777 
01778   
01779   str << "void __speFunc__" << indexName() << "__" << epStr()
01780       << "(DMAListEntry* dmaList) {\n";
01781 
01782   ParamList* curParam = NULL;
01783   int dmaList_curIndex = 0;
01784 
01785   
01786   if (accel_numScalars > 0) {
01787     if (accel_dmaList_scalarNeedsWrite) {
01788       str << "  void* __scalar_buf_ptr = (void*)(dmaList[" << accel_dmaList_numReadOnly
01789           << "].ea);\n";
01790     } else {
01791       str << "  void* __scalar_buf_ptr = (void*)(dmaList[0].ea);\n";
01792       dmaList_curIndex++;
01793     }
01794     str << "  char* __scalar_buf_offset = (char*)(__scalar_buf_ptr);\n";
01795   }
01796 
01797   
01798   curParam = param;
01799   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01800     curParam = curParam->next;
01801   }
01802   while (curParam != NULL) {
01803     if (curParam->param->isArray()) {
01804       str << "  " << curParam->param->getType()->getBaseName() << "* "
01805           << curParam->param->getName() << " = ("
01806           << curParam->param->getType()->getBaseName() << "*)(dmaList["
01807           << dmaList_curIndex << "].ea);\n";
01808       dmaList_curIndex++;
01809     } else {
01810       str << "  " << curParam->param->getType()->getBaseName() << " "
01811           << curParam->param->getName() << " = *(("
01812           << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01813       str << "  __scalar_buf_offset += sizeof("
01814           << curParam->param->getType()->getBaseName() << ");\n";
01815     }
01816     curParam = curParam->next;
01817   }
01818 
01819   
01820   curParam = accelParam;
01821   while (curParam != NULL) {
01822     if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY) {
01823       if (curParam->param->isArray()) {
01824         str << "  " << curParam->param->getType()->getBaseName() << "* "
01825             << curParam->param->getName() << " = ("
01826             << curParam->param->getType()->getBaseName() << "*)(dmaList["
01827             << dmaList_curIndex << "].ea);\n";
01828         dmaList_curIndex++;
01829       } else {
01830         str << "  " << curParam->param->getType()->getBaseName() << " "
01831             << curParam->param->getName() << " = *(("
01832             << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01833         str << "  __scalar_buf_offset += sizeof("
01834             << curParam->param->getType()->getBaseName() << ");\n";
01835       }
01836     }
01837     curParam = curParam->next;
01838   }
01839 
01840   
01841   dmaList_curIndex = accel_dmaList_numReadOnly;
01842   if ((accel_numScalars > 0) && (accel_dmaList_scalarNeedsWrite)) {
01843     dmaList_curIndex++;
01844   }
01845 
01846   
01847   curParam = accelParam;
01848   while (curParam != NULL) {
01849     if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE) {
01850       if (curParam->param->isArray()) {
01851         str << "  " << curParam->param->getType()->getBaseName() << "* "
01852             << curParam->param->getName() << " = ("
01853             << curParam->param->getType()->getBaseName() << "*)(dmaList["
01854             << dmaList_curIndex << "].ea);\n";
01855         dmaList_curIndex++;
01856       } else {
01857         str << "  " << curParam->param->getType()->getBaseName() << " "
01858             << curParam->param->getName() << " = *(("
01859             << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01860         str << "  __scalar_buf_offset += sizeof("
01861             << curParam->param->getType()->getBaseName() << ");\n";
01862       }
01863     }
01864     curParam = curParam->next;
01865   }
01866 
01867   
01868   curParam = accelParam;
01869   while (curParam != NULL) {
01870     if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY) {
01871       if (curParam->param->isArray()) {
01872         str << "  " << curParam->param->getType()->getBaseName() << "* "
01873             << curParam->param->getName() << " = ("
01874             << curParam->param->getType()->getBaseName() << "*)(dmaList["
01875             << dmaList_curIndex << "].ea);\n";
01876         dmaList_curIndex++;
01877       } else {
01878         str << "  " << curParam->param->getType()->getBaseName() << " "
01879             << curParam->param->getName() << " = *(("
01880             << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01881         str << "  __scalar_buf_offset += sizeof("
01882             << curParam->param->getType()->getBaseName() << ");\n";
01883       }
01884     }
01885     curParam = curParam->next;
01886   }
01887 
01888   
01889   str << "  {\n    " << (*accelCodeBody) << "\n  }\n";
01890 
01891   
01892   if ((accel_numScalars > 0) && (accel_dmaList_scalarNeedsWrite)) {
01893     str << "  __scalar_buf_offset = (char*)(__scalar_buf_ptr);\n";
01894 
01895     
01896     curParam = param;
01897     if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01898       curParam = curParam->next;
01899     }
01900     while (curParam != NULL) {
01901       if (!(curParam->param->isArray())) {
01902         str << "  __scalar_buf_offset += sizeof("
01903             << curParam->param->getType()->getBaseName() << ");\n";
01904       }
01905       curParam = curParam->next;
01906     }
01907 
01908     
01909     curParam = accelParam;
01910     while (curParam != NULL) {
01911       if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01912                                               Parameter::ACCEL_BUFFER_TYPE_READONLY)) {
01913         str << "  __scalar_buf_offset += sizeof("
01914             << curParam->param->getType()->getBaseName() << ");\n";
01915       }
01916       curParam = curParam->next;
01917     }
01918 
01919     
01920     curParam = accelParam;
01921     while (curParam != NULL) {
01922       if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01923                                               Parameter::ACCEL_BUFFER_TYPE_READWRITE)) {
01924         str << "  *((" << curParam->param->getType()->getBaseName()
01925             << "*)__scalar_buf_offset) = " << curParam->param->getName() << ";\n";
01926         str << "  __scalar_buf_offset += sizeof("
01927             << curParam->param->getType()->getBaseName() << ");\n";
01928       }
01929       curParam = curParam->next;
01930     }
01931 
01932     
01933     curParam = accelParam;
01934     while (curParam != NULL) {
01935       if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01936                                               Parameter::ACCEL_BUFFER_TYPE_WRITEONLY)) {
01937         str << "  *((" << curParam->param->getType()->getBaseName()
01938             << "*)__scalar_buf_offset) = " << curParam->param->getName() << ";\n";
01939         str << "  __scalar_buf_offset += sizeof("
01940             << curParam->param->getType()->getBaseName() << ");\n";
01941       }
01942       curParam = curParam->next;
01943     }
01944   }
01945 
01946   str << "}\n\n\n";
01947 
01948   return 1;
01949 }
01950 
01951 void Entry::genAccels_spe_c_regFuncs(XStr& str) {
01952   if (isAccel()) {
01953     str << "  funcLookupTable[curIndex  ].funcIndex = curIndex;\n"
01954         << "  funcLookupTable[curIndex++].funcPtr = __speFunc__" << indexName() << "__"
01955         << epStr() << ";\n";
01956   }
01957 }
01958 
01959 void Entry::genAccels_ppe_c_regFuncs(XStr& str) {
01960   if (isAccel()) {
01961     str << "  " << indexName() << "::accel_spe_func_index__" << epStr()
01962         << " = curIndex++;\n";
01963   }
01964 }
01965 
01966 
01967 void Entry::genIndexDecls(XStr& str) {
01968   str << "    /* DECLS: ";
01969   print(str);
01970   str << "     */";
01971 
01972   XStr templateSpecLine;
01973   templateSpecLine << "\n    " << generateTemplateSpec(tspec);
01974 
01975   
01976   str << "\n    // Entry point registration at startup" << templateSpecLine
01977       << "\n    static int reg_" << epStr()
01978       << "();"  
01979       << "\n    // Entry point index lookup" << templateSpecLine
01980       << "\n    inline static int idx_" << epStr() << "() {"
01981       << "\n      static int epidx = " << epRegFn(0) << ";"
01982       << "\n      return epidx;"
01983       << "\n    }\n";
01984 
01985   if (!isConstructor()) {
01986     str << templateSpecLine << "\n    inline static int idx_" << name << "(" << retType
01987         << " (" << container->baseName() << "::*)(";
01988     if (param) param->print(str);
01989     str << ") ) {"
01990         << "\n      return " << epIdx(0) << ";"
01991         << "\n    }\n\n";
01992   }
01993 
01994 
01995 #if CMK_CELL != 0
01996   if (isAccel()) {
01997     str << "    static int accel_spe_func_index__" << epStr() << ";\n";
01998   }
01999 #endif
02000 
02001   
02002   str << templateSpecLine << "\n    static int ";
02003   if (isConstructor())
02004     str << "ckNew";
02005   else
02006     str << name;
02007   str << "(" << paramType(1, 0) << ") { return " << epIdx(0) << "; }";
02008 
02009   
02010   if (isAccel()) {
02011     genAccelIndexWrapperDecl_general(str);
02012 #if CMK_CELL != 0
02013     genAccelIndexWrapperDecl_spe(str);
02014 #endif
02015   }
02016 
02017   if (isReductionTarget()) {
02018     str << "\n    // Entry point registration at startup" << templateSpecLine
02019         << "\n    static int reg_" << epStr(true)
02020         << "();"  
02021         << "\n    // Entry point index lookup" << templateSpecLine
02022         << "\n    inline static int idx_" << epStr(true) << "() {"
02023         << "\n      static int epidx = " << epRegFn(0, true) << ";"
02024         << "\n      return epidx;"
02025         << "\n    }" << templateSpecLine << "\n    static int "
02026         << "redn_wrapper_" << name << "(CkReductionMsg* impl_msg) { return "
02027         << epIdx(0, true) << "; }" << templateSpecLine << "\n    static void _call_"
02028         << epStr(true) << "(void* impl_msg, void* impl_obj_void);";
02029   }
02030 
02031   
02032   str << templateSpecLine << "\n    static void _call_" << epStr()
02033       << "(void* impl_msg, void* impl_obj);";
02034   str << templateSpecLine << "\n    static void _call_sdag_" << epStr()
02035       << "(void* impl_msg, void* impl_obj);";
02036   if (isThreaded()) {
02037     str << templateSpecLine << "\n    static void _callthr_" << epStr()
02038         << "(CkThrCallArg *);";
02039   }
02040   if (hasCallMarshall) {
02041     str << templateSpecLine << "\n    static int _callmarshall_" << epStr()
02042         << "(char* impl_buf, void* impl_obj_void);";
02043   }
02044   if (param->isMarshalled()) {
02045     str << templateSpecLine << "\n    static void _marshallmessagepup_" << epStr()
02046         << "(PUP::er &p,void *msg);";
02047   }
02048   str << "\n";
02049 }
02050 
02051 void Entry::genDecls(XStr& str) {
02052   if (external) return;
02053 
02054   str << "/* DECLS: ";
02055   print(str);
02056   str << " */\n";
02057 
02058   if (isMigrationConstructor()) {
02059   }  
02060   else if (container->isGroup()) {
02061     genGroupDecl(str);
02062   } else if (container->isArray()) {
02063     if (!isIget())
02064       genArrayDecl(str);
02065     else if (container->isForElement())
02066       genArrayDecl(str);
02067   } else {  
02068     genChareDecl(str);
02069   }
02070 }
02071 
02072 void Entry::genClosureEntryDecls(XStr& str) { genClosure(str, false); }
02073 
02074 void Entry::genClosureEntryDefs(XStr& str) {
02075   templateGuardBegin(tspec || container->isTemplated(), str);
02076   genClosure(str, true);
02077   templateGuardEnd(str);
02078 }
02079 
02080 void Entry::genClosure(XStr& decls, bool isDef) {
02081   if (isConstructor() || (isLocal() && !sdagCon)) return;
02082 
02083   bool hasArray = false, isMessage = false, hasRdma = false;
02084   XStr messageType;
02085   int i = 0, addNumRdmaFields = 1;
02086   XStr structure, toPup, alloc, getter, dealloc;
02087   for (ParamList *pl = param; pl != NULL; pl = pl->next, i++) {
02088     Parameter* sv = pl->param;
02089 
02090     if (XStr(sv->type->getBaseName()) == "CkArrayOptions") continue;
02091 
02092     structure << "      ";
02093     getter << "      ";
02094 
02095     if ((sv->isMessage() != 1) && (sv->isVoid() != 1)) {
02096       if (sv->isRdma()) {
02097         hasRdma = hasRdma || true;
02098         structure << "\n#if CMK_ONESIDED_IMPL\n";
02099         if (sv->isFirstRdma())
02100           structure << "      "
02101                     << "int num_rdma_fields;\n";
02102         structure << "      "
02103                   << "CkNcpyBuffer "
02104                   << "ncpyBuffer_" << sv->name << ";\n";
02105         structure << "#else\n";
02106         structure << "      " << sv->type << " "
02107                   << "*" << sv->name << ";\n";
02108         structure << "#endif\n";
02109         if (sv->isFirstRdma()) {
02110           getter << "#if CMK_ONESIDED_IMPL\n";
02111           getter << "      "
02112                  << "int "
02113                  << "& "
02114                  << "getP" << i << "() { return "
02115                  << " num_rdma_fields;}\n";
02116           getter << "#endif\n";
02117           i++;
02118         }
02119         getter << "#if CMK_ONESIDED_IMPL\n";
02120         getter << "      "
02121                << "CkNcpyBuffer "
02122                << "& "
02123                << "getP" << i << "() { return "
02124                << "ncpyBuffer_" << sv->name << ";}\n";
02125         getter << "#else\n";
02126         getter << sv->type << " "
02127                << "*";
02128         getter << "& "
02129                << "getP" << i << "() { return " << sv->name << ";}\n";
02130         getter << "#endif\n";
02131         toPup << "#if CMK_ONESIDED_IMPL\n";
02132         if (sv->isFirstRdma()) {
02133           toPup << "          char *impl_buf = _impl_marshall ? _impl_marshall->msgBuf : "
02134                    "_impl_buf_in;\n";
02135           toPup << "        "
02136                 << "__p | "
02137                 << "num_rdma_fields;\n";
02138         }
02139         
02140 
02141 
02142 
02143 
02144         toPup << "        if (__p.isPacking()) {\n";
02145         toPup << "          ncpyBuffer_" << sv->name << ".ptr = ";
02146         toPup << "(void *)((char *)(ncpyBuffer_" << sv->name << ".ptr) - impl_buf);\n";
02147         toPup << "        }\n";
02148         toPup << "        "
02149               << "__p | "
02150               << "ncpyBuffer_" << sv->name << ";\n";
02151         toPup << "#endif\n";
02152       } else {
02153         structure << "      ";
02154         getter << "      ";
02155         structure << sv->type << " ";
02156         getter << sv->type << " ";
02157       }
02158 
02159       if (sv->isArray() != 0) {
02160         structure << "*";
02161         getter << "*";
02162       }
02163       if (sv->isArray() != 0) {
02164         hasArray = hasArray || true;
02165       } else if (!sv->isRdma()) {
02166         toPup << "        "
02167               << "__p | " << sv->name << ";\n";
02168         sv->podType = true;
02169       }
02170 
02171       if (sv->name != 0) {
02172         if (!sv->isRdma()) {
02173           structure << sv->name << ";\n";
02174           getter << "& "
02175                  << "getP" << i << "() { return " << sv->name << ";}\n";
02176         }
02177       }
02178 
02179     } else if (sv->isVoid() != 1) {
02180       if (sv->isMessage()) {
02181         isMessage = true;
02182         if (sv->isRdma()) {
02183           structure << "CkNcpyBuffer"
02184                     << " "
02185                     << "ncpyBuffer_" << sv->name << ";\n";
02186         } else {
02187           structure << sv->type << " " << sv->name << ";\n";
02188         }
02189         toPup << "        "
02190               << "CkPupMessage(__p, (void**)&" << sv->name << ");\n";
02191         messageType << sv->type->deref();
02192       }
02193     }
02194   }
02195 
02196   structure << "\n";
02197 
02198   toPup << "        packClosure(__p);\n";
02199 
02200   XStr initCode;
02201   initCode << "        init();\n";
02202 
02203   if (hasArray || hasRdma) {
02204     structure << "      "
02205               << "CkMarshallMsg* _impl_marshall;\n";
02206     structure << "      "
02207               << "char* _impl_buf_in;\n";
02208     structure << "      "
02209               << "int _impl_buf_size;\n";
02210     dealloc << "        if (_impl_marshall) CmiFree(UsrToEnv(_impl_marshall));\n";
02211     initCode << "        _impl_marshall = 0;\n";
02212     initCode << "        _impl_buf_in = 0;\n";
02213     initCode << "        _impl_buf_size = 0;\n";
02214 
02215     toPup << "        __p | _impl_buf_size;\n";
02216     toPup << "        bool hasMsg = (_impl_marshall != 0); __p | hasMsg;\n";
02217     toPup << "        "
02218           << "if (hasMsg) CkPupMessage(__p, (void**)&"
02219           << "_impl_marshall"
02220           << ");\n";
02221     toPup << "        "
02222           << "else PUParray(__p, _impl_buf_in, _impl_buf_size);\n";
02223     toPup << "        if (__p.isUnpacking()) {\n";
02224     toPup << "          char *impl_buf = _impl_marshall ? _impl_marshall->msgBuf : "
02225              "_impl_buf_in;\n";
02226     param->beginUnmarshallSDAG(toPup);
02227     toPup << "        }\n";
02228   }
02229 
02230   
02231   if (isLocal()) {
02232     toPup.clear();
02233     toPup
02234         << "        CkAbort(\"Can\'t migrate while a local SDAG method is active.\");\n";
02235   }
02236 
02237   if (!isMessage) {
02238     genClosureTypeName = new XStr();
02239     genClosureTypeNameProxy = new XStr();
02240     *genClosureTypeNameProxy << "Closure_" << container->baseName() << "::";
02241     *genClosureTypeNameProxy << name << "_" << entryCount << "_closure";
02242     *genClosureTypeName << name << "_" << entryCount << "_closure";
02243 
02244     container->sdagPUPReg << "  PUPable_reg(SINGLE_ARG(" << *genClosureTypeNameProxy
02245                           << "));\n";
02246 
02247     if (isDef) {
02248       if (container->isTemplated()) {
02249         decls << container->tspec(false) << "\n";
02250       }
02251       decls << generateTemplateSpec(tspec) << "\n";
02252       decls << "    struct " << *genClosureTypeNameProxy << " : public SDAG::Closure"
02253             << " {\n";
02254       decls << structure << "\n";
02255       decls << "      " << *genClosureTypeName << "() {\n";
02256       decls << initCode;
02257       decls << "      }\n";
02258       decls << "      " << *genClosureTypeName << "(CkMigrateMessage*) {\n";
02259       decls << initCode;
02260       decls << "      }\n";
02261       decls << getter;
02262       decls << "      void pup(PUP::er& __p) {\n";
02263       decls << toPup;
02264       decls << "      }\n";
02265       decls << "      virtual ~" << *genClosureTypeName << "() {\n";
02266       decls << dealloc;
02267       decls << "      }\n";
02268       decls << "      "
02269             << ((container->isTemplated() || tspec) ? "PUPable_decl_template"
02270                                                     : "PUPable_decl")
02271             << "(SINGLE_ARG(" << *genClosureTypeName;
02272       if (tspec) {
02273         decls << "<";
02274         tspec->genShort(decls);
02275         decls << ">";
02276       }
02277       decls << "));\n";
02278       decls << "    };\n";
02279     } else {
02280       decls << generateTemplateSpec(tspec) << "\n";
02281       decls << "    struct " << *genClosureTypeName << ";\n";
02282     }
02283   } else {
02284     genClosureTypeName = new XStr();
02285     genClosureTypeNameProxy = new XStr();
02286     *genClosureTypeNameProxy << messageType;
02287     *genClosureTypeName << messageType;
02288   }
02289 
02290   genClosureTypeNameProxyTemp = new XStr();
02291   *genClosureTypeNameProxyTemp << (container->isTemplated() ? "typename " : "")
02292                                << genClosureTypeNameProxy;
02293 }
02294 
02295 
02296 
02297 
02298 XStr Entry::callThread(const XStr& procName, int prependEntryName) {
02299   if (isConstructor() || isMigrationConstructor())
02300     die("Constructors may not be 'threaded'", first_line_);
02301 
02302   XStr str, procFull;
02303   procFull << "_callthr_";
02304   if (prependEntryName) procFull << name << "_";
02305   procFull << procName;
02306 
02307   str << "  CthThread tid = CthCreate((CthVoidFn)" << procFull
02308       << ", new CkThrCallArg(impl_msg,impl_obj), " << getStackSize() << ");\n";
02309   str << "  ((Chare *)impl_obj)->CkAddThreadListeners(tid,impl_msg);\n";
02310 
02311 #if CMK_BIGSIM_CHARM
02312   str << "  BgAttach(tid);\n";
02313 #endif
02314   str << "  CthResume(tid);\n";
02315   str << "}\n";
02316 
02317   str << makeDecl("void") << "::" << procFull << "(CkThrCallArg *impl_arg)\n";
02318   str << "{\n";
02319   str << "  void *impl_msg = impl_arg->msg;\n";
02320   str << "  void *impl_obj_void = impl_arg->obj;\n";
02321   str << "  " << container->baseName() << " *impl_obj = static_cast<"
02322       << container->baseName() << " *>(impl_obj_void);\n";
02323   str << "  delete impl_arg;\n";
02324   return str;
02325 }
02326 
02327 
02328 
02329 
02330 
02331 void Entry::genCall(XStr& str, const XStr& preCall, bool redn_wrapper, bool usesImplBuf) {
02332   bool isArgcArgv = false;
02333   bool isMigMain = false;
02334   bool isSDAGGen = sdagCon || isWhenEntry;
02335   bool needsClosure = isSDAGGen && (param->isMarshalled() ||
02336                                     (param->isVoid() && isWhenEntry && redn_wrapper));
02337 
02338   if (isConstructor() && container->isMainChare() && (!param->isVoid()) &&
02339       (!param->isCkArgMsgPtr())) {
02340     if (param->isCkMigMsgPtr())
02341       isMigMain = true;
02342     else
02343       isArgcArgv = true;
02344   } else {
02345     
02346     if (redn_wrapper)
02347       param->beginRednWrapperUnmarshall(str, needsClosure);
02348     else {
02349       if (isSDAGGen)
02350         param->beginUnmarshallSDAGCall(str, usesImplBuf);
02351       else
02352         param->beginUnmarshall(str);
02353     }
02354   }
02355 
02356   str << preCall;
02357   if (!isConstructor() && fortranMode && !isWhenEntry && !sdagCon) {
02358     if (!container->isArray()) {  
02359       cerr << (char*)container->baseName()
02360            << ": only chare arrays are currently supported\n";
02361       exit(1);
02362     }
02363     str << "/* FORTRAN */\n";
02364     XStr dim;
02365     dim << ((Array*)container)->dim();
02366     if (dim == (const char*)"1D")
02367       str << "  int index1 = impl_obj->thisIndex;\n";
02368     else if (dim == (const char*)"2D") {
02369       str << "  int index1 = impl_obj->thisIndex.x;\n";
02370       str << "  int index2 = impl_obj->thisIndex.y;\n";
02371     } else if (dim == (const char*)"3D") {
02372       str << "  int index1 = impl_obj->thisIndex.x;\n";
02373       str << "  int index2 = impl_obj->thisIndex.y;\n";
02374       str << "  int index3 = impl_obj->thisIndex.z;\n";
02375     }
02376     str << "  ::";
02377     str << fortranify(container->baseName(), "_Entry_", name);
02378     str << "((char **)(impl_obj->user_data)";
02379     str << ", &index1";
02380     if (dim == (const char*)"2D" || dim == (const char*)"3D") str << ", &index2";
02381     if (dim == (const char*)"3D") str << ", &index3";
02382     if (!param->isVoid()) {
02383       str << ", ";
02384       param->unmarshallAddress(str);
02385     }
02386     str << ");\n";
02387     str << "/* FORTRAN END */\n";
02388   }
02389 
02390   
02391   else if (isAccel()) {
02392 #if CMK_CELL != 0
02393     str << "  if (1) {   // DMK : TODO : For now, hardcode the condition (i.e. for now, "
02394            "do not dynamically load-balance between host and accelerator)\n";
02395     str << "    _accelCall_spe_" << epStr() << "(";
02396     genAccelFullCallList(str);
02397     str << ");\n";
02398     str << "  } else {\n  ";
02399 #endif
02400 
02401     str << "  _accelCall_general_" << epStr() << "(";
02402     genAccelFullCallList(str);
02403     str << ");\n";
02404 
02405 #if CMK_CELL != 0
02406     str << "  }\n";
02407 #endif
02408 
02409   }
02410 
02411   else {  
02412     if(param->hasRecvRdma()) {
02413       str << "#if CMK_ONESIDED_IMPL\n";
02414       str << "  if(CMI_IS_ZC_RECV(env) || CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_DONE_MSG) {\n";
02415       str << "#endif\n";
02416       genRegularCall(str, preCall, redn_wrapper, usesImplBuf, true);
02417       str << "#if CMK_ONESIDED_IMPL\n";
02418       str << "  else if(CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_DONE_MSG) {\n";
02419       
02420       genRegularCall(str, preCall, redn_wrapper, usesImplBuf, false);
02421       
02422       str << "    }\n";
02423       str << "  } else {\n";
02424       str << "#endif\n";
02425     }
02426     genRegularCall(str, preCall, redn_wrapper, usesImplBuf, false);
02427     if(param->hasRecvRdma()) {
02428       str << "#if CMK_ONESIDED_IMPL\n";
02429       str << "  }\n";
02430       str << "#endif\n";
02431     }
02432   }
02433 }
02434 
02435 void Entry::genRegularCall(XStr& str, const XStr& preCall, bool redn_wrapper, bool usesImplBuf, bool isRdmaPost) {
02436     bool isArgcArgv = false;
02437     bool isMigMain = false;
02438     bool isSDAGGen = sdagCon || isWhenEntry;
02439     bool needsClosure = isSDAGGen && (param->isMarshalled() ||
02440                                       (param->isVoid() && isWhenEntry && redn_wrapper));
02441 
02442 
02443 
02444     if (isArgcArgv) str << "  CkArgMsg *m=(CkArgMsg *)impl_msg;\n";  
02445 
02446     if (isMigrationConstructor() && container->isArray()) {
02447       
02448       
02449       
02450       str << "  call_migration_constructor<" << container->baseName()
02451           << "> c = impl_obj_void;\n"
02452           << "  c";
02453     } else if (isConstructor()) {  
02454       str << "  new (impl_obj_void) " << container->baseName();
02455     } else {  
02456       str << "  impl_obj->" << (tspec ? "template " : "") << (containsWhenConstruct ? "_sdag_fnc_" : "" ) << name;
02457       if (tspec) {
02458         str << "<";
02459         tspec->genShort(str);
02460         str << ">";
02461       }
02462     }
02463 
02464     if (isArgcArgv) {  
02465                        
02466       str << "(m->argc,m->argv);\n";
02467       str << "  delete m;\n";
02468     } else if (isMigMain) {
02469       str << "((CkMigrateMessage*)impl_msg);\n";
02470     } else {  
02471       if (isSDAGGen) {
02472         str << "(";
02473         if (param->isMessage()) {
02474           param->unmarshall(str, false, true, isRdmaPost);
02475         } else if (needsClosure) {
02476           if(isRdmaPost)
02477             param->unmarshall(str, false, true, isRdmaPost);
02478           else
02479             str << "genClosure";
02480         }
02481         
02482         if(isRdmaPost) str << ",ncpyPost";
02483         str << ");\n";
02484         if (needsClosure) {
02485           if(!isRdmaPost)
02486             str << "  genClosure->deref();\n";
02487         }
02488       } else {
02489         str << "(";
02490         param->unmarshall(str, false, true, isRdmaPost);
02491         
02492         if(isRdmaPost) str << ",ncpyPost";
02493         str << ");\n";
02494       }
02495       if(isRdmaPost) {
02496         str << "#if CMK_ONESIDED_IMPL\n";
02497         
02498         str << "  void *buffPtrs["<< numRdmaRecvParams <<"];\n";
02499         str << "#endif\n";
02500         param->storePostedRdmaPtrs(str, isSDAGGen);
02501         str << "#if CMK_ONESIDED_IMPL\n";
02502         str << "  if(CMI_IS_ZC_RECV(env)) \n";
02503         str << "    CkRdmaIssueRgets(env, ((CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_MSG) ? ncpyEmApiMode::BCAST_RECV : ncpyEmApiMode::P2P_RECV), NULL, ";
02504         if(isSDAGGen)
02505           str << " genClosure->num_rdma_fields, ";
02506         else
02507           str << " impl_num_rdma_fields, ";
02508         str << " buffPtrs, ncpyPost);\n";
02509         str << "#else\n";
02510 
02511         str << "#endif\n";
02512       }
02513       
02514       if(param->hasRdma() && !container->isForElement() && !isRdmaPost) {
02515         
02516         
02517         
02518         str << "#if CMK_ONESIDED_IMPL\n";
02519         if(param->hasRecvRdma())
02520           
02521           
02522           
02523           str << "  if(!CMI_IS_ZC_RECV(env) && CMI_ZC_MSGTYPE(env) != CMK_ZC_BCAST_RECV_DONE_MSG && CMI_ZC_MSGTYPE(env) != CMK_ZC_BCAST_RECV_ALL_DONE_MSG && CMI_ZC_MSGTYPE(env) != CMK_ZC_P2P_RECV_DONE_MSG)\n";
02524         str << "    CkPackRdmaPtrs(impl_buf_begin);\n";
02525         str << "#endif\n";
02526       }
02527     }
02528 }
02529 
02530 void Entry::genDefs(XStr& str) {
02531   if (external) return;
02532   XStr containerType = container->baseName();
02533   XStr preMarshall, preCall, postCall;
02534 
02535   templateGuardBegin(tspec || container->isTemplated(), str);
02536   str << "/* DEFS: ";
02537   print(str);
02538   str << " */\n";
02539 
02540   if (isMigrationConstructor()) {
02541   }  
02542   else if (isTramTarget() && container->isForElement()) {
02543     genTramDefs(str);
02544   } else if (container->isGroup()) {
02545     genGroupDefs(str);
02546   } else if (container->isArray()) {
02547     genArrayDefs(str);
02548   } else
02549     genChareDefs(str);
02550 
02551   if (!isConstructor() && fortranMode) {
02552     str << "/* FORTRAN SECTION */\n";
02553 
02554     
02555     
02556     str << "extern \"C\" ";
02557     str << "void ";
02558     str << fortranify(container->baseName(), "_Entry_", name);
02559     str << "(char **";
02560     str << ", " << container->indexList();
02561     if (!param->isVoid()) {
02562       str << ", ";
02563       param->printAddress(str);
02564     }
02565     str << ");\n";
02566 
02567     str << "/* FORTRAN SECTION END */\n";
02568   }
02569 
02570   if (container->isMainChare() || container->isChare() || container->isForElement()) {
02571     if (isReductionTarget()) {
02572       XStr retStr;
02573       retStr << retType;
02574       str << makeDecl(retStr);
02575       
02576       str << "::_call_" << epStr(true) << "(void* impl_msg, void* impl_obj_void)"
02577           << "\n{"
02578           << "\n  " << container->baseName() << "* impl_obj = static_cast<"
02579           << container->baseName() << "*> (impl_obj_void);\n"
02580           << "  char* impl_buf = (char*)((CkReductionMsg*)impl_msg)->getData();\n";
02581       XStr precall;
02582       genCall(str, precall, true, false);
02583       if (!(sdagCon || isWhenEntry))
02584         str << "  delete (CkReductionMsg*)impl_msg;\n}\n\n";
02585       else
02586         str << "  \n}\n\n";
02587     }
02588   }
02589 
02590   
02591   if (container->getForWhom() != forAll) {
02592     templateGuardEnd(str);
02593     return;
02594   }
02595 
02596   
02597   str << "\n// Entry point registration function"
02598       << "\n"
02599       << makeDecl("int") << "::reg_" << epStr() << "() {"
02600       << "\n  int epidx = " << genRegEp() << ";";
02601   if (hasCallMarshall)
02602     str << "\n  CkRegisterMarshallUnpackFn(epidx, "
02603         << "_callmarshall_" << epStr(false, true) << ");";
02604   if (param->isMarshalled()) {
02605     str << "\n  CkRegisterMessagePupFn(epidx, "
02606         << "_marshallmessagepup_" << epStr(false, true) << ");\n";
02607   } else if (param->isMessage() && !isMigrationConstructor()) {
02608     str << "\n  CkRegisterMessagePupFn(epidx, (CkMessagePupFn)";
02609     param->param->getType()->deref()->print(str);
02610     str << "::ckDebugPup);";
02611   }
02612   str << "\n  return epidx;"
02613       << "\n}\n\n";
02614 
02615   if (isReductionTarget()) {
02616     str << "\n// Redn wrapper registration function"
02617         << "\n"
02618         << makeDecl("int") << "::reg_" << epStr(true) << "() {"
02619         << "\n  return " << genRegEp(true) << ";"
02620         << "\n}\n\n";
02621   }
02622 
02623 
02624 #if CMK_CELL != 0
02625   if (isAccel()) {
02626     str << "int " << indexName() << "::"
02627         << "accel_spe_func_index__" << epStr() << "=0;\n";
02628   }
02629 #endif
02630 
02631   
02632   if (isSync() || isIget()) {
02633     
02634     
02635     preMarshall
02636         << "  int impl_ref = CkGetRefNum(impl_msg), impl_src = CkGetSrcPe(impl_msg);\n";
02637     if (retType->isVoid() || retType->isMessage()) preCall << "  void *impl_retMsg=";
02638     if (retType->isVoid()) {
02639       preCall << "CkAllocSysMsg();\n  ";
02640     } else if (retType->isMessage()) {
02641       preCall << "(void *) ";
02642     } else {
02643       preCall << "  " << retType << " impl_ret_val= ";
02644       postCall << "  //Marshall: impl_ret_val\n";
02645       postCall << "  int impl_ret_size=0;\n";
02646       postCall << "  { //Find the size of the PUP'd data\n";
02647       postCall << "    PUP::sizer implPS;\n";
02648       postCall << "    implPS|impl_ret_val;\n";
02649       postCall << "    impl_ret_size+=implPS.size();\n";
02650       postCall << "  };\n";
02651       postCall
02652           << "  CkMarshallMsg *impl_retMsg=CkAllocateMarshallMsg(impl_ret_size, NULL);\n";
02653       postCall << "  { //Copy over the PUP'd data;\n";
02654       postCall << "    PUP::toMem implPS((void *)impl_retMsg->msgBuf);\n";
02655       postCall << "    implPS|impl_ret_val;\n";
02656       postCall << "  };\n";
02657     }
02658     postCall << "  CkSendToFutureID(impl_ref, impl_retMsg, impl_src);\n";
02659   } else if (isExclusive()) {
02660     
02661     preMarshall
02662         << "  if(CmiTryLock(impl_obj->__nodelock)) {\n"; 
02663     
02664     if (param->isMarshalled()) {
02665       preMarshall << "    impl_msg = CkCopyMsg(&impl_msg);\n";
02666     }
02667     preMarshall << "    CkSendMsgNodeBranch(" << epIdx()
02668                 << ",impl_msg,CkMyNode(),impl_obj->CkGetNodeGroupID());\n";
02669     preMarshall << "    return;\n";
02670     preMarshall << "  }\n";
02671 
02672     postCall << "  CmiUnlock(impl_obj->__nodelock);\n";
02673   }
02674 
02675   if (param->isVoid() && !isNoKeep()) {
02676     
02677 
02678 
02679 
02680 
02681     postCall << "  if(UsrToEnv(impl_msg)->isVarSysMsg() == 0)\n";
02682     postCall << "    CkFreeSysMsg(impl_msg);\n";
02683   }
02684 
02685   if (!isConstructor() && fortranMode) {  
02686     str << "/* FORTRAN SECTION */\n";
02687 
02688     XStr dim;
02689     dim << ((Array*)container)->dim();
02690 
02691     
02692     
02693     str << "extern \"C\" ";
02694     str << "void ";
02695     str << fortranify(container->baseName(), "_Invoke_", name);
02696     str << "(void** aindex";
02697     str << ", " << container->indexList();
02698     if (!param->isVoid()) {
02699       str << ", ";
02700       param->printAddress(str);
02701     }
02702     str << ")\n";
02703     str << "{\n";
02704     str << "  CkArrayID *aid = (CkArrayID *)*aindex;\n";
02705     str << "\n";
02706     str << "  " << container->proxyName() << " h(*aid);\n";
02707     if (dim == (const char*)"1D")
02708       str << "  h[*index1]." << name << "(";
02709     else if (dim == (const char*)"2D")
02710       str << "  h[CkArrayIndex2D(*index1, *index2)]." << name << "(";
02711     else if (dim == (const char*)"3D")
02712       str << "  h[CkArrayIndex3D(*index1, *index2, *index3)]." << name << "(";
02713     if (!param->isVoid()) param->printValue(str);
02714     str << ");\n";
02715     str << "}\n";
02716 
02717     if (container->isArray()) {
02718       str << "extern \"C\" ";
02719       str << "void ";
02720       str << fortranify(container->baseName(), "_Broadcast_", name);
02721       str << "(void** aindex";
02722       if (!param->isVoid()) {
02723         str << ", ";
02724         param->printAddress(str);
02725       }
02726       str << ")\n";
02727       str << "{\n";
02728       str << "  CkArrayID *aid = (CkArrayID *)*aindex;\n";
02729       str << "\n";
02730       str << "  " << container->proxyName() << " h(*aid);\n";
02731         str << "  h." << name << "(";
02732       if (!param->isVoid()) param->printValue(str);
02733       str << ");\n";
02734       str << "}\n";
02735     }
02736 
02737     if (isReductionTarget()) {
02738       str << "extern \"C\" ";
02739       str << "int ";
02740       str << fortranify(container->baseName(), "_ReductionTarget_", name);
02741       str << "(void)\n";
02742       str << "{\n";
02743       str << "  return CkReductionTarget(" << container->baseName() << ", " << name << ");\n";
02744       str << "}\n";
02745     }
02746 
02747     str << "/* FORTRAN SECTION END */\n";
02748   }
02749 
02750   
02751   
02752   
02753   
02754   if (isAccel()) {
02755     genAccelIndexWrapperDef_general(str);
02756 #if CMK_CELL != 0
02757     genAccelIndexWrapperDef_spe(str);
02758 #endif
02759   }
02760 
02761   
02762   str << makeDecl("void") << "::_call_" << epStr()
02763       << "(void* impl_msg, void* impl_obj_void)\n";
02764   str << "{\n";
02765   
02766   
02767   if (!isMigrationConstructor()) {
02768     str << "  " << container->baseName() << "* impl_obj = static_cast<"
02769         << container->baseName() << "*>(impl_obj_void);\n";
02770   }
02771   if (!isLocal()) {
02772     if (isThreaded()) str << callThread(epStr());
02773     str << preMarshall;
02774     if (param->isMarshalled()) {
02775       if (param->hasConditional())
02776         str << "  MarshallMsg_" << epStr() << " *impl_msg_typed=(MarshallMsg_" << epStr()
02777             << " *)impl_msg;\n";
02778       else
02779         str << "  CkMarshallMsg *impl_msg_typed=(CkMarshallMsg *)impl_msg;\n";
02780       str << "  char *impl_buf=impl_msg_typed->msgBuf;\n";
02781       str << "  envelope *env = UsrToEnv(impl_msg_typed);\n";
02782     }
02783     genCall(str, preCall, false, false);
02784     param->endUnmarshall(str);
02785     str << postCall;
02786     if (isThreaded() && param->isMarshalled()) str << "  delete impl_msg_typed;\n";
02787   } else {
02788     str << "  CkAbort(\"This method should never be called as it refers to a LOCAL entry "
02789            "method!\");\n";
02790   }
02791   str << "}\n";
02792 
02793   if (hasCallMarshall) {
02794     str << makeDecl("int") << "::_callmarshall_" << epStr()
02795         << "(char* impl_buf, void* impl_obj_void) {\n";
02796     str << "  " << containerType << "* impl_obj = static_cast<" << containerType
02797         << "*>(impl_obj_void);\n";
02798     str << "  envelope *env = UsrToEnv(impl_buf);\n";
02799     if (!isLocal()) {
02800       if (!param->hasConditional()) {
02801         genCall(str, preCall, false, true);
02802         
02803 
02804 
02805         str << "  return implP.size();\n";
02806       } else {
02807         str << "  CkAbort(\"This method is not implemented for EPs using conditional "
02808                "packing\");\n";
02809         str << "  return 0;\n";
02810       }
02811     } else {
02812       str << "  CkAbort(\"This method should never be called as it refers to a LOCAL "
02813              "entry method!\");\n";
02814       str << "  return 0;\n";
02815     }
02816     str << "}\n";
02817   }
02818   if (param->isMarshalled()) {
02819     str << makeDecl("void") << "::_marshallmessagepup_" << epStr()
02820         << "(PUP::er &implDestP,void *impl_msg) {\n";
02821     if (!isLocal()) {
02822       if (param->hasConditional())
02823         str << "  MarshallMsg_" << epStr() << " *impl_msg_typed=(MarshallMsg_" << epStr()
02824             << " *)impl_msg;\n";
02825       else
02826         str << "  CkMarshallMsg *impl_msg_typed=(CkMarshallMsg *)impl_msg;\n";
02827       str << "  char *impl_buf=impl_msg_typed->msgBuf;\n";
02828       str << "  envelope *env = UsrToEnv(impl_msg_typed);\n";
02829       param->beginUnmarshall(str);
02830       param->pupAllValues(str);
02831     } else {
02832       str << "  /*Fake pupping since we don't really have a message */\n";
02833       str << "  int n=0;\n";
02834       str << "  if (implDestP.hasComments()) implDestP.comment(\"LOCAL message\");\n";
02835       str << "  implDestP|n;\n";
02836     }
02837     str << "}\n";
02838   }
02839 
02840   
02841   
02842   if ((param->isMarshalled() || param->isVoid()) && genClosureTypeNameProxy) {
02843     if (container->isTemplated()) str << container->tspec(false);
02844     if (tspec) {
02845       str << "template <";
02846       tspec->genLong(str, false);
02847       str << "> ";
02848     }
02849 
02850     str << ((container->isTemplated() || tspec) ? "PUPable_def_template_nonInst"
02851                                                 : "PUPable_def")
02852         << "(SINGLE_ARG(" << *genClosureTypeNameProxy;
02853     if (tspec) {
02854       str << "<";
02855       tspec->genShort(str);
02856       str << ">";
02857     }
02858     str << "))\n";
02859   }
02860 
02861   templateGuardEnd(str);
02862 }
02863 
02864 XStr Entry::genRegEp(bool isForRedn) {
02865   XStr str;
02866   str << "CkRegisterEp";
02867   if (tspec) {
02868     str << "<";
02869     tspec->genShort(str);
02870     str << ">";
02871   }
02872   str << "(\"";
02873   if (isForRedn)
02874     str << "redn_wrapper_" << name << "(CkReductionMsg *impl_msg)\",\n";
02875   else
02876     str << name << "(" << paramType(0) << ")\",\n";
02877   str << "      _call_" << epStr(isForRedn, true);
02878   str << ", ";
02879   
02880   if (param->isMarshalled()) {
02881     if (param->hasConditional())
02882       str << "MarshallMsg_" << epStr() << "::__idx";
02883     else
02884       str << "CkMarshallMsg::__idx";
02885   } else if (!param->isVoid() && !isMigrationConstructor()) {
02886     param->genMsgProxyName(str);
02887     str << "::__idx";
02888   } else if (isForRedn) {
02889     str << "CMessage_CkReductionMsg::__idx";
02890   } else {
02891     str << "0";
02892   }
02893   
02894   str << ", __idx";
02895   
02896   str << ", 0";
02897   
02898   
02899   
02900   
02901   if (!isForRedn && (attribs & SNOKEEP)) str << "+CK_EP_NOKEEP";
02902   if (attribs & SNOTRACE) str << "+CK_EP_TRACEDISABLE";
02903   if (attribs & SIMMEDIATE) {
02904      str << "+CK_EP_TRACEDISABLE";
02905      str << "+CK_EP_IMMEDIATE";
02906   }
02907   if (attribs & SINLINE) str << "+CK_EP_INLINE";
02908   if (attribs & SAPPWORK) str << "+CK_EP_APPWORK";
02909 
02910   
02911   if (attribs & SMEM) str << "+CK_EP_MEMCRITICAL";
02912 
02913   if (internalMode) str << "+CK_EP_INTRINSIC";
02914   str << ")";
02915   return str;
02916 }
02917 
02918 void Entry::genReg(XStr& str) {
02919   if (tspec) return;
02920 
02921   if (external) {
02922     str << "  CkIndex_" << label << "::idx_" << name;
02923     if (targs) str << "<" << targs << ">";
02924     str << "( static_cast<" << retType << " (" << label << "::*)(" << paramType(0, 0)
02925         << ")>(NULL) );\n";
02926     return;
02927   }
02928 
02929   str << "  // REG: " << *this;
02930   str << "  " << epIdx(0) << ";\n";
02931   if (isReductionTarget()) str << "  " << epIdx(0, true) << ";\n";
02932   if (isConstructor()) {
02933     if (container->isMainChare() && !isMigrationConstructor())
02934       str << "  CkRegisterMainChare(__idx, " << epIdx(0) << ");\n";
02935     if (param->isVoid()) str << "  CkRegisterDefaultCtor(__idx, " << epIdx(0) << ");\n";
02936     if (isMigrationConstructor())
02937       str << "  CkRegisterMigCtor(__idx, " << epIdx(0) << ");\n";
02938   }
02939 }
02940 
02941 void Entry::preprocess() {
02942   ParamList* pl = param;
02943   if (pl != NULL && pl->hasConditional()) {
02944     XStr str;
02945     str << "MarshallMsg_" << epStr();
02946     NamedType* nt = new NamedType(strdup(str));
02947     MsgVar* var = new MsgVar(new BuiltinType("char"), "msgBuf", 0, 1);
02948     MsgVarList* list = new MsgVarList(var);
02949     do {
02950       if (pl->param->isConditional()) {
02951         var = new MsgVar(pl->param->getType(), pl->param->getName(), 1, 0);
02952         list = new MsgVarList(var, list);
02953       }
02954     } while (NULL != (pl = pl->next));
02955     Message* m = new Message(-1, nt, list);
02956     m->setModule(container->containerModule);
02957     container->containerModule->prependConstruct(m);
02958   }
02959 
02960   
02961   
02962   accel_numScalars = 0;
02963   accel_numArrays = 0;
02964   accel_dmaList_numReadOnly = 0;
02965   accel_dmaList_numReadWrite = 0;
02966   accel_dmaList_numWriteOnly = 0;
02967   accel_dmaList_scalarNeedsWrite = 0;
02968   if (isAccel()) {
02969     ParamList* curParam = param;
02970     if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
02971       curParam = curParam->next;
02972     }
02973     while (curParam != NULL) {
02974       if (curParam->param->isArray()) {
02975         accel_numArrays++;
02976         accel_dmaList_numReadOnly++;
02977       } else {
02978         accel_numScalars++;
02979       }
02980       curParam = curParam->next;
02981     }
02982     curParam = accelParam;
02983     while (curParam != NULL) {
02984       if (curParam->param->isArray()) {
02985         accel_numArrays++;
02986         switch (curParam->param->getAccelBufferType()) {
02987           case Parameter::ACCEL_BUFFER_TYPE_READWRITE:
02988             accel_dmaList_numReadWrite++;
02989             break;
02990           case Parameter::ACCEL_BUFFER_TYPE_READONLY:
02991             accel_dmaList_numReadOnly++;
02992             break;
02993           case Parameter::ACCEL_BUFFER_TYPE_WRITEONLY:
02994             accel_dmaList_numWriteOnly++;
02995             break;
02996           default:
02997             XLAT_ERROR_NOCOL("unknown accel param type", first_line_);
02998             break;
02999         }
03000       } else {
03001         accel_numScalars++;
03002         switch (curParam->param->getAccelBufferType()) {
03003           case Parameter::ACCEL_BUFFER_TYPE_READWRITE:
03004             accel_dmaList_scalarNeedsWrite++;
03005             break;
03006           case Parameter::ACCEL_BUFFER_TYPE_READONLY:
03007             break;
03008           case Parameter::ACCEL_BUFFER_TYPE_WRITEONLY:
03009             accel_dmaList_scalarNeedsWrite++;
03010             break;
03011           default:
03012             XLAT_ERROR_NOCOL("unknown accel param type", first_line_);
03013             break;
03014         }
03015       }
03016       curParam = curParam->next;
03017     }
03018     if (accel_numScalars > 0) {
03019       if (accel_dmaList_scalarNeedsWrite) {
03020         accel_dmaList_numReadWrite++;
03021       } else {
03022         accel_dmaList_numReadOnly++;
03023       }
03024     }
03025   }
03026 }
03027 
03028 int Entry::paramIsMarshalled(void) { return param->isMarshalled(); }
03029 
03030 int Entry::getStackSize(void) { return (stacksize ? stacksize->getIntVal() : 0); }
03031 
03032 void Entry::setAccelParam(ParamList* apl) { accelParam = apl; }
03033 void Entry::setAccelCodeBody(XStr* acb) { accelCodeBody = acb; }
03034 void Entry::setAccelCallbackName(XStr* acbn) { accelCallbackName = acbn; }
03035 
03036 int Entry::isThreaded(void) { return (attribs & STHREADED); }
03037 int Entry::isSync(void) { return (attribs & SSYNC); }
03038 int Entry::isIget(void) { return (attribs & SIGET); }
03039 int Entry::isConstructor(void) {
03040   return !strcmp(name, container->baseName(0).get_string());
03041 }
03042 bool Entry::isMigrationConstructor() { return isConstructor() && (attribs & SMIGRATE); }
03043 int Entry::isExclusive(void) { return (attribs & SLOCKED); }
03044 int Entry::isImmediate(void) { return (attribs & SIMMEDIATE); }
03045 int Entry::isSkipscheduler(void) { return (attribs & SSKIPSCHED); }
03046 int Entry::isInline(void) { return attribs & SINLINE; }
03047 int Entry::isLocal(void) { return attribs & SLOCAL; }
03048 int Entry::isCreate(void) { return (attribs & SCREATEHERE) || (attribs & SCREATEHOME); }
03049 int Entry::isCreateHome(void) { return (attribs & SCREATEHOME); }
03050 int Entry::isCreateHere(void) { return (attribs & SCREATEHERE); }
03051 int Entry::isPython(void) { return (attribs & SPYTHON); }
03052 int Entry::isNoTrace(void) { return (attribs & SNOTRACE); }
03053 int Entry::isAppWork(void) { return (attribs & SAPPWORK); }
03054 int Entry::isNoKeep(void) { return (attribs & SNOKEEP); }
03055 int Entry::isSdag(void) { return (sdagCon != 0); }
03056 bool Entry::isTramTarget(void) { return (attribs & SAGGREGATE) != 0; }
03057 
03058 
03059 int Entry::isAccel(void) { return (attribs & SACCEL); }
03060 
03061 int Entry::isMemCritical(void) { return (attribs & SMEM); }
03062 int Entry::isReductionTarget(void) { return (attribs & SREDUCE); }
03063 
03064 char* Entry::getEntryName() { return name; }
03065 int Entry::getLine() { return line; }
03066 Chare* Entry::getContainer(void) const { return container; }
03067 
03068 }