Static Value-Flow Analysis
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
SVF::ICFGBuilder Class Reference

#include <ICFGBuilder.h>

Public Types

typedef std::vector< const Instruction * > InstVec
 
typedef Set< const Instruction * > BBSet
 
typedef Map< const Instruction *, CallICFGNode * > CSToCallNodeMapTy
 
typedef Map< const Instruction *, RetICFGNode * > CSToRetNodeMapTy
 
typedef Map< const Instruction *, IntraICFGNode * > InstToBlockNodeMapTy
 
typedef Map< const Function *, FunEntryICFGNode * > FunToFunEntryNodeMapTy
 
typedef Map< const Function *, FunExitICFGNode * > FunToFunExitNodeMapTy
 
typedef FIFOWorkList< const Instruction * > WorkList
 

Public Member Functions

 ICFGBuilder ()
 
ICFGbuild ()
 

Private Member Functions

LLVMModuleSetllvmModuleSet ()
 
CSToRetNodeMapTycsToRetNodeMap ()
 
CSToCallNodeMapTycsToCallNodeMap ()
 
InstToBlockNodeMapTyinstToBlockNodeMap ()
 
FunToFunEntryNodeMapTyfunToFunEntryNodeMap ()
 
FunToFunExitNodeMapTyfunToFunExitNodeMap ()
 

Private Attributes

ICFGicfg
 
BBSet visited
 
void processFunEntry (const Function *fun, WorkList &worklist)
 
void processNoPrecessorBasicBlocks (const Function *fun, WorkList &worklist)
 
void processFunBody (WorkList &worklist)
 
void processFunExit (const Function *fun)
 
void checkICFGNodesVisited (const Function *fun)
 
void connectGlobalToProgEntry ()
 
void addICFGInterEdges (const Instruction *cs, const Function *callee)
 Create edges between ICFG nodes across functions. More...
 
ICFGNodegetICFGNode (const Instruction *inst)
 
bool hasICFGNode (const Instruction *inst)
 
CallICFGNodegetCallICFGNode (const Instruction *cs)
 get a call node More...
 
RetICFGNodegetRetICFGNode (const Instruction *cs)
 get a return node More...
 
IntraICFGNodegetIntraICFGNode (const Instruction *inst)
 get a intra node More...
 
FunEntryICFGNodegetFunEntryICFGNode (const Function *fun)
 get a function entry node More...
 
FunExitICFGNodegetFunExitICFGNode (const Function *fun)
 get a function exit node More...
 
GlobalICFGNodegetGlobalICFGNode () const
 
InterICFGNodeaddInterBlockICFGNode (const Instruction *inst)
 Add/Get an inter block ICFGNode. More...
 
ICFGNodeaddBlockICFGNode (const Instruction *inst)
 Add/Get a basic block ICFGNode. More...
 
IntraICFGNodeaddIntraBlockICFGNode (const Instruction *inst)
 Add and get IntraBlock ICFGNode. More...
 
FunEntryICFGNodeaddFunEntryBlock (const Function *fun)
 
FunExitICFGNodeaddFunExitBlock (const Function *fun)
 
void addGlobalICFGNode ()
 

Detailed Description

Definition at line 41 of file ICFGBuilder.h.

Member Typedef Documentation

◆ BBSet

Definition at line 47 of file ICFGBuilder.h.

◆ CSToCallNodeMapTy

Definition at line 48 of file ICFGBuilder.h.

◆ CSToRetNodeMapTy

Definition at line 49 of file ICFGBuilder.h.

◆ FunToFunEntryNodeMapTy

Definition at line 51 of file ICFGBuilder.h.

◆ FunToFunExitNodeMapTy

Definition at line 52 of file ICFGBuilder.h.

◆ InstToBlockNodeMapTy

Definition at line 50 of file ICFGBuilder.h.

◆ InstVec

typedef std::vector<const Instruction*> SVF::ICFGBuilder::InstVec

Definition at line 46 of file ICFGBuilder.h.

◆ WorkList

Definition at line 59 of file ICFGBuilder.h.

Constructor & Destructor Documentation

◆ ICFGBuilder()

SVF::ICFGBuilder::ICFGBuilder ( )
inline

Definition at line 61 of file ICFGBuilder.h.

61  : icfg(new ICFG())
62  {
63 
64  }

Member Function Documentation

◆ addBlockICFGNode()

ICFGNode * ICFGBuilder::addBlockICFGNode ( const Instruction inst)
inlineprivate

Add/Get a basic block ICFGNode.

Definition at line 331 of file ICFGBuilder.cpp.

332 {
333  ICFGNode* node;
335  node = addInterBlockICFGNode(inst);
336  else
337  node = addIntraBlockICFGNode(inst);
338  const_cast<SVFBasicBlock*>(
339  llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
340  ->addICFGNode(node);
341  return node;
342 }
IntraICFGNode * addIntraBlockICFGNode(const Instruction *inst)
Add and get IntraBlock ICFGNode.
InterICFGNode * addInterBlockICFGNode(const Instruction *inst)
Add/Get an inter block ICFGNode.
LLVMModuleSet * llvmModuleSet()
Definition: ICFGBuilder.h:69
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb) const
Definition: LLVMModule.h:237
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition: LLVMUtil.cpp:649

◆ addFunEntryBlock()

FunEntryICFGNode * ICFGBuilder::addFunEntryBlock ( const Function fun)
private

Definition at line 355 of file ICFGBuilder.cpp.

356 {
357  return funToFunEntryNodeMap()[fun] =
358  icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
359 }
FunToFunEntryNodeMapTy & funToFunEntryNodeMap()
Definition: ICFGBuilder.h:89
virtual FunEntryICFGNode * addFunEntryICFGNode(const SVFFunction *svfFunc)
Definition: ICFG.h:204

◆ addFunExitBlock()

FunExitICFGNode * ICFGBuilder::addFunExitBlock ( const Function fun)
inlineprivate

Definition at line 361 of file ICFGBuilder.cpp.

362 {
363  return funToFunExitNodeMap()[fun] =
364  icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
365 }
FunToFunExitNodeMapTy & funToFunExitNodeMap()
Definition: ICFGBuilder.h:94
virtual FunExitICFGNode * addFunExitICFGNode(const SVFFunction *svfFunc)
Definition: ICFG.h:211

◆ addGlobalICFGNode()

void SVF::ICFGBuilder::addGlobalICFGNode ( )
inlineprivate

Definition at line 175 of file ICFGBuilder.h.

176  {
177  icfg->globalBlockNode = new GlobalICFGNode(icfg->totalICFGNode++);
179  }
virtual void addICFGNode(ICFGNode *node)
Add a ICFG node.
Definition: ICFG.h:219
NodeID totalICFGNode
Definition: ICFG.h:66
GlobalICFGNode * globalBlockNode
unique basic block for all globals
Definition: ICFG.h:71

◆ addICFGInterEdges()

void ICFGBuilder::addICFGInterEdges ( const Instruction cs,
const Function callee 
)
private

Create edges between ICFG nodes across functions.

Create edges between ICFG nodes across functions

direct call

if this is an external function (no function body)

otherwise connect interprocedural edges

indirect call (don't know callee)

Definition at line 278 of file ICFGBuilder.cpp.

279 {
280 
281  CallICFGNode* callICFGNode = getCallICFGNode(cs);
282  RetICFGNode* retBlockNode = getRetICFGNode(cs);
283 
285  if(callee)
286  {
287  SVFFunction* svfFun =
288  llvmModuleSet()->getSVFFunction(callee);
290  if (SVFUtil::isExtCall(svfFun))
291  {
292  icfg->addIntraEdge(callICFGNode, retBlockNode);
293  }
295  else
296  {
297  FunEntryICFGNode* calleeEntryNode = getFunEntryICFGNode(callee);
298  FunExitICFGNode* calleeExitNode = getFunExitICFGNode(callee);
299  icfg->addCallEdge(callICFGNode, calleeEntryNode);
300  icfg->addRetEdge(calleeExitNode, retBlockNode);
301  }
302  }
304  else
305  {
306  icfg->addIntraEdge(callICFGNode, retBlockNode);
307  }
308 }
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
Definition: ICFGBuilder.h:131
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
Definition: ICFGBuilder.h:136
FunEntryICFGNode * getFunEntryICFGNode(const Function *fun)
get a function entry node
Definition: ICFGBuilder.h:147
FunExitICFGNode * getFunExitICFGNode(const Function *fun)
get a function exit node
Definition: ICFGBuilder.h:152
ICFGEdge * addCallEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition: ICFG.cpp:366
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition: ICFG.cpp:384
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
Definition: ICFG.cpp:325
SVFFunction * getSVFFunction(const Function *fun) const
Definition: LLVMModule.h:230
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278

◆ addInterBlockICFGNode()

InterICFGNode * ICFGBuilder::addInterBlockICFGNode ( const Instruction inst)
private

Add/Get an inter block ICFGNode.

(1) Add and get CallBlockICFGNode (2) Handle call instruction by creating interprocedural edges

Definition at line 237 of file ICFGBuilder.cpp.

238 {
239  assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
240  assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
241  assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
242  const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
243  bool isvcall = cppUtil::isVirtualCallSite(cb);
244  SVFFunction* calledFunc = nullptr;
245  auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
246  if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
247  {
248  calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc);
249  }
250  else
251  {
252  calledFunc = SVFUtil::dyn_cast<SVFFunction>(
253  llvmModuleSet()->getSVFValue(called_llvmval));
254  }
255 
256  SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
257 
258  CallICFGNode* callICFGNode = icfg->addCallICFGNode(
259  bb, llvmModuleSet()->getSVFType(inst->getType()),
260  calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
261  isvcall ? cppUtil::getVCallIdx(cb) : 0,
262  isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
263  csToCallNodeMap()[inst] = callICFGNode;
264  llvmModuleSet()->setValueAttr(inst, callICFGNode);
265 
266  assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
267  RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
268  csToRetNodeMap()[inst] = retICFGNode;
269  llvmModuleSet()->setValueAttr(inst, retICFGNode);
270 
271  addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
272  return callICFGNode;
273 }
CSToRetNodeMapTy & csToRetNodeMap()
Definition: ICFGBuilder.h:74
CSToCallNodeMapTy & csToCallNodeMap()
Definition: ICFGBuilder.h:79
void addICFGInterEdges(const Instruction *cs, const Function *callee)
Create edges between ICFG nodes across functions.
virtual CallICFGNode * addCallICFGNode(const SVFBasicBlock *bb, const SVFType *ty, const SVFFunction *calledFunc, bool isVararg, bool isvcall, s32_t vcallIdx, const std::string &funNameOfVcall)
Definition: ICFG.h:183
virtual RetICFGNode * addRetICFGNode(CallICFGNode *call)
Definition: ICFG.h:196
void setValueAttr(const Value *val, SVFValue *value)
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition: LLVMUtil.h:45
const Function * getCallee(const CallBase *cs)
Definition: LLVMUtil.h:63
std::string getFunNameOfVCallSite(const CallBase *cs)
Definition: CppUtil.cpp:635
s32_t getVCallIdx(const CallBase *cs)
Definition: CppUtil.cpp:646
bool isVirtualCallSite(const CallBase *cs)
Definition: CppUtil.cpp:352
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::Function Function
Definition: BasicTypes.h:85

◆ addIntraBlockICFGNode()

IntraICFGNode * ICFGBuilder::addIntraBlockICFGNode ( const Instruction inst)
private

Add and get IntraBlock ICFGNode.

Definition at line 344 of file ICFGBuilder.cpp.

345 {
346  IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
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);
352  return sNode;
353 }
InstToBlockNodeMapTy & instToBlockNodeMap()
Definition: ICFGBuilder.h:84
virtual IntraICFGNode * addIntraICFGNode(const SVFBasicBlock *bb, bool isRet)
Definition: ICFG.h:175
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition: LLVMModule.h:423

◆ build()

ICFG * ICFGBuilder::build ( )

Create ICFG nodes and edges

Definition at line 43 of file ICFGBuilder.cpp.

44 {
45  DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
46  // Add the unique global ICFGNode at the entry of a program (before the main method).
48 
49  // Add function entry and exit
50  for (Module &M : llvmModuleSet()->getLLVMModules())
51  {
52  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
53  {
54  const Function *fun = &*F;
55  if (fun->isDeclaration())
56  continue;
57  addFunEntryBlock(fun);
58  addFunExitBlock(fun);
59  }
60 
61  }
62 
63  for (Module &M : llvmModuleSet()->getLLVMModules())
64  {
65  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
66  {
67  const Function *fun = &*F;
68  if (fun->isDeclaration())
69  continue;
70  WorkList worklist;
71  processFunEntry(fun,worklist);
72  processNoPrecessorBasicBlocks(fun, worklist);
73  processFunBody(worklist);
74  processFunExit(fun);
75 
77  }
78 
79  }
81  return icfg;
82 }
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DGENERAL
Definition: SVFType.h:490
FunEntryICFGNode * addFunEntryBlock(const Function *fun)
void connectGlobalToProgEntry()
FIFOWorkList< const Instruction * > WorkList
Definition: ICFGBuilder.h:59
void addGlobalICFGNode()
Definition: ICFGBuilder.h:175
void processNoPrecessorBasicBlocks(const Function *fun, WorkList &worklist)
void processFunBody(WorkList &worklist)
void checkICFGNodesVisited(const Function *fun)
Definition: ICFGBuilder.cpp:84
void processFunEntry(const Function *fun, WorkList &worklist)
FunExitICFGNode * addFunExitBlock(const Function *fun)
void processFunExit(const Function *fun)
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
llvm::Module Module
Definition: BasicTypes.h:84

◆ checkICFGNodesVisited()

void ICFGBuilder::checkICFGNodesVisited ( const Function fun)
private

Definition at line 84 of file ICFGBuilder.cpp.

85 {
86  for (const auto& bb: *fun)
87  {
88  for (const auto& inst: bb)
89  {
90  if(LLVMUtil::isIntrinsicInst(&inst))
91  continue;
92  assert(visited.count(&inst) && "inst never visited");
93  assert(hasICFGNode(&inst) && "icfgnode not created");
94  }
95  }
96 }
bool hasICFGNode(const Instruction *inst)
Definition: ICFGBuilder.h:125
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition: LLVMUtil.cpp:204

◆ connectGlobalToProgEntry()

void ICFGBuilder::connectGlobalToProgEntry ( )
private

Definition at line 312 of file ICFGBuilder.cpp.

313 {
314  for (Module &M : llvmModuleSet()->getLLVMModules())
315  {
316  if (const Function* mainFunc = LLVMUtil::getProgEntryFunction(M))
317  {
318  // main function
319  FunEntryICFGNode* entryNode = getFunEntryICFGNode(mainFunc);
320  GlobalICFGNode* globalNode = getGlobalICFGNode();
321  IntraCFGEdge* intraEdge = new IntraCFGEdge(globalNode, entryNode);
322  icfg->addICFGEdge(intraEdge);
323  }
324  else
325  {
326  // not main function
327  }
328  }
329 }
GlobalICFGNode * getGlobalICFGNode() const
Definition: ICFGBuilder.h:157
bool addICFGEdge(ICFGEdge *edge)
Add ICFG edge, only used by addIntraEdge, addCallEdge, addRetEdge etc.
Definition: ICFG.h:277
const Function * getProgEntryFunction(Module &module)
Get program entry function from module.
Definition: LLVMUtil.h:367

◆ csToCallNodeMap()

CSToCallNodeMapTy& SVF::ICFGBuilder::csToCallNodeMap ( )
inlineprivate

Definition at line 79 of file ICFGBuilder.h.

80  {
82  }
CSToCallNodeMapTy CSToCallNodeMap
map a callsite to its CallICFGNode
Definition: LLVMModule.h:103

◆ csToRetNodeMap()

CSToRetNodeMapTy& SVF::ICFGBuilder::csToRetNodeMap ( )
inlineprivate

Definition at line 74 of file ICFGBuilder.h.

75  {
76  return llvmModuleSet()->CSToRetNodeMap;
77  }
CSToRetNodeMapTy CSToRetNodeMap
map a callsite to its RetICFGNode
Definition: LLVMModule.h:104

◆ funToFunEntryNodeMap()

FunToFunEntryNodeMapTy& SVF::ICFGBuilder::funToFunEntryNodeMap ( )
inlineprivate

Definition at line 89 of file ICFGBuilder.h.

90  {
92  }
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
map a function to its FunExitICFGNode
Definition: LLVMModule.h:106

◆ funToFunExitNodeMap()

FunToFunExitNodeMapTy& SVF::ICFGBuilder::funToFunExitNodeMap ( )
inlineprivate

Definition at line 94 of file ICFGBuilder.h.

95  {
97  }
FunToFunExitNodeMapTy FunToFunExitNodeMap
map a function to its FunEntryICFGNode
Definition: LLVMModule.h:107

◆ getCallICFGNode()

CallICFGNode* SVF::ICFGBuilder::getCallICFGNode ( const Instruction cs)
inlineprivate

get a call node

Definition at line 131 of file ICFGBuilder.h.

132  {
133  return llvmModuleSet()->getCallICFGNode(cs);
134  }
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node

◆ getFunEntryICFGNode()

FunEntryICFGNode* SVF::ICFGBuilder::getFunEntryICFGNode ( const Function fun)
inlineprivate

get a function entry node

Definition at line 147 of file ICFGBuilder.h.

148  {
149  return llvmModuleSet()->getFunEntryICFGNode(fun);
150  }
FunEntryICFGNode * getFunEntryICFGNode(const Function *fun)
Add a function entry node.
Definition: LLVMModule.h:305

◆ getFunExitICFGNode()

FunExitICFGNode* SVF::ICFGBuilder::getFunExitICFGNode ( const Function fun)
inlineprivate

get a function exit node

Definition at line 152 of file ICFGBuilder.h.

153  {
154  return llvmModuleSet()->getFunExitICFGNode(fun);
155  }
FunExitICFGNode * getFunExitICFGNode(const Function *fun)
Add a function exit node.
Definition: LLVMModule.h:312

◆ getGlobalICFGNode()

GlobalICFGNode* SVF::ICFGBuilder::getGlobalICFGNode ( ) const
inlineprivate

Definition at line 157 of file ICFGBuilder.h.

158  {
159  return icfg->getGlobalICFGNode();
160  }
GlobalICFGNode * getGlobalICFGNode() const
Definition: ICFG.h:236

◆ getICFGNode()

ICFGNode* SVF::ICFGBuilder::getICFGNode ( const Instruction inst)
inlineprivate

Definition at line 120 of file ICFGBuilder.h.

121  {
122  return llvmModuleSet()->getICFGNode(inst);
123  }
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.

◆ getIntraICFGNode()

IntraICFGNode* SVF::ICFGBuilder::getIntraICFGNode ( const Instruction inst)
inlineprivate

get a intra node

Definition at line 141 of file ICFGBuilder.h.

142  {
143  return llvmModuleSet()->getIntraICFGNode(inst);
144  }
IntraICFGNode * getIntraICFGNode(const Instruction *inst)
get a intra node

◆ getRetICFGNode()

RetICFGNode* SVF::ICFGBuilder::getRetICFGNode ( const Instruction cs)
inlineprivate

get a return node

Definition at line 136 of file ICFGBuilder.h.

137  {
138  return llvmModuleSet()->getRetICFGNode(cs);
139  }
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node

◆ hasICFGNode()

bool SVF::ICFGBuilder::hasICFGNode ( const Instruction inst)
inlineprivate

Definition at line 125 of file ICFGBuilder.h.

126  {
127  return llvmModuleSet()->hasICFGNode(inst);
128  }
bool hasICFGNode(const Instruction *inst)

◆ instToBlockNodeMap()

InstToBlockNodeMapTy& SVF::ICFGBuilder::instToBlockNodeMap ( )
inlineprivate

Definition at line 84 of file ICFGBuilder.h.

85  {
87  }
InstToBlockNodeMapTy InstToBlockNodeMap
map a basic block to its ICFGNode
Definition: LLVMModule.h:105

◆ llvmModuleSet()

LLVMModuleSet* SVF::ICFGBuilder::llvmModuleSet ( )
inlineprivate

Definition at line 69 of file ICFGBuilder.h.

70  {
72  }
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118

◆ processFunBody()

void ICFGBuilder::processFunBody ( WorkList worklist)
private

function body

function body

branch condition value

default case is set to -1;

Definition at line 146 of file ICFGBuilder.cpp.

147 {
149  while (!worklist.empty())
150  {
151  const Instruction* inst = worklist.pop();
152  ICFGNode* srcNode = getICFGNode(inst);
153  if (SVFUtil::isa<ReturnInst>(inst))
154  {
155  FunExitICFGNode* FunExitICFGNode = getFunExitICFGNode(inst->getFunction());
156  icfg->addIntraEdge(srcNode, FunExitICFGNode);
157  }
158  InstVec nextInsts;
159  LLVMUtil::getNextInsts(inst, nextInsts);
160  s64_t branchID = 0;
161  for (InstVec::const_iterator nit = nextInsts.begin(), enit =
162  nextInsts.end(); nit != enit; ++nit)
163  {
164  const Instruction* succ = *nit;
165  ICFGNode* dstNode;
166  if (visited.find(succ) != visited.end())
167  {
168  dstNode = getICFGNode(succ);
169  }
170  else
171  {
172  visited.insert(succ);
173  dstNode = addBlockICFGNode(succ);
174  worklist.push(succ);
175  }
176 
177 
179  {
180  RetICFGNode* retICFGNode = getRetICFGNode(inst);
181  srcNode = retICFGNode;
182  }
183 
184  if (const BranchInst* br = SVFUtil::dyn_cast<BranchInst>(inst))
185  {
186  assert(branchID <= 1 && "if/else has more than two branches?");
187  if(br->isConditional())
188  icfg->addConditionalIntraEdge(srcNode, dstNode, 1 - branchID);
189  else
190  icfg->addIntraEdge(srcNode, dstNode);
191  }
192  else if (const SwitchInst* si = SVFUtil::dyn_cast<SwitchInst>(inst))
193  {
195  const ConstantInt* condVal = const_cast<SwitchInst*>(si)->findCaseDest(const_cast<BasicBlock*>(succ->getParent()));
197  s64_t val = -1;
198  if (condVal && condVal->getBitWidth() <= 64)
199  val = condVal->getSExtValue();
200  icfg->addConditionalIntraEdge(srcNode, dstNode,val);
201  }
202  else
203  icfg->addIntraEdge(srcNode, dstNode);
204  branchID++;
205  }
206  }
207 }
std::vector< const Instruction * > InstVec
Definition: ICFGBuilder.h:46
ICFGNode * addBlockICFGNode(const Instruction *inst)
Add/Get a basic block ICFGNode.
ICFGNode * getICFGNode(const Instruction *inst)
Definition: ICFGBuilder.h:120
ICFGEdge * addConditionalIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode, s64_t branchCondVal)
Definition: ICFG.cpp:344
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition: LLVMUtil.cpp:551
llvm::BasicBlock BasicBlock
Definition: BasicTypes.h:86
llvm::SwitchInst SwitchInst
Definition: BasicTypes.h:155
llvm::Instruction Instruction
Definition: BasicTypes.h:87
llvm::BranchInst BranchInst
Definition: BasicTypes.h:154
signed long long s64_t
Definition: GeneralType.h:49
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125

◆ processFunEntry()

void ICFGBuilder::processFunEntry ( const Function fun,
WorkList worklist 
)
private

Create edges between ICFG nodes within a function

function entry

Definition at line 100 of file ICFGBuilder.cpp.

101 {
103  const Instruction* entryInst = &((fun->getEntryBlock()).front());
104 
105  InstVec insts;
106  if (LLVMUtil::isIntrinsicInst(entryInst))
107  LLVMUtil::getNextInsts(entryInst, insts);
108  else
109  insts.push_back(entryInst);
110  for (InstVec::const_iterator nit = insts.begin(), enit = insts.end();
111  nit != enit; ++nit)
112  {
113  visited.insert(*nit);
114  ICFGNode* instNode = addBlockICFGNode(*nit); //add interprocedural edge
115  worklist.push(*nit);
116  icfg->addIntraEdge(FunEntryICFGNode, instNode);
117  }
118 
119 
120 
121 }

◆ processFunExit()

void ICFGBuilder::processFunExit ( const Function f)
private

function exit e.g., exit(0). In LLVM, it usually manifests as "unreachable" instruction If a function has multiple exit(0), we will only have one "unreachle" instruction after the UnifyFunctionExitNodes pass.

Definition at line 214 of file ICFGBuilder.cpp.

215 {
217 
218  for (const auto& bb : *f)
219  {
220  for (const auto& inst : bb)
221  {
222  if (SVFUtil::isa<ReturnInst>(&inst))
223  {
225  }
226  }
227  }
228 }

◆ processNoPrecessorBasicBlocks()

void ICFGBuilder::processNoPrecessorBasicBlocks ( const Function fun,
WorkList worklist 
)
private

bbs with no predecessors

Definition at line 126 of file ICFGBuilder.cpp.

127 {
128  for (const auto& bb: *fun)
129  {
130  for (const auto& inst: bb)
131  {
132  if (LLVMUtil::isNoPrecessorBasicBlock(inst.getParent()) &&
133  !visited.count(&inst))
134  {
135  visited.insert(&inst);
136  (void)addBlockICFGNode(&inst);
137  worklist.push(&inst);
138  }
139  }
140  }
141 }
bool isNoPrecessorBasicBlock(const BasicBlock *bb)
Definition: LLVMUtil.h:297

Member Data Documentation

◆ icfg

ICFG* SVF::ICFGBuilder::icfg
private

Definition at line 56 of file ICFGBuilder.h.

◆ visited

BBSet SVF::ICFGBuilder::visited
private

Definition at line 182 of file ICFGBuilder.h.


The documentation for this class was generated from the following files: