Beispiel #1
0
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);