38 using namespace SVFUtil;
62 for (Function::const_iterator bit = func->
getLLVMFun()->begin(), ebit = func->
getLLVMFun()->end(); bit != ebit; ++bit)
65 collectBBCallingProgExit(bb);
90 double num = log(succ_number)/log(2);
93 std::vector<Condition*> condVec;
94 for(
u32_t i = 0 ; i < bit_num; i++)
96 condVec.push_back(newCond(bb.getTerminator()));
101 succ_it != succ_end(&bb);
102 succ_it++, succ_index++)
114 for(
u32_t j = 0 ; j < bit_num; j++)
117 u32_t tool = 0x01 << j;
118 if(tool & succ_index)
120 path_cond = condAnd(path_cond, condVec.at(j));
124 path_cond = condAnd(path_cond, (condNeg(condVec.at(j))));
127 setBranchCond(&bb,succ,path_cond);
140 return getTrueCond();
143 BBCondMap::const_iterator it = bbConds.find(bb);
144 assert(it!=bbConds.end() &&
"basic block does not have branch and conditions??");
145 CondPosMap::const_iterator cit = it->second.find(pos);
146 assert(cit!=it->second.end() &&
"no condition on the branch??");
165 condPosMap[pos] = cond;
174 const BasicBlock* succ1 = brInst->getSuccessor(0);
176 if(isTestNullExpr(brInst->getCondition(),val))
180 return getFalseCond();
183 return getTrueCond();
185 if(isTestNotNullExpr(brInst->getCondition(),val))
189 return getTrueCond();
192 return getFalseCond();
203 const BasicBlock* succ1 = brInst->getSuccessor(0);
204 const BasicBlock* succ2 = brInst->getSuccessor(1);
206 bool branch1 = isBBCallsProgExit(succ1);
207 bool branch2 = isBBCallsProgExit(succ2);
210 if(branch1 ==
true && branch2 ==
false)
214 return getFalseCond();
217 return getTrueCond();
220 else if(branch1 ==
false && branch2 ==
true)
224 return getFalseCond();
227 return getTrueCond();
230 else if(branch1 ==
true && branch2 ==
true)
232 return getFalseCond();
247 const Function* fun = bb->getParent();
248 assert(fun==dst->getParent() &&
"two basic blocks should be in the same function");
250 const LoopInfo* loopInfo = getLoopInfo(fun);
251 if(loopInfo->isLoopHeader(const_cast<BasicBlock*>(bb)))
253 const Loop *loop = loopInfo->getLoopFor(bb);
256 loop->getExitBlocks(exitbbs);
258 while(!exitbbs.empty())
261 if(isBBCallsProgExit(eb) ==
false)
262 filteredbbs.insert(eb);
270 if(pdt->dominates(dst,*it) ==
false)
275 return getTrueCond();
289 assert(bb->getTerminator()->getSuccessor(0) == succ &&
"not the unique successor?");
290 return getTrueCond();
293 if(
const BranchInst* brInst = SVFUtil::dyn_cast<BranchInst>(bb->getTerminator()))
295 assert(brInst->getNumSuccessors() == 2 &&
"not a two successors branch??");
296 const BasicBlock* succ1 = brInst->getSuccessor(0);
297 const BasicBlock* succ2 = brInst->getSuccessor(1);
298 assert((succ1 == succ || succ2 == succ) &&
"not a successor??");
300 Condition* evalLoopExit = evaluateLoopExitBranch(bb,succ);
304 Condition* evalProgExit = evaluateProgExit(brInst,succ);
308 Condition* evalTestNullLike = evaluateTestNullLikeExpr(brInst,succ,val);
310 return evalTestNullLike;
313 return getBranchCond(bb, succ);
318 return (cmp->getPredicate() == CmpInst::ICMP_EQ);
323 return (cmp->getPredicate() == CmpInst::ICMP_NE);
328 if(
const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(test))
330 return isTestContainsNullAndTheValue(cmp,val) && isEQCmp(cmp);
337 if(
const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(test))
339 return isTestContainsNullAndTheValue(cmp,val) && isNECmp(cmp);
347 const Value* op0 = cmp->getOperand(0);
348 const Value* op1 = cmp->getOperand(1);
349 if((op0 == val && SVFUtil::isa<ConstantPointerNull>(op1))
350 || (op1 == val && SVFUtil::isa<ConstantPointerNull>(op0)) )
362 for(BasicBlock::const_iterator it = bb.begin(), eit = bb.end(); it!=eit; it++)
365 if(SVFUtil::isa<CallInst>(inst) || SVFUtil::isa<InvokeInst>(inst))
368 funToExitBBsMap[bb.getParent()].insert(&bb);
378 const Function* fun = bb->getParent();
379 FunToExitBBsMap::const_iterator it = funToExitBBsMap.find(fun);
380 if(it!=funToExitBBsMap.end())
383 for(BasicBlockSet::const_iterator bit = it->second.begin(), ebit= it->second.end(); bit!=ebit; bit++)
385 if(pdt->dominates(*bit,bb))
400 assert(BB1 && BB2 &&
"expect nullptr BB here!");
404 if(dt->dominates(BB1,BB2) && !dt->dominates(BB0,BB2))
406 Condition* cond = ComputeIntraVFGGuard(BB1,BB2);
407 return condNeg(cond);
420 const BasicBlock* funEntryBB = &dstBB->getParent()->getEntryBlock();
422 Condition* c1 = ComputeIntraVFGGuard(srcBB,callBB);
423 setCFCond(funEntryBB,condOr(getCFCond(funEntryBB),getCFCond(callBB)));
424 Condition* c2 = ComputeIntraVFGGuard(funEntryBB,dstBB);
425 return condAnd(c1,c2);
437 Condition* c1 = ComputeIntraVFGGuard(srcBB,funExitBB);
438 setCFCond(retBB,condOr(getCFCond(retBB),getCFCond(funExitBB)));
439 Condition* c2 = ComputeIntraVFGGuard(retBB,dstBB);
440 return condAnd(c1,c2);
449 assert(srcBB->getParent() == dstBB->getParent() &&
"two basic blocks are not in the same function??");
452 if(postDT->dominates(dstBB,srcBB))
453 return getTrueCond();
456 worklist.
push(srcBB);
457 setCFCond(srcBB,getTrueCond());
459 while(!worklist.
empty())
466 if(
Condition* loopExitCond = evaluateLoopExitBranch(bb,dstBB))
467 return condAnd(cond, loopExitCond);
471 succ_it != succ_end(bb); succ_it++)
479 if(postDT->dominates(succ,bb))
480 brCond = getTrueCond();
482 brCond = getEvalBrCond(bb, succ);
485 ") --> " <<
"succ_bb (" << succ->getName() <<
") condition: " << brCond <<
"\n");
486 Condition* succPathCond = condAnd(cond, brCond);
487 if(setCFCond(succ, condOr(getCFCond(succ), succPathCond)))
493 ") --> " <<
"dst_bb (" << dstBB->getName() <<
") condition: " << getCFCond(dstBB) <<
"\n");
495 return getCFCond(dstBB);
505 bddCondMgr =
nullptr;
514 outs() <<
"print path condition\n";
516 for(BBCondMap::const_iterator it = bbConds.begin(), eit = bbConds.end(); it!=eit; ++it)
519 for(CondPosMap::const_iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
527 outs() << bb->getName() <<
"-->" << succ->getName() <<
":";
528 outs() << dumpCond(cond) <<
"\n";
bool isTestNullExpr(const Value *test, const Value *val) const
Return true if this is a test null expression.
virtual void allocateForBB(const BasicBlock &bb)
Allocate path condition for every basic block.
Condition * getBranchCond(const BasicBlock *bb, const BasicBlock *succ) const
Get branch condition.
llvm::BranchInst BranchInst
static u32_t maximumCxtLen
virtual Condition * ComputeInterCallVFGGuard(const BasicBlock *src, const BasicBlock *dst, const BasicBlock *callBB)
llvm::BasicBlock BasicBlock
Condition * evaluateBranchCond(const BasicBlock *bb, const BasicBlock *succ, const Value *val)
Evaluate branch conditions.
Condition * evaluateTestNullLikeExpr(const BranchInst *brInst, const BasicBlock *succ, const Value *val)
Return branch condition after evaluating test null like expression.
std::string pasMsg(std::string msg)
Print each pass/phase message by converting a string into blue string output.
Condition * evaluateLoopExitBranch(const BasicBlock *bb, const BasicBlock *succ)
Evaluate loop exit branch.
u32_t getBBSuccessorPos(const BasicBlock *BB, const BasicBlock *Succ)
Get basic block successor position.
void printPathCond()
Print out the path condition information.
static u64_t maximumBudget
static BddCondManager * bddCondMgr
bbd manager
llvm::succ_const_iterator succ_const_iterator
llvm::PostDominatorTree PostDominatorTree
bool isTestContainsNullAndTheValue(const CmpInst *cmp, const Value *val) const
Return true if two values on the predicate are what we want.
bool isProgExitCall(const CallSite cs)
void setBranchCond(const BasicBlock *bb, const BasicBlock *succ, Condition *cond)
Get/Set a branch condition, and its terminator instruction.
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
llvm::Instruction Instruction
llvm::SmallVector< BasicBlock *, 8 > SmallBBVector
bool isNECmp(const CmpInst *cmp) const
Return true if the predicate of this compare instruction is not equal.
Condition * evaluateProgExit(const BranchInst *brInst, const BasicBlock *succ)
Return condition when there is a branch calls program exit.
bool isEQCmp(const CmpInst *cmp) const
Evaluate test null/not null like expressions.
virtual Condition * ComputeInterRetVFGGuard(const BasicBlock *src, const BasicBlock *dst, const BasicBlock *retBB)
llvm::DominatorTree DominatorTree
const BasicBlock * getFunExitBB(const Function *fun)
raw_ostream & outs()
Overwrite llvm::outs()
void allocate(const SVFModule *module)
Perform path allocation.
bool isTestNotNullExpr(const Value *test, const Value *val) const
Return true if this is a test not null expression.
Map< u32_t, Condition * > CondPosMap
map a branch to its Condition
#define DGENERAL
General debug flag is for each phase of a pass, it is often in a colorful output format.
void destroy()
Release memory.
static u32_t maximumPathLen
Function * getLLVMFun() const
bool isBBCallsProgExit(const BasicBlock *bb)
static u32_t totalCondNum
void collectBBCallingProgExit(const BasicBlock &bb)
Collect basic block contains program exit function call.
virtual Condition * ComputeIntraVFGGuard(const BasicBlock *src, const BasicBlock *dst)
Guard Computation for a value-flow (between two basic blocks)
virtual Condition * getPHIComplementCond(const BasicBlock *BB1, const BasicBlock *BB2, const BasicBlock *BB0)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DEBUG model of each pass.
u32_t getBBSuccessorNum(const BasicBlock *BB)
Get num of BB's successors.
FunctionSetType::const_iterator const_iterator
bool isExtCall(const SVFFunction *fun)
static const llvm::cl::opt< bool > PrintPathCond