37 using namespace SVFUtil;
50 for (
Module &M : llvmModuleSet()->getLLVMModules())
52 for (Module::const_iterator
F = M.begin(), E = M.end();
F != E; ++
F)
55 if (fun->isDeclaration())
57 addFunEntryBlock(fun);
63 for (
Module &M : llvmModuleSet()->getLLVMModules())
65 for (Module::const_iterator
F = M.begin(), E = M.end();
F != E; ++
F)
68 if (fun->isDeclaration())
71 processFunEntry(fun,worklist);
72 processNoPrecessorBasicBlocks(fun, worklist);
73 processFunBody(worklist);
76 checkICFGNodesVisited(fun);
80 connectGlobalToProgEntry();
86 for (
const auto& bb: *fun)
88 for (
const auto& inst: bb)
92 assert(visited.count(&inst) &&
"inst never visited");
93 assert(hasICFGNode(&inst) &&
"icfgnode not created");
103 const Instruction* entryInst = &((fun->getEntryBlock()).front());
109 insts.push_back(entryInst);
110 for (InstVec::const_iterator nit = insts.begin(), enit = insts.end();
113 visited.insert(*nit);
114 ICFGNode* instNode = addBlockICFGNode(*nit);
128 for (
const auto& bb: *fun)
130 for (
const auto& inst: bb)
133 !visited.count(&inst))
135 visited.insert(&inst);
136 (void)addBlockICFGNode(&inst);
137 worklist.
push(&inst);
149 while (!worklist.
empty())
152 ICFGNode* srcNode = getICFGNode(inst);
153 if (SVFUtil::isa<ReturnInst>(inst))
161 for (InstVec::const_iterator nit = nextInsts.begin(), enit =
162 nextInsts.end(); nit != enit; ++nit)
166 if (visited.find(succ) != visited.end())
168 dstNode = getICFGNode(succ);
172 visited.insert(succ);
173 dstNode = addBlockICFGNode(succ);
181 srcNode = retICFGNode;
184 if (
const BranchInst* br = SVFUtil::dyn_cast<BranchInst>(inst))
186 assert(branchID <= 1 &&
"if/else has more than two branches?");
187 if(br->isConditional())
188 icfg->addConditionalIntraEdge(srcNode, dstNode, 1 - branchID);
190 icfg->addIntraEdge(srcNode, dstNode);
192 else if (
const SwitchInst* si = SVFUtil::dyn_cast<SwitchInst>(inst))
198 if (condVal && condVal->getBitWidth() <= 64)
199 val = condVal->getSExtValue();
200 icfg->addConditionalIntraEdge(srcNode, dstNode,val);
203 icfg->addIntraEdge(srcNode, dstNode);
218 for (
const auto& bb : *f)
220 for (
const auto& inst : bb)
222 if (SVFUtil::isa<ReturnInst>(&inst))
241 assert(llvmModuleSet()->getCallBlock(inst)==
nullptr &&
"duplicate CallICFGNode");
242 const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
245 auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
246 if (
const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
248 calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc);
252 calledFunc = SVFUtil::dyn_cast<SVFFunction>(
253 llvmModuleSet()->getSVFValue(called_llvmval));
256 SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
259 bb, llvmModuleSet()->getSVFType(inst->getType()),
263 csToCallNodeMap()[inst] = callICFGNode;
264 llvmModuleSet()->setValueAttr(inst, callICFGNode);
266 assert(llvmModuleSet()->getRetBlock(inst)==
nullptr &&
"duplicate RetICFGNode");
267 RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
268 csToRetNodeMap()[inst] = retICFGNode;
269 llvmModuleSet()->setValueAttr(inst, retICFGNode);
288 llvmModuleSet()->getSVFFunction(callee);
292 icfg->addIntraEdge(callICFGNode, retBlockNode);
299 icfg->addCallEdge(callICFGNode, calleeEntryNode);
300 icfg->addRetEdge(calleeExitNode, retBlockNode);
306 icfg->addIntraEdge(callICFGNode, retBlockNode);
314 for (
Module &M : llvmModuleSet()->getLLVMModules())
322 icfg->addICFGEdge(intraEdge);
335 node = addInterBlockICFGNode(inst);
337 node = addIntraBlockICFGNode(inst);
339 llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
347 assert (node==
nullptr &&
"no IntraICFGNode for this instruction?");
349 llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
350 instToBlockNodeMap()[inst] = sNode;
351 llvmModuleSet()->setValueAttr(inst, sNode);
357 return funToFunEntryNodeMap()[fun] =
358 icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
363 return funToFunExitNodeMap()[fun] =
364 icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
bool push(const Data &data)
FunEntryICFGNode * addFunEntryBlock(const Function *fun)
void connectGlobalToProgEntry()
IntraICFGNode * addIntraBlockICFGNode(const Instruction *inst)
Add and get IntraBlock ICFGNode.
std::vector< const Instruction * > InstVec
void processNoPrecessorBasicBlocks(const Function *fun, WorkList &worklist)
InterICFGNode * addInterBlockICFGNode(const Instruction *inst)
Add/Get an inter block ICFGNode.
void processFunBody(WorkList &worklist)
void checkICFGNodesVisited(const Function *fun)
void processFunEntry(const Function *fun, WorkList &worklist)
FunExitICFGNode * addFunExitBlock(const Function *fun)
ICFGNode * addBlockICFGNode(const Instruction *inst)
Add/Get a basic block ICFGNode.
void addICFGInterEdges(const Instruction *cs, const Function *callee)
Create edges between ICFG nodes across functions.
void processFunExit(const Function *fun)
const SVFFunctionType * getFunctionType() const
Returns the FunctionType.
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
bool isNoPrecessorBasicBlock(const BasicBlock *bb)
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
const Function * getProgEntryFunction(Module &module)
Get program entry function from module.
const Function * getCallee(const CallBase *cs)
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
bool isExtCall(const SVFFunction *fun)
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
std::ostream & outs()
Overwrite llvm::outs()
std::string getFunNameOfVCallSite(const CallBase *cs)
s32_t getVCallIdx(const CallBase *cs)
bool isVirtualCallSite(const CallBase *cs)
llvm::BasicBlock BasicBlock
llvm::SwitchInst SwitchInst
llvm::Instruction Instruction
llvm::BranchInst BranchInst
llvm::ConstantInt ConstantInt