00001 #include "When.h"
00002 #include "xi-Chare.h"
00003
00004 using std::list;
00005
00006 namespace xi {
00007
00008 WhenConstruct::WhenConstruct(EntryList* el, SdagConstruct* body)
00009 : BlockConstruct(SWHEN, 0, 0, 0, 0, 0, body, el), speculativeState(0) {
00010 label_str = "when";
00011 }
00012
00013 void WhenConstruct::generateEntryList(list<CEntry*>& CEntrylist,
00014 WhenConstruct* thisWhen) {
00015 elist->generateEntryList(CEntrylist, this);
00016 generateChildrenEntryList(CEntrylist, thisWhen);
00017 }
00018
00019 void WhenConstruct::propagateState(list<EncapState*> encap, list<CStateVar*>& plist,
00020 list<CStateVar*>& wlist, int uniqueVarNum) {
00021 CStateVar* sv;
00022 list<CStateVar*> whensEntryMethodStateVars;
00023 list<CStateVar*> whenCurEntry;
00024 stateVars = new list<CStateVar*>();
00025 stateVarsChildren = new list<CStateVar*>();
00026
00027 for (list<CStateVar*>::iterator iter = plist.begin(); iter != plist.end(); ++iter) {
00028 sv = *iter;
00029 stateVars->push_back(sv);
00030 stateVarsChildren->push_back(sv);
00031 }
00032
00033 encapState = encap;
00034
00035 EntryList* el;
00036 el = elist;
00037 ParamList* pl;
00038 int cntr = 0;
00039 bool dummy_var = false;
00040 while (el != NULL) {
00041 pl = el->entry->param;
00042 if (!pl->isVoid()) {
00043 while (pl != NULL) {
00044 if (pl->getGivenName() ==
00045 NULL) {
00046 char s[128];
00047 sprintf(s, "gen_name%d", cntr);
00048 pl->setGivenName(s);
00049 cntr++;
00050 dummy_var = true;
00051 }
00052 sv = new CStateVar(pl);
00053 if (!dummy_var) {
00054
00055 stateVarsChildren->push_back(sv);
00056 whensEntryMethodStateVars.push_back(sv);
00057 } else
00058 dummy_var = false;
00059 whenCurEntry.push_back(sv);
00060 el->entry->addEStateVar(sv);
00061 pl = pl->next;
00062 }
00063 }
00064
00065 EncapState* state = new EncapState(el->entry, whenCurEntry);
00066 if (!el->entry->paramIsMarshalled() && !el->entry->param->isVoid())
00067 state->isMessage = true;
00068 if (!el->entry->param->isVoid()) encap.push_back(state);
00069 whenCurEntry.clear();
00070 el = el->next;
00071 }
00072
00073 encapStateChild = encap;
00074
00075 propagateStateToChildren(encap, *stateVarsChildren, whensEntryMethodStateVars,
00076 uniqueVarNum);
00077 }
00078
00079 void WhenConstruct::generateWhenCode(XStr& op, int indent) {
00080 buildTypes(encapState);
00081 buildTypes(encapStateChild);
00082
00083
00084
00085 #if CMK_BIGSIM_CHARM
00086
00087 indentBy(op, indent);
00088 op << "cmsgbuf->bgLog2 = "
00089 "(void*)static_cast<SDAG::TransportableBigSimLog*>(c->closure[1])->log;\n";
00090 #endif
00091
00092
00093 indentBy(op, indent);
00094 op << this->label << "(";
00095
00096
00097 int cur = 0;
00098 for (list<EncapState*>::iterator iter = encapState.begin(); iter != encapState.end();
00099 ++iter, ++cur) {
00100 EncapState& state = **iter;
00101 op << "\n";
00102 indentBy(op, indent + 1);
00103 if (state.isMessage)
00104 op << "static_cast<" << *state.type
00105 << "*>(static_cast<SDAG::MsgClosure*>(c->closure[" << cur << "])->msg)";
00106 else if (state.isBgParentLog)
00107 op << "NULL";
00108 else
00109 op << "static_cast<" << *state.type << "*>(c->closure[" << cur << "])";
00110 if (cur != encapState.size() - 1) op << ", ";
00111 }
00112
00113 int prev = cur;
00114
00115 cur = 0;
00116 for (EntryList *el = elist; el != NULL; el = el->next, cur++)
00117 if (el->entry->intExpr) {
00118 if ((cur + prev) > 0) op << ", ";
00119 op << "\n";
00120 indentBy(op, indent + 1);
00121 op << "c->refnums[" << cur << "]";
00122 }
00123
00124 op << "\n";
00125 indentBy(op, indent);
00126 op << ");\n";
00127 #if CMK_BIGSIM_CHARM
00128 generateTlineEndCall(op);
00129 generateBeginExec(op, "sdagholder");
00130 #endif
00131 }
00132
00133 void WhenConstruct::generateEntryName(XStr& defs, Entry* e, int curEntry) {
00134 if ((e->paramIsMarshalled() == 1) || (e->param->isVoid() == 1))
00135 defs << e->getEntryName() << "_" << curEntry;
00136 else {
00137 for (list<CStateVar*>::iterator it = e->stateVars.begin(); it != e->stateVars.end();
00138 ++it) {
00139 CStateVar* sv = *it;
00140 defs << sv->name;
00141 }
00142 }
00143 defs << "_buf";
00144 }
00145
00146 void WhenConstruct::generateCode(XStr& decls, XStr& defs, Entry* entry) {
00147 buildTypes(encapState);
00148 buildTypes(encapStateChild);
00149
00150 int entryLen = 0, numRefs = 0;
00151
00152
00153
00154 {
00155 int cur = 0;
00156 for (EntryList *el = elist; el != NULL; el = el->next, cur++) {
00157 entryLen++;
00158 if (el->entry->intExpr) numRefs++;
00159 }
00160 }
00161
00162
00163
00164
00165 if (numRefs > 0) {
00166 sprintf(nameStr, "%s%s", CParsedFile::className->charstar(), label->charstar());
00167 generateClosureSignature(decls, defs, entry, false, "SDAG::Continuation*", label,
00168 false, encapState);
00169
00170
00171 int cur = 0;
00172 for (EntryList *el = elist; el != NULL; el = el->next, cur++)
00173 if (el->entry->intExpr) defs << " CMK_REFNUM_TYPE refnum_" << cur << ";\n";
00174 int indent = 2;
00175
00176
00177 indent = unravelClosuresBegin(defs);
00178 indentBy(defs, indent);
00179
00180 defs << "{\n";
00181
00182 cur = 0;
00183
00184 for (EntryList *el = elist; el != NULL; el = el->next, cur++)
00185 if (el->entry->intExpr) {
00186 indentBy(defs, indent + 1);
00187 defs << "refnum_" << cur << " = "
00188 << (el->entry->intExpr ? el->entry->intExpr : "0") << ";\n";
00189 }
00190
00191
00192 indentBy(defs, indent);
00193 defs << "}\n";
00194 unravelClosuresEnd(defs);
00195
00196
00197 defs << " return " << label << "(";
00198 cur = 0;
00199 for (list<EncapState*>::iterator iter = encapState.begin(); iter != encapState.end();
00200 ++iter, ++cur) {
00201 EncapState* state = *iter;
00202 if (state->name)
00203 defs << *state->name;
00204 else
00205 defs << "gen" << cur;
00206 if (cur != encapState.size() - 1) defs << ", ";
00207 }
00208 for (int i = 0; i < numRefs; i++)
00209 defs << ((cur + i) > 0 ? ", " : "") << "refnum_" << i;
00210 defs << ");\n";
00211
00212 endMethod(defs);
00213 }
00214
00215 sprintf(nameStr, "%s%s", CParsedFile::className->charstar(), label->charstar());
00216 generateClosureSignature(decls, defs, entry, false, "SDAG::Continuation*", label, false,
00217 encapState, numRefs);
00218
00219 #if CMK_BIGSIM_CHARM
00220 generateBeginTime(defs);
00221 #endif
00222
00223 if (entryLen > 1) defs << " std::unordered_set<SDAG::Buffer*> ignore;\n";
00224
00225 XStr haveAllBuffersCond;
00226 XStr removeMessagesIfFound, deleteMessagesIfFound;
00227 XStr continutationSpec;
00228
00229 {
00230 int cur = 0;
00231 for (EntryList *el = elist; el != NULL; el = el->next, cur++) {
00232 Entry* e = el->entry;
00233 XStr bufName("buf");
00234 bufName << cur;
00235 XStr refName;
00236 refName << "refnum_" << cur;
00237 defs << " SDAG::Buffer* " << bufName << " = __dep->tryFindMessage("
00238 << e->entryPtr->entryNum
00239 << ", " << (e->intExpr ? "true" : "false")
00240 << ", " << (e->intExpr ? refName.get_string_const() : "0")
00241 << ", " << (entryLen > 1 ? "&ignore" : "0")
00242 << ");\n";
00243 haveAllBuffersCond << bufName;
00244 removeMessagesIfFound << " __dep->removeMessage(" << bufName << ");\n";
00245 deleteMessagesIfFound << " delete " << bufName << ";\n";
00246
00247
00248
00249 if (e->intExpr) {
00250 continutationSpec << " c->entries.push_back(" << e->entryPtr->entryNum
00251 << ");\n";
00252 continutationSpec << " c->refnums.push_back(refnum_" << cur << ");\n";
00253 } else {
00254 continutationSpec << " c->anyEntries.push_back(" << e->entryPtr->entryNum
00255 << ");\n";
00256 }
00257
00258
00259
00260 if (entryLen > cur + 1) {
00261 haveAllBuffersCond << " && ";
00262 defs << " if (" << bufName << ") ignore.insert(" << bufName << ");\n";
00263 }
00264 }
00265 }
00266
00267
00268 defs << " if (" << haveAllBuffersCond << ") {\n";
00269
00270 #if CMK_BIGSIM_CHARM
00271 {
00272
00273 defs << " void* logs1[" << entryLen << "]; \n";
00274 defs << " void* logs2[" << entryLen + 1 << "]; \n";
00275 int localnum = 0;
00276 int cur = 0;
00277 for (EntryList *el = elist; el != NULL; el = el->next, cur++) {
00278 XStr bufName("buf");
00279 bufName << cur;
00280 defs << " logs1[" << localnum << "] = " << bufName << "->bgLog1; \n";
00281 defs << " logs2[" << localnum << "] = " << bufName << "->bgLog2; \n";
00282 localnum++;
00283 }
00284 defs << " logs2[" << localnum << "] = "
00285 << "_bgParentLog; \n";
00286 generateEventBracket(defs, SWHEN);
00287 defs << " _TRACE_BG_FORWARD_DEPS(logs1, logs2, " << localnum
00288 << ", _bgParentLog);\n";
00289 }
00290 #endif
00291
00292
00293 defs << removeMessagesIfFound;
00294
00295
00296 if (speculativeState)
00297 defs << " __dep->removeAllSpeculationIndex(" << speculativeState->name
00298 << "->speculationIndex);\n";
00299
00300
00301 defs << " ";
00302
00303 if (constructs && !constructs->empty())
00304 generateCall(defs, encapState, encapStateChild, constructs->front()->label);
00305 else
00306 generateCall(defs, encapState, encapStateChild, label, "_end");
00307
00308
00309 defs << deleteMessagesIfFound;
00310
00311 defs << " return 0;\n";
00312 defs << " } else {\n";
00313
00314
00315 defs << " SDAG::Continuation* c = new SDAG::Continuation(" << nodeNum << ");\n";
00316
00317
00318 {
00319 int cur = 0;
00320 for (list<EncapState*>::iterator iter = encapState.begin(); iter != encapState.end();
00321 ++iter, ++cur) {
00322 EncapState& state = **iter;
00323 defs << " c->addClosure(";
00324
00325
00326
00327 if (state.isMessage) defs << "new SDAG::MsgClosure(";
00328 if (state.isBgParentLog) defs << "new SDAG::TransportableBigSimLog(";
00329 state.name ? (defs << *state.name) : (defs << "gen" << cur);
00330 if (state.isMessage || state.isBgParentLog) defs << ")";
00331 defs << ");\n";
00332 }
00333 }
00334
00335
00336 defs << continutationSpec;
00337
00338
00339 defs << " __dep->reg(c);\n";
00340
00341
00342 defs << " return c;\n";
00343 defs << " }\n";
00344
00345 endMethod(defs);
00346
00352
00353 generateClosureSignature(decls, defs, entry, false, "void", label, true,
00354 encapStateChild);
00355
00356 #if CMK_BIGSIM_CHARM
00357 generateBeginTime(defs);
00358 generateEventBracket(defs, SWHEN_END);
00359 #endif
00360
00361
00362
00363
00364
00365 bool messageOutOfScope = false;
00366 int cur = 0;
00367 for (EntryList *el = elist; el != NULL; el = el->next, cur++)
00368 if (el->entry->param->isMessage() == 1) messageOutOfScope = true;
00369
00370
00371
00372 if (messageOutOfScope) {
00373 int indent = unravelClosuresBegin(defs, true);
00374
00375
00376
00377
00378 for (EntryList *el = elist; el != NULL; el = el->next, cur++) {
00379 if (el->entry->param->isMessage() == 1) {
00380 CStateVar*& sv = *el->entry->stateVars.begin();
00381 indentBy(defs, indent);
00382 defs << "CmiFree(UsrToEnv(" << sv->name << "));\n";
00383 }
00384 }
00385
00386 unravelClosuresEnd(defs, true);
00387 }
00388
00389
00390 defs << " ";
00391 generateCall(defs, encapState, encapState, next->label, nextBeginOrEnd ? 0 : "_end");
00392
00393 endMethod(defs);
00394
00395 generateChildrenCode(decls, defs, entry);
00396 }
00397
00398 void WhenConstruct::numberNodes() {
00399 nodeNum = numWhens++;
00400 SdagConstruct::numberNodes();
00401 }
00402
00403 }