static DebugWaitFor dbgShowGlobal(char *line, processPo p, termPo loc, insWord ins, void *cl) { char buff[MAX_SYMB_LEN]; integer pos = 0; integer ix = 0; integer llen = uniStrLen(line); enum { initSte, inVar } st = initSte; while (ix < llen) { codePoint cp = nextCodePoint(line, &ix, llen); switch (st) { case initSte: if (!isSpaceChar(cp)) { st = inVar; appendCodePoint(buff, &pos, NumberOf(buff), cp); } continue; case inVar: if (!isSpaceChar(cp)) { appendCodePoint(buff, &pos, NumberOf(buff), cp); continue; } else break; } } if (uniStrLen(buff) > 0) { appendCodePoint(buff, &pos, NumberOf(buff), 0); globalPo glb = globalVar(buff); if (glb != Null) { termPo val = getGlobal(glb); if (val != Null) outMsg(debugOutChnnl, "%s = %,*T\n", buff, displayDepth, val); else outMsg(debugOutChnnl, "%s not set\n", buff); } } resetDeflt("n"); return moreDebug; }
virtual void run(const MatchFinder::MatchResult &Result){ //get the ASTContext clang::ASTContext *Context = Result.Context; //get the VarASTNode const clang::VarDecl *vd = Result.Nodes.getNodeAs<clang::VarDecl>("vardecl"); //TODO handle the condition "without vaild data" if(!vd || ASTUtility::IsDeclInSTDFile(vd, Context)) return; /* * distinguish Global Var * hasGlobalStorage():distinguish GloabalVar or StaticLocalVar * isStaticLocal():distinguish StaticLocalVar */ if(vd->hasGlobalStorage() && (vd->isStaticLocal() == false)) { //vd is a globalVar pointer std::string globalVar(vd->getNameAsString()); if(globalVar.size() < globalVarLength) ASTUtility::Print(vd, Context, "Rule051"); ASTUtility::Print(vd, Context, "Rule052"); } }
/** * @brief Computes the FuncInfo and returns it. */ ShPtr<OptimFuncInfo> OptimFuncInfoCFGTraversal::performComputation() { // First, we pre-compute varsAlwaysModifiedBeforeRead. The reason is that // their computation differs from the computation of the rest of the sets. precomputeAlwaysModifiedVarsBeforeRead(); // Every function's body is of the following form: // // (1) definitions of local variables, including assignments of global // variables into local variables // (2) other statements // // We store which variables are read/modified in (1). Then, we start the // traversal from (2). During the traversal, we check which variables are // read/modified and update funcInfo accordingly. The stored information // from (1) is used to compute the set of global variables which are read // in the function, but not modified. // // To give a specific example, consider the following code: // // def func(mango): // global orange // global plum // lychee = orange // achira = plum // orange = mango // plum = rand() // result = plum * apple + orange // orange = lychee // plum = achira // return result // // Here, even though the global variable orange is modified, its value // before calling func() is the same as after calling func(). Indeed, its // value is restored before the return statement. Hence, we may put it into // funcInfo->varsWithNeverChangedValue. // TODO Implement a more robust analysis. ShPtr<Statement> currStmt = traversedFunc->getBody(); while (isVarDefOrAssignStmt(currStmt)) { updateFuncInfo(currStmt); ShPtr<Expression> lhs(getLhs(currStmt)); ShPtr<Expression> rhs(getRhs(currStmt)); // If there is no right-hand side, it is a VarDefStmt with no // initializer, which we may skip. if (!rhs) { currStmt = currStmt->getSuccessor(); continue; } // If there are any function calls or dereferences, we have reached // (2). ShPtr<ValueData> currStmtData(va->getValueData(currStmt)); if (currStmtData->hasCalls() || currStmtData->hasDerefs()) { break; } // Check whether the statement is of the form localVar = globalVar. ShPtr<Variable> localVar(cast<Variable>(lhs)); ShPtr<Variable> globalVar(cast<Variable>(rhs)); if (!localVar || !globalVar || hasItem(globalVars, localVar) || !hasItem(globalVars, globalVar)) { // It is not of the abovementioned form, so skip it. currStmt = currStmt->getSuccessor(); continue; } storedGlobalVars[globalVar] = localVar; currStmt = currStmt->getSuccessor(); } // Perform the traversal only if we haven't reached the end of the function // yet. Since empty statements are not present in a CFG, skip them before // the traversal. if ((currStmt = skipEmptyStmts(currStmt))) { performTraversal(currStmt); } // We use the exit node of the CFG to check that every variable from // storedGlobalVars is retrieved its original value before every return. ShPtr<CFG::Node> exitNode(cfg->getExitNode()); // For every predecessor of the exit node... for (auto i = exitNode->pred_begin(), e = exitNode->pred_end(); i != e; ++i) { bool checkingShouldContinue = checkExitNodesPredecessor((*i)->getSrc()); if (!checkingShouldContinue) { break; } } // Update funcInfo using the remaining variables in storedGlobalVars. for (const auto &p : storedGlobalVars) { funcInfo->varsWithNeverChangedValue.insert(p.first); } // Update funcInfo->never{Read,Modified}Vars by global variables which are // untouched in this function. for (auto i = module->global_var_begin(), e = module->global_var_end(); i != e; ++i) { ShPtr<Variable> var((*i)->getVar()); if (!hasItem(funcInfo->mayBeReadVars, var) && !hasItem(funcInfo->mayBeModifiedVars, var)) { funcInfo->neverReadVars.insert(var); funcInfo->neverModifiedVars.insert(var); } } // If the cfg contains only a single non-{entry,exit} node, every // mayBe{Read,Modifed} variable can be turned into a always{Read,Modified} // variable. if (cfg->getNumberOfNodes() == 3) { addToSet(funcInfo->mayBeReadVars, funcInfo->alwaysReadVars); addToSet(funcInfo->mayBeModifiedVars, funcInfo->alwaysModifiedVars); } // Add all variables which are never read and never modified to // varsWithNeverChangedValue. VarSet neverReadAndModifedVars(setIntersection(funcInfo->neverReadVars, funcInfo->neverModifiedVars)); addToSet(neverReadAndModifedVars, funcInfo->varsWithNeverChangedValue); // Add all global variables are not read in this function into // varsAlwaysModifiedBeforeRead. addToSet(setDifference(globalVars, funcInfo->mayBeReadVars), funcInfo->varsAlwaysModifiedBeforeRead); return funcInfo; }
// u is used to denote this effect // v other effect // If nThisContexts == 1, then nGlobalFactors and Q_size must be 0 and // Q, globalSample, globalPostMean, globalPostVar, globalPriorVar and thisContext will not be touched. // If nOtherContexts == 1, then otherContext will not be touched. extern "C" void gaussianPosterior_2WayInteraction_2Levels( // OUTPUT double* localSample /* nLevelsThisEff x nLocalFactors x nThisContexts (u) */, double* globalSample /* nLevelsThisEff x nGlobalFactors (u_global) */, double* localPostMean /* NULL or nLevelsThisEff x nLocalFactors x nThisContexts: This is the posterior given the globalSample */, double* localPostVar /* NULL or nLevelsThisEff x nLocalFactors x nLocalFactors x nThisContexts: This is the posterior given the globalSample */, double* globalPostMean /* NULL or nLevelsThisEff x nGlobalFactors */, double* globalPostVar /* NULL or nLevelsThisEff x nGlobalFactors x nGlobalFactors */, //INPUT const int* option /*1: output sample, 2: output mean & var, 3: output sample & Mean & Var*/, const int* thisEffIndex /* nObs x 1 */, const int* otherEffIndex /* nObs x 1 */, const int* thisContext /* nObs x 1 */, const int* otherContext /* nObs x 1 */, const double* obs /* nObs x 1 */, const double* Q /* nLocalFactors x nGlobalFactors x nThisContexts */, const double* offset, /* NULL or nLevelsThisEff x nLocalFactors x nThisContexts */ const double* obsVar /* nObsVar x 1 */, const double* localPriorVar /* nThisContexts x 1 */, const double* globalPriorVar /* 1x1 */, const double* otherEff /* nLevelsOtherEff x nLocalFactors x nOtherContexts */, const int* nObs_, const int* nObsVar_ /* 1 or nObs */, const int* nLevelsThisEff_, const int* nThisContexts_, const int* nLevelsOtherEff_, const int* nOtherContexts_, const int* nLocalFactors_, const int* nGlobalFactors_, const int* nOffset_ /* 0 or nLevelsThisEff*nLocalFactors*nThisContexts */, const int* Q_size_ /* 1 or nLocalFactors*nGlobalFactors*nThisContexts */, const int* obsIndex, const int* oiStart, const int* oiNum, // OTHER const int* debug_, const int* verbose_ ){ int nObs=(*nObs_), nObsVar=(*nObsVar_), nLevelsThisEff=(*nLevelsThisEff_), nThisContexts=(*nThisContexts_), nLevelsOtherEff=(*nLevelsOtherEff_), nOtherContexts=(*nOtherContexts_), nLocalFactors=(*nLocalFactors_), nGlobalFactors=(*nGlobalFactors_), nOffset=(*nOffset_), Q_size=(*Q_size_), debug=(*debug_), verbose=(*verbose_); if(nObsVar != 1 && nObsVar != nObs) STOP1("nObsVar = %d", nObsVar); if(nThisContexts == 1 && nGlobalFactors != 0) STOP1("nThisContexts = 1, but nGlobalFactors = %d", nGlobalFactors); if(nThisContexts == 1 && Q_size != 0) STOP1("nThisContexts = 1, but Q_size = %d", Q_size); if(Q_size != 1 && Q_size != nLocalFactors*nGlobalFactors*nThisContexts) STOP1("Q_size = %d", Q_size); if(Q_size == 1 && Q[0] != 1 && Q[0] != 0) STOP1("Q = ", Q[0]); int outputMeanVar, drawSample; if(*option == 1){ outputMeanVar = 0; drawSample = 1; }else if(*option == 2){ outputMeanVar = 1; drawSample = 0; }else if(*option == 3){ outputMeanVar = 1; drawSample = 1; }else STOP1("Unknown option: %d", *option); // Initialize objects int max_nFactors = MAX(nLocalFactors, nGlobalFactors); int *num = (int*)Calloc(nThisContexts, int); // num[k]: #obs of user i in context k int N = (nThisContexts == 1 ? nLocalFactors : nGlobalFactors); Matrix_ColumnMajor temp1(max_nFactors, max_nFactors), temp2(max_nFactors, max_nFactors), temp3(max_nFactors, max_nFactors), globalMean(N,1), globalVar(N,N); Matrix_ColumnMajor *E_i = new Matrix_ColumnMajor[nThisContexts]; Matrix_ColumnMajor *S_i = new Matrix_ColumnMajor[nThisContexts]; Matrix_ColumnMajor *z_i = new Matrix_ColumnMajor[nThisContexts]; Matrix_ColumnMajor *Q_ = new Matrix_ColumnMajor[nThisContexts]; Matrix_ColumnMajor *Qt_ = new Matrix_ColumnMajor[nThisContexts]; for(int k=0; k<nThisContexts; k++){ E_i[k].resize(nLocalFactors, nLocalFactors); S_i[k].resize(nLocalFactors, nLocalFactors); z_i[k].resize(nLocalFactors, 1); if(Q_size > 1){ Q_[k].resize(nLocalFactors, nGlobalFactors); for(int a=0; a<nLocalFactors; a++) for(int b=0; b<nGlobalFactors; b++) Q_[k](a,b) = Q[C_3DA(a,b,k,nLocalFactors,nGlobalFactors)]; Qt_[k].transpose(Q_[k]); } } double *v_jk = (double*)Calloc(nLocalFactors, double); // o[ijk] = obs[ijk] - v[j,,k]' offset[i,,k] double *o; if(nOffset == 0){ o = (double*)obs; }else if(nOffset == nLevelsThisEff*nLocalFactors*nThisContexts){ o = (double*)Calloc(nObs, double); computeMultiResponseUV( o, offset, otherEff, thisEffIndex, otherEffIndex, thisContext, otherContext, nObs_, nLocalFactors_, nLevelsThisEff_, nThisContexts_, nLevelsOtherEff_, nOtherContexts_, debug_ ); for(int m=0; m<nObs; m++) o[m] = obs[m] - o[m]; }else STOP1("nOffset = %d", nOffset);