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 }