bool FunctionStaticSlicer::updateRCSC(
                PostDominanceFrontier::DomSetType::const_iterator start,
                PostDominanceFrontier::DomSetType::const_iterator end) {
  bool changed = false;
#ifdef DEBUG_RC
  errs() << __func__ << " ============ BEG\n";
#endif
  for (; start != end; start++) {
    const BasicBlock *BB = *start;
    const Instruction &i = BB->back();
    InsInfo *ii = getInsInfo(&i);
    /* SC = BC \cup ... */
#ifdef DEBUG_SLICING
    errs() << "XXXXXXXXXXXXXX " << BB->getName() << " ";
    i.print(errs());
    errs() << '\n';
#endif
    ii->deslice();
    /* RC = ... \cup \cup(b \in BC) RB */
    for (ValSet::const_iterator II = ii->REF_begin(), EE = ii->REF_end();
         II != EE; II++)
      if (ii->addRC(*II)) {
        changed = true;
#ifdef DEBUG_RC
        errs() << "  added " << (*II)->getName() << "\n";
#endif
      }
  }
#ifdef DEBUG_RC
  errs() << __func__ << " ============ END: changed=" << changed << "\n";
#endif
  return changed;
}
/*
 * SC(i)={i| DEF(i) \cap RC(j) \neq \emptyset}
 */
void FunctionStaticSlicer::computeSCi(const Instruction *i, const Instruction *j) {
  InsInfo *insInfoi = getInsInfo(i), *insInfoj = getInsInfo(j);

  bool isect_nonempty = false;
  for (ValSet::const_iterator I = insInfoi->DEF_begin(),
       E = insInfoi->DEF_end(); I != E && !isect_nonempty; I++) {
    const Pointee &DEFi = *I;
    for (ValSet::const_iterator II = insInfoj->RC_begin(),
         EE = insInfoj->RC_end(); II != EE; II++) {
      if (sameValues(DEFi, *II)) {
        isect_nonempty = true;
        break;
      }
    }
  }

  if (isect_nonempty) {
    insInfoi->deslice();
#ifdef DEBUG_SLICING
    errs() << "XXXXXXXXXXXXXY ";
    i->print(errs());
    errs() << '\n';
#endif
  }
}
/*
 * SC(i)={i| DEF(i) \cap RC(j) \neq \emptyset}
 */
void FunctionStaticSlicer::computeSCi(const Instruction *i, const Instruction *j) {
  InsInfo *insInfoi = getInsInfo(i), *insInfoj = getInsInfo(j);
  // Intersection between DEF and RC is initially empty
  bool isect_nonempty = false;
  for (ValSet::const_iterator I = insInfoi->DEF_begin(),
       E = insInfoi->DEF_end(); I != E && !isect_nonempty; I++) {
    const Pointee &DEFi = *I;
    for (ValSet::const_iterator II = insInfoj->RC_begin(),
         EE = insInfoj->RC_end(); II != EE; II++) {
    	if(Helper::checkValid(DEFi, *II))
    		if (AA->alias(DEFi.first, II->first)) {
    			DEBUG( errs() << "isect_nonempty " );
    			DEBUG( DEFi.first->print(errs()) );
    			DEBUG( errs() << "\n" );
    			isect_nonempty = true;
    			break;
    		}
    }
  }

  if (isect_nonempty) {
    insInfoi->deslice();
#ifdef DEBUG_SLICING
    errs() << "XXXXXXXXXXXXXY ";
    i->print(errs());
    errs() << '\n';
#endif
  }
}
void FunctionStaticSlicer::clearMem() {
	// Clear RC from every instruction other than call or return 
	// instruction. Call and return instruction will be later 
	// used in emitToCalls and emitToExits. 
	for (inst_iterator I = inst_begin(fun), E = inst_end(fun); I != E; I++) {
		Instruction *i = &*I;
    if( CallInst *CI = dyn_cast<CallInst>(i) )
			continue;
    if( ReturnInst *RI = dyn_cast<ReturnInst>(i) )
			continue;
		InsInfo *insInfoi = getInsInfo(&*I);
		insInfoi->clearRC();
	}
}
/*
 * j is predecessor of i
 * SC(i)={i| REF(i) \cap RC(j) \neq \emptyset}
 * Statement i should be in slice if it uses a relevant variable
 */
void FwdFunctionStaticSlicer::computeSCi(const Instruction *i, const Instruction *j) {
  InsInfo *insInfoi = getInsInfo(i), *insInfoj = getInsInfo(j);
#ifdef DEBUG_SLICE
  errs() << "\n\ti ==>\t";
  i->print(errs());
  errs() << "\n\tj ==>\t";
  j->print(errs());
#endif

  bool isect_nonempty = false;
  for (ValSet::const_iterator I = insInfoi->REF_begin(),
       E = insInfoi->REF_end(); I != E && !isect_nonempty; I++) {
    const Pointee &REFi = *I;
    for (ValSet::const_iterator II = insInfoj->RC_begin(),
         EE = insInfoj->RC_end(); II != EE; II++) {

    	if(Helper::checkValid(REFi, *II)) {
#ifdef DEBUG_SLICE
        	errs() << "\n\t\t";
        	REFi.first->print(errs());
        	errs() << "\t\t";
    		II->first->print(errs());
#endif
    		if (AA->isMustAlias(REFi.first, II->first)) {
    			isect_nonempty = true;
    			break;
    		}
    	}
    }
  }

  if (isect_nonempty) {
    insInfoi->deslice();
#ifdef DEBUG_SLICING
    errs() << "\n\tXXXXXXXXXXXXXY ";
    i->print(errs());
    errs() << '\n';
#endif
  }
}
bool FunctionStaticSlicer::computeBC() {
  bool changed = false;
#ifdef DEBUG_BC
  errs() << " ====== BEG BC Computation ======\n";
#endif
  if (!forward) {
    PostDominanceFrontier &PDF = MP->getAnalysis<PostDominanceFrontier>(fun);
    for (inst_iterator I = inst_begin(fun), E = inst_end(fun); I != E; I++) {
      Instruction *i = &*I;
      const InsInfo *ii = getInsInfo(i);
      if (ii->isSliced())
        continue;
      BasicBlock *BB = i->getParent();
#ifdef DEBUG_BC
      errs() << "  ";
      i->print(errs());
      errs() << " -> bb=" << BB->getName() << '\n';
#endif
      PostDominanceFrontier::const_iterator frontier = PDF.find(BB);
      if (frontier == PDF.end())
        continue;
      changed |= updateRCSC(frontier->second.begin(), frontier->second.end());
    }
  }
  else {
    for (inst_iterator I = inst_begin(fun), E = inst_end(fun); I != E; I++) {
      Instruction *i = &*I;
      if (!isa<BranchInst>(i))
        continue;
      BranchInst * bi = dyn_cast<BranchInst>(i);
      if (bi->isUnconditional()) // skip unconditional inst
        continue;
      const InsInfo *ii = getInsInfo(i);
      if (ii->isSliced())
        continue;
      unsigned succs = bi->getNumSuccessors(); 
      for (unsigned si = 0; si < succs; si++) {
        BasicBlock * BB = bi->getSuccessor(si);
        BasicBlock * Pred = BB->getUniquePredecessor();
        if (Pred == NULL)
          continue;
        for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; BI++) {
          InsInfo *bii = getInsInfo(&*BI);
          bii->deslice();
          for (ValSet::const_iterator VI = bii->DEF_begin(), VE = bii->DEF_end();
            VI != VE; VI++) {
            if (bii->addRC(*VI)) {
              changed = true;
#ifdef DEBUG_RC
              errs() << "  added ";
              printVal(*VI); 
              errs() << "\n";
#endif
            }
          }
        }
      }
    }
  }
#ifdef DEBUG_BC
  errs() << " ====== END BC Computation ======\n";
#endif
  return changed;
}