00001 #include "CEntry.h"
00002 #include "CStateVar.h"
00003 #include "constructs/Constructs.h"
00004 #include "xi-Chare.h"
00005 #include "xi-symbol.h"
00006
00007 using std::list;
00008
00009 namespace xi {
00010 void CEntry::generateDeps(XStr& op) {
00011 for (list<WhenConstruct*>::iterator cn = whenList.begin(); cn != whenList.end(); ++cn)
00012 op << " __dep->addDepends(" << (*cn)->nodeNum << "," << entryNum << ");\n";
00013 }
00014
00015 void generateLocalWrapper(XStr& decls, XStr& defs, int isVoid, XStr& signature,
00016 Entry* entry, std::list<CStateVar*>* params, XStr* next, bool isDummy) {
00017 int numRdmaParams = 0;
00018 for (std::list<CStateVar*>::iterator it = params->begin(); it != params->end(); ++it) {
00019 CStateVar& var = **it;
00020 if (var.isRdma) numRdmaParams++;
00021 }
00022
00023 templateGuardBegin(false, defs);
00024 defs << entry->getContainer()->tspec() << "void " << entry->getContainer()->baseName()
00025 << "::" << signature << "{\n";
00026
00027 if(isDummy) {
00028
00029
00030 defs << " " << "CkPrintf(\"Error> Direct call to SDAG entry method \\\'%s::%s\\\'!\\n\", \""
00031 << entry->getContainer()->baseName() << "\", \"" << signature << "\"); \n";
00032 defs << " " << "CkAbort(\"Direct SDAG call is not allowed for SDAG entry methods having when constructs. Call such SDAG methods using a proxy\"); \n";
00033 } else {
00034 defs << " " << *entry->genClosureTypeNameProxyTemp << "*"
00035 << " genClosure = new " << *entry->genClosureTypeNameProxyTemp << "()"
00036 << ";\n";
00037 if (params) {
00038 int i = 0;
00039 for (std::list<CStateVar*>::iterator it = params->begin(); it != params->end();
00040 ++it, ++i) {
00041 CStateVar& var = **it;
00042 if (var.name) {
00043 if (var.isRdma) {
00044 defs << "#if CMK_ONESIDED_IMPL\n";
00045 if (var.isFirstRdma)
00046 defs << " genClosure->getP" << i++ << "() = " << numRdmaParams << ";\n";
00047 defs << " genClosure->getP" << i << "() = "
00048 << "ncpyBuffer_" << var.name << ";\n";
00049 defs << "#else\n";
00050 defs << " genClosure->getP" << i << "() = "
00051 << "(" << var.type << "*)"
00052 << "ncpyBuffer_" << var.name << ".ptr"
00053 << ";\n";
00054 defs << "#endif\n";
00055 } else
00056 defs << " genClosure->getP" << i << "() = " << var.name << ";\n";
00057 }
00058 }
00059 }
00060 defs << " " << ( entry->containsWhenConstruct ? "_sdag_fnc_" : "") << *next << "(genClosure);\n";
00061 defs << " genClosure->deref();\n";
00062 }
00063 defs << "}\n\n";
00064 templateGuardEnd(defs);
00065 }
00066
00067 void CEntry::generateCode(XStr& decls, XStr& defs) {
00068 CStateVar* sv;
00069 int i = 0;
00070 int isVoid = 1;
00071 int lastWasVoid;
00072
00073 XStr signature;
00074 signature << *entry << "(";
00075 for (list<CStateVar*>::iterator it = myParameters.begin(); it != myParameters.end();
00076 ++it, ++i) {
00077 sv = *it;
00078 isVoid = sv->isVoid;
00079 if ((sv->isMsg != 1) && (sv->isVoid != 1)) {
00080 if (i > 0) signature << ", ";
00081 if (sv->byConst) signature << "const ";
00082
00083 if (sv->isRdma)
00084 signature << "CkNcpyBuffer ";
00085 else
00086 signature << sv->type << " ";
00087 if (sv->arrayLength != 0)
00088 signature << "*";
00089 else if (sv->declaredRef) {
00090 signature << "&";
00091 }
00092 if (sv->numPtrs != 0) {
00093 for (int k = 0; k < sv->numPtrs; k++) signature << "*";
00094 }
00095 if (sv->name != 0) {
00096 if (sv->isRdma) {
00097 signature << "ncpyBuffer_" << sv->name;
00098 } else {
00099 signature << sv->name;
00100 }
00101 }
00102 } else if (sv->isVoid != 1) {
00103 if (i < 1)
00104 signature << sv->type << "* " << sv->name << "_msg";
00105 else
00106 printf("ERROR: A message must be the only parameter in an entry function\n");
00107 } else
00108 signature << "void";
00109 }
00110
00111 signature << ")";
00112
00113 XStr newSig;
00114
00115 if (isVoid || needsParamMarshalling) {
00116 newSig << *entry << "(" << *decl_entry->genClosureTypeNameProxyTemp
00117 << "* genClosure)";
00118 decls << " void " << newSig << ";\n";
00119
00120 decls << " void " << signature << ";\n";
00121 generateLocalWrapper(decls, defs, isVoid, signature, decl_entry, &myParameters,
00122 entry);
00123 } else {
00124 newSig << signature << "";
00125 decls << " void " << newSig << ";\n";
00126 }
00127
00128 templateGuardBegin(false, defs);
00129 defs << decl_entry->getContainer()->tspec() << "void "
00130 << decl_entry->getContainer()->baseName() << "::" << newSig << "{\n";
00131 defs << " if (!__dep.get()) _sdag_init();\n";
00132
00133 #if CMK_BIGSIM_CHARM
00134 defs << " void* _bgParentLog = NULL;\n";
00135 defs << " CkElapse(0.01e-6);\n";
00136 SdagConstruct::generateTlineEndCall(defs);
00137 #endif
00138
00139 if (needsParamMarshalling || isVoid) {
00140
00141
00142 if (refNumNeeded && !isVoid)
00143 defs << " if (!genClosure->hasRefnum) "
00144 "genClosure->setRefnum(genClosure->getP0());\n";
00145
00146
00147 #if CMK_BIGSIM_CHARM
00148 defs << " SDAG::Buffer* cmsgbuf = ";
00149 #endif
00150
00151
00152
00153 defs << " __dep->pushBuffer(" << entryNum << ", genClosure);\n";
00154 } else {
00155
00156
00157
00158
00159
00160
00161 defs << " CmiReference(UsrToEnv(" << sv->name << "_msg));\n";
00162
00163 #if CMK_BIGSIM_CHARM
00164 defs << " SDAG::Buffer* cmsgbuf = ";
00165 #endif
00166
00167 defs << " __dep->pushBuffer(" << entryNum << ", new SDAG::MsgClosure(" << sv->name
00168 << "_msg"
00169 << "));\n";
00170 }
00171
00172
00173
00174 defs << " SDAG::Continuation* c = __dep->tryFindContinuation(" << entryNum << ");\n";
00175
00176
00177 defs << " if (c) {\n";
00178
00179 #if USE_CRITICAL_PATH_HEADER_ARRAY
00180 defs << " MergeablePathHistory *currentSaved = c->getPath();\n";
00181 defs << " mergePathHistory(currentSaved);\n";
00182 #endif
00183 SdagConstruct::generateTraceEndCall(defs, 2);
00184 #if CMK_BIGSIM_CHARM
00185 SdagConstruct::generateEndExec(defs);
00186 #endif
00187
00188 if (whenList.size() == 1) {
00189 (*whenList.begin())->generateWhenCode(defs, 2);
00190 } else {
00191
00192
00193 defs << " switch(c->whenID) {\n";
00194 for (list<WhenConstruct*>::iterator cn = whenList.begin(); cn != whenList.end();
00195 ++cn) {
00196 defs << " case " << (*cn)->nodeNum << ":\n";
00197 (*cn)->generateWhenCode(defs, 3);
00198 defs << " break;\n";
00199 }
00200 defs << " }\n";
00201 }
00202
00203 SdagConstruct::generateDummyBeginExecute(defs, 2, decl_entry);
00204
00205
00206 defs << " delete c;\n";
00207 defs << " }\n";
00208
00209 #if USE_CRITICAL_PATH_HEADER_ARRAY
00210 defs << "else {\n";
00211 defs << " MergeablePathHistory *currentSaved = saveCurrentPath();\n";
00212 defs << " buff0->setPath(currentSaved);\n";
00213 defs << "}\n";
00214 #endif
00215 defs << "}\n\n";
00216 templateGuardEnd(defs);
00217 }
00218
00219 list<Entry*> CEntry::getCandidates() { return candidateEntries_; }
00220
00221 void CEntry::addCandidate(Entry* e) { candidateEntries_.push_front(e); }
00222
00223 void CEntry::check() {
00224 if (decl_entry == NULL) {
00225 XStr str;
00226 paramlist->printTypes(str);
00227 std::string msg = "no matching declaration for entry method \'" +
00228 std::string(entry->get_string_const()) + "(" +
00229 std::string(str.get_string_const()) + ")\'";
00230 XLAT_ERROR_NOCOL(msg, first_line_);
00231
00232 std::list<Entry*> clist = getCandidates();
00233 if (!clist.empty())
00234 for (std::list<Entry*>::iterator it = clist.begin(); it != clist.end(); ++it)
00235 XLAT_NOTE("candidate method not viable: type signatures must match exactly",
00236 (*it)->first_line_);
00237 }
00238 }
00239
00240 }