ClearBlue
SymbolicExprGraph.h
1 /*
2  * Developed by Qingkai Shi, Fan Gang
3  * Copy Right by Prism Research Group, HKUST and State Key Lab for Novel
4  * Software Tech., Nanjing University.
5  */
6 
7 #ifndef SYMBOLIC_EXPR_GRAPH_H
8 #define SYMBOLIC_EXPR_GRAPH_H
9 
10 #include <llvm/IR/BasicBlock.h>
11 #include <llvm/IR/CallSite.h>
12 #include <llvm/IR/Constants.h>
13 #include <llvm/IR/Function.h>
14 #include <llvm/IR/InstIterator.h>
15 #include <llvm/IR/Instructions.h>
16 #include <llvm/IR/Value.h>
17 
18 #include <llvm/Support/Casting.h>
19 #include <llvm/Support/FileSystem.h>
20 #include <llvm/Support/Format.h>
21 #include <llvm/Support/raw_ostream.h>
22 
23 #include <map>
24 #include <set>
25 #include <unordered_map>
26 #include <unordered_set>
27 #include <vector>
28 
29 #include "Analysis/Alias/PathSensitiveAADriver/ProgramVal.h"
30 #include "IR/SEG/SEGValue.h"
31 #include "Transform/ValueComparator.h"
32 #include "Utils/ADT/MapIterators.h"
33 #include "Utils/ADT/kvec.h"
34 
35 using namespace llvm;
36 
37 class SEGCallSite;
43 
44 class SEGOpcodeNode;
45 class SEGOperandNode;
46 class SEGRegionNode;
47 class SEGPhiNode;
48 class SEGLoadMemNode;
49 class SEGStoreMemNode;
50 
51 class SEGReturnNode;
54 
55 class SEGArgumentNode;
58 class SEGVarArgumentNode;
59 
60 class SEGCastNode;
63 
64 class SEGSiteBase;
65 
66 class SymbolicExprGraph;
68 class OCValueFlowBuilder;
69 
70 class SEGOptions {
71 public:
72  static bool EnableValueToString;
73  static bool EnableArithmeticFlow;
74 };
75 
76 class SEGObject {
77  friend class SEGSerializer;
78  friend class SEGHash;
79 
80 public:
81  enum SEGObjectKind {
82  // nodes
83  SEGOBJK_NodeBegin,
84  // operand nodes
85  SEGOBJK_OperandBegin,
86 
87  SEGOBJK_ArgumentBegin,
88  SEGOBJK_CommonArgument,
89  SEGOBJK_VarArgument,
90  SEGOBJK_PseudoArgument,
91  SEGOBJK_ArgumentEnd,
92 
93  SEGOBJK_CallSiteOutputBegin,
94  SEGOBJK_CallSiteCommonOutput,
95  SEGOBJK_CallSitePseudoOutput,
96  SEGOBJK_CallSiteOutputEnd,
97 
98  SEGOBJK_ReturnBegin,
99  SEGOBJK_CommonReturn,
100  SEGOBJK_PseudoReturn,
101  SEGOBJK_ReturnEnd,
102 
103  SEGOBJK_LoadMem,
104  SEGOBJK_StoreMem,
105  SEGOBJK_Phi,
106  SEGOBJK_Region,
107  SEGOBJK_SimpleOperand,
108  SEGOBJK_Undef,
109  SEGOBJK_CallSitePseudoInput,
110  SEGOBJK_CallSiteSummaryArgument,
111  SEGOBJK_CallSiteSummaryReturn,
112 
113  SEGOBJK_OperandEnd,
114 
115  // opcode nodes
116  SEGOBJK_OpcodeBegin,
117  SEGOBJK_BinaryWithIntConst,
118  SEGOBJK_Cast,
119  SEGOBJK_SimpleOpcode,
120  SEGOBJK_OpcodeEnd,
121 
122  SEGOBJK_NodeEnd,
123 
124  // use sites
125  SEGOBJK_SiteBegin,
126 
127  SEGOBJK_CallSite,
128  SEGOBJK_ReturnSite,
129 
130  SEGOBJK_SimpleSiteBegin,
131  SEGOBJK_GEPSite,
132  SEGOBJK_DereferenceSite,
133  SEGOBJK_DivSite,
134  SEGOBJK_CmpSite,
135  SEGOBJK_AllocSite,
136  SEGOBJK_SimpleSiteEnd,
137 
138  SEGOBJK_SiteEnd,
139  };
140 
141 private:
142  const SEGObjectKind ObjKind;
143 
145  SymbolicExprGraph *ParentGraph;
146 
148  BasicBlock *ParentBasicBlock = nullptr;
149 
150  // Index of this SEGObject
151  int64_t ObjIndex = -1;
152 
153  // Index of this SEG
154  std::string SEGIndex;
155 
156 protected:
157 public:
158  SEGObject(SEGObjectKind OK, SymbolicExprGraph *SEG, BasicBlock *BB,
159  bool fromDisk);
160 
161  virtual ~SEGObject() = 0;
162 
163  // getLLVMDbgValue and getLLVMDbgInstruction are used for printing human
164  // readable info for SEGObjects This design is to eliminate the enumerating of
165  // SEG object types to print the required corresponding info for SEGObjects We
166  // try best to collect such info, For example, for callsite output nodes, if
167  // we want to distinguish the output values, we can use getLLVMDbgValue to get
168  // the value if we want to get the line number in the source code, we can use
169  // getLLVMDbgInstruction This function returns the callsite instruction
170  // containing the output node, which can be used to get the line number to
171  // find the callsite
172  //
173  // getLLVMDbgValue and getLLVMDbgInstruction are virtual functions in
174  // SEGObject. Thus, we can use them on each node in SEG, to print human
175  // readable debug info and still eliminate enumerating SEG Object types
176 
177  // Try best to collect the llvm value corresponding to the SEGObject
178  // For printing human readable Debug info relative to values
179  // SEGOperandNode : the value of the node
180  // SEGSite : the instruction
181  // Default : null
182  virtual Value *getLLVMDbgValue() const { return nullptr; }
183 
184  // Try best to collect the llvm instruction corresponding to the SEGObject
185  // For printing human readable Debug info requiring instructions
186  // In detail,
187  // For callsite pseudo-output nodes, we return the callsite
188  // For store mem node, we return the store site
189  // Otherwise, we return the instruction for the value if value exists or
190  // otherwise return null
191  virtual Instruction *getLLVMDbgInstruction() const {
192  Value *val = getLLVMDbgValue();
193  if (val != nullptr) {
194  return dyn_cast<Instruction>(val);
195  }
196 
197  return nullptr;
198  }
199 
200  SEGObjectKind getKind() const { return ObjKind; }
201 
202  std::string getSEGIndex() const { return SEGIndex; }
203 
204  void setObjIndex(int64_t index) { ObjIndex = index; }
205 
206  int64_t getObjIndex() const {
207  assert(ObjIndex != -1 && "Index should not be -1");
208  return ObjIndex;
209  }
210 
211  const char *getKindName() const;
212 
213  void setParentBasicBlock(BasicBlock *BB) { this->ParentBasicBlock = BB; }
214 
215  BasicBlock *getParentBasicBlock() const { return ParentBasicBlock; }
216 
217  Function *getParentFunction() const { return ParentBasicBlock->getParent(); }
218 
219  const SymbolicExprGraph *getParentGraph() const { return ParentGraph; }
220  SymbolicExprGraph *getParentGraph() { return ParentGraph; }
221 
222  friend raw_ostream &operator<<(llvm::raw_ostream &Out, const SEGObject &N);
223 };
224 
225 struct seg_cmp {
226  bool operator()(const SEGObject *A, const SEGObject *B) const {
227  std::string indexSEGA = A ? A->getSEGIndex() : "";
228  std::string indexSEGB = B ? B->getSEGIndex() : "";
229  if (indexSEGA != indexSEGB || (indexSEGA.empty() && indexSEGB.empty())) {
230  return indexSEGA < indexSEGB;
231  } else {
232  int64_t indexA = A ? A->getObjIndex() : -1;
233  int64_t indexB = B ? B->getObjIndex() : -1;
234  return indexA < indexB;
235  }
236  }
237 };
238 
240 class SEGNodeBase : public SEGObject {
241  friend class SEGSerializer;
242  friend class SEGHash;
243 
244 protected:
248  SEGNodeBase(SEGObjectKind K, Type *Ty, SymbolicExprGraph *SEG, BasicBlock *BB,
249  bool fromDisk);
250 
251  void setDescription(std::string &Desc) { Description = Desc; }
252 
253  friend class SymbolicExprGraph;
254 
255 private:
256  // This is useful for debugging
257  std::string Description;
258 
261  std::vector<SEGNodeBase *> Children;
262 
264  std::map<const SEGNodeBase *, float, seg_cmp> Parents;
265 
267  std::vector<SEGSiteBase *> UseSites;
268  std::set<SEGSiteBase *> UseSiteSet;
269 
271  Type *LLVMType = nullptr;
272 
274  SEGRegionNode *Region = nullptr;
275 
276 public:
277  virtual ~SEGNodeBase() {}
278 
280  Type *getLLVMType() const { return LLVMType; }
281 
282  SEGNodeBase *getChild(unsigned I) const {
283  assert(Children.size() > I &&
284  "Invalid child index when querying SEG edges");
285  return Children[I];
286  }
287 
288  float getConfidence(const SEGNodeBase *ParentNode) const {
289  auto It = Parents.find(ParentNode);
290  assert(It != Parents.end() &&
291  "Invalid parent node when querying SEG edges");
292  return It->second;
293  }
294 
295  unsigned getNumChildren() const { return Children.size(); }
296 
297  unsigned getNumParents() const { return Parents.size(); }
298 
299  void addChild(SEGNodeBase *N, float Confidence = 1.0f) {
300  Children.push_back(N);
301  N->Parents.insert(std::make_pair(this, Confidence));
302  }
303 
304  void eraseAllChildren() {
305  for (auto *Child : Children) {
306  Child->Parents.erase(this);
307  }
308  Children.clear();
309  }
310 
311  void addUseSite(SEGSiteBase *U) {
312  if (!UseSiteSet.count(U)) {
313  UseSiteSet.insert(U);
314  UseSites.push_back(U);
315  }
316  }
317 
318  virtual bool isTerminalNode() const { return Children.empty(); }
319 
320  SEGRegionNode *getRegion() const;
321 
322  bool containsParentNode(const SEGNodeBase *N) const {
323  return Parents.count(N);
324  }
325 
326  const std::string &getDescription() const { return Description; }
327 
329  virtual void dot(raw_fd_ostream &O) const = 0;
330 
331  friend raw_ostream &operator<<(llvm::raw_ostream &Out, const SEGNodeBase &N);
332 
333  /*==-------Iterators------==*/
335  private:
336  const SEGNodeBase *Node;
337  key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
338 
339  public:
340  ValueFlowIterator(const SEGNodeBase *N, bool End) : Node(N) {
341  if (End) {
342  It = N->parent_end();
343  } else {
344  It = N->parent_begin();
345  increment();
346  }
347  }
348 
350  : Node(VFIt.Node), It(VFIt.It) {}
351 
352  ValueFlowIterator &operator=(const ValueFlowIterator &VFIt) {
353  if (this != &VFIt) {
354  this->Node = VFIt.Node;
355  this->It = VFIt.It;
356  }
357  return *this;
358  }
359 
360  ValueFlowIterator operator++(int) {
361  ValueFlowIterator Old(*this);
362  ++(*this);
363  return Old;
364  }
365 
366  ValueFlowIterator &operator++() {
367  It++;
368  increment();
369  return *this;
370  }
371 
372  const SEGNodeBase *operator*() { return *It; }
373 
374  bool operator==(const ValueFlowIterator &VFIt) { return It == VFIt.It; }
375 
376  bool operator!=(const ValueFlowIterator &VFIt) { return It != VFIt.It; }
377 
378  private:
379  void increment();
380  };
381 
382  ValueFlowIterator vflow_begin() const { return {this, false}; }
383 
384  ValueFlowIterator vflow_end() const { return {this, true}; }
385 
386  key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
387  parent_begin() const {
388  return {Parents.begin()};
389  }
390 
391  key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
392  parent_end() const {
393  return {Parents.end()};
394  }
395 
396  iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
397  parents() const {
398  return {Parents.begin(), Parents.end()};
399  }
400 
401  std::vector<SEGNodeBase *>::const_iterator child_begin() const {
402  return Children.begin();
403  }
404 
405  std::vector<SEGNodeBase *>::const_iterator child_end() const {
406  return Children.end();
407  }
408 
409  iterator_range<std::vector<SEGNodeBase *>::const_iterator> children() const {
410  return {Children.begin(), Children.end()};
411  }
412 
413  std::map<const SEGNodeBase *, float>::const_iterator
414  parent_confidence_begin() const {
415  return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
416  Parents.begin());
417  }
418 
419  std::map<const SEGNodeBase *, float>::const_iterator
420  parent_confidence_end() const {
421  return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
422  Parents.end());
423  }
424 
425  size_t child_size() const { return Children.size(); }
426 
427  size_t parent_size() const { return Parents.size(); }
428 
429  std::vector<SEGSiteBase *>::const_iterator use_site_begin() const {
430  return UseSites.begin();
431  }
432 
433  std::vector<SEGSiteBase *>::const_iterator use_site_end() const {
434  return UseSites.end();
435  }
436 
437  iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
438  return {UseSites.begin(), UseSites.end()};
439  };
440 
441  size_t use_site_size() const { return UseSites.size(); }
442 
443 public:
444  static bool classof(const SEGObject *N) {
445  return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
446  }
447 };
448 
452 class SEGOperandNode : public SEGNodeBase {
453 protected:
456  Value *LLVMValue = nullptr;
457 
458  SEGValue *segValue = nullptr;
459 
461  SEGOperandNode(SEGObjectKind K, Type *Ty, SymbolicExprGraph *SEG,
462  BasicBlock *BB, bool fromDisk);
463 
475  SEGOperandNode(SEGObjectKind K, Value *Val, Type *Ty, SymbolicExprGraph *SEG,
476  BasicBlock *BB, bool fromDisk);
477 
479  friend class SymbolicExprGraph;
480  friend class SEGHash;
481 
482 public:
483  virtual ~SEGOperandNode() = 0;
484 
485  Value *getLLVMValue() const { return LLVMValue; }
486 
487  SEGValue *getSEGValue() const { return segValue; }
488 
489  void dot(raw_fd_ostream &O) const override;
490 
491  friend raw_ostream &operator<<(llvm::raw_ostream &Out,
492  const SEGOperandNode &N) {
493  if (Value *Val = N.getLLVMValue()) {
494  Out << *Val;
495  } else {
496  Out << N.getDescription();
497  }
498  return Out;
499  }
500 
501  virtual Value *getLLVMDbgValue() const override { return getLLVMValue(); }
502 
503 public:
504  static bool classof(const SEGObject *N) {
505  return N->getKind() >= SEGOBJK_OperandBegin &&
506  N->getKind() <= SEGOBJK_OperandEnd;
507  }
508 
509 private:
510  void initialize(Value *Val);
511 };
512 
515 class SEGOpcodeNode : public SEGNodeBase {
516 
517 public:
518  enum CodeKind {
519  CK_BinaryBegin,
520  CK_URem = CK_BinaryBegin,
521  CK_FRem,
522  CK_SRem,
523  CK_UDiv,
524  CK_FDiv,
525  CK_SDiv,
526  CK_And,
527  CK_Or,
528  CK_Xor,
529  CK_Add,
530  CK_FAdd,
531  CK_Sub,
532  CK_FSub,
533  CK_Mul,
534  CK_FMul,
535  CK_Shl,
536  CK_LShr,
537  CK_AShr,
538  CK_BinaryEnd = CK_AShr,
539 
540  CK_CastBegin,
541  CK_AddressCast = CK_CastBegin,
542  CK_Int2Ptr,
543  CK_Ptr2Int,
544  CK_Bitcast,
545  CK_Trunc,
546  CK_FPTrunc,
547  CK_SExt,
548  CK_ZExt,
549  CK_FPExt,
550  CK_SI2FP,
551  CK_FP2SI,
552  CK_UI2FP,
553  CK_FP2UI,
554  CK_CastEnd = CK_FP2UI,
555 
556  CK_ExtractElmt,
557  CK_InsertElmt,
558 
559  CK_Select,
560 
561  CK_GetElmtPtr,
562 
563  CK_Concat,
564 
565  CK_CmpBegin,
566  // Predicates for comparing floating numbers
567  // U L G E Intuitive operation
568  CK_FFalse = CK_CmpBegin,
584 
585  // Predicates for comparing integers
596  CK_CmpEnd = CK_ISLE,
597 
598  CK_InvalidCode,
599  };
600 
601 protected:
602  CodeKind Opcode;
603 
605  SEGOpcodeNode(SEGObjectKind K, CodeKind Opcode, Type *Ty,
606  SymbolicExprGraph *SEG, BasicBlock *BB, bool fromDisk);
607 
609  friend class SymbolicExprGraph;
610 
611 public:
612  virtual ~SEGOpcodeNode() = 0;
613 
614  CodeKind getOpcode() const { return Opcode; }
615 
616  virtual void dot(raw_fd_ostream &O) const;
617 
618  bool isCmpNode() const {
619  return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
620  }
621 
622  bool isSignedCmp() const { return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
623 
624  bool isUnSignedCmp() const { return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
625 
626  bool isFloatCmp() const { return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
627 
628  bool isAddNode() const { return Opcode == CK_Add; }
629 
630  bool isSubNode() const { return Opcode == CK_Sub; }
631 
632  bool isGEPNode() const { return Opcode == CK_GetElmtPtr; }
633 
634  bool isSelectNode() const { return Opcode == CK_Select; }
635 
636  bool isCastNode() const {
637  return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
638  }
639 
640  bool isBinaryNode() const {
641  return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
642  }
643 
644  bool isExtractElmtNode() const { return Opcode == CK_ExtractElmt; }
645 
646  bool isInsertElmtNode() const { return Opcode == CK_InsertElmt; }
647 
648  bool isConcatNode() const { return Opcode == CK_Concat; }
649 
650 public:
651  static bool classof(const SEGObject *N) {
652  return N->getKind() >= SEGOBJK_OpcodeBegin &&
653  N->getKind() <= SEGOBJK_OpcodeEnd;
654  }
655 
656  static const char *getOpcodeName(CodeKind CK);
657 };
658 
659 class SEGSiteBase : public SEGObject {
660 
661 private:
662  Instruction *User = nullptr;
663 
664  SEGValue *segValue = nullptr;
665 
666 protected:
667  SEGSiteBase(SEGObjectKind K, Instruction *User, SymbolicExprGraph *G,
668  bool fromDisk);
669  friend class SymbolicExprGraph;
670 
671 public:
672  virtual ~SEGSiteBase() = 0;
673 
674  CallSite getLLVMCallSite() const { return CallSite(User); }
675 
676  Instruction *getInstruction() const { return User; }
677 
678  SEGValue *getSEGValue() const { return segValue; }
679 
680  virtual Value *getLLVMDbgValue() const override { return getInstruction(); }
681 
682  friend raw_ostream &operator<<(llvm::raw_ostream &Out,
683  const SEGSiteBase &US) {
684  Out << *US.User;
685  return Out;
686  }
687 
688 public:
689  static bool classof(const SEGObject *O) {
690  return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
691  }
692 };
693 
694 namespace FalconPlus {
695 class AbstractCond;
696 class RegionCond;
697 class IntraFalcon;
698 class AbstractCondPtr;
699 class MemValueSet;
700 } // namespace FalconPlus
701 
702 namespace SymbolicExecution {
703 class AnalysisState;
704 }; // namespace SymbolicExecution
705 
707 
708  friend class SEGRegionNode;
709  friend class SymbolicExprGraphBuilder;
710  friend class IntraFalcon;
711  friend class PTGraph;
712  friend class SEGObject;
713  friend class OCValueFlowBuilder;
714  friend class SEGSerializer;
715 
716  friend class FalconPlus::AbstractCond;
717  friend class FalconPlus::RegionCond;
718  friend class FalconPlus::IntraFalcon;
719  friend class FalconPlus::AbstractCondPtr;
720  friend class FalconPlus::MemValueSet;
721 
722  friend class SymbolicExecution::AnalysisState;
723 
724 public:
725  struct CDGCond {
726  SEGNodeBase *CondNode;
727  BasicBlock *BB;
728  bool Cond;
729 
730  public:
731  CDGCond(SEGNodeBase *CN, BasicBlock *B, bool C)
732  : CondNode(CN), BB(B), Cond(C) {}
733 
734  bool operator<(const CDGCond &RHS) const {
735  return (CondNode < RHS.CondNode) ||
736  (CondNode == RHS.CondNode && BB < RHS.BB) ||
737  (CondNode == RHS.CondNode && BB == RHS.BB && Cond < RHS.Cond);
738  }
739 
740  bool operator==(const CDGCond &RHS) const {
741  return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
742  }
743 
744  BasicBlock *getBB() const { return BB; }
745  };
746 
747 private:
748  // The base function for this SEG
749  Function *BaseFunc = nullptr;
750 
751  // All the nodes in seg
752  std::vector<SEGObject *> NodesList;
753 
755  std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
756 
760  std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
761 
764  std::set<SEGNodeBase *> NonValueNodes;
765 
767  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>
768  StoreMemNodesMap;
769 
771  std::map<Instruction *, SEGSiteBase *> InstSiteMap;
772  std::vector<SEGCallSite *> CallSites;
773 
781  std::map<BasicBlock *, std::set<CDGCond> *> BlockCondMap;
782 
783  std::string SEGIndex;
784 
785 public:
786  // For Swap
787  std::string getSEGIndex() const {
788  assert(!SEGIndex.empty() && "SEGIndex should not be empty");
789  return SEGIndex;
790  }
791 
792  template <class T> T *getSEGObject(int64_t index) {
793  assert(index == -1 || (index >= 0 && index < NodesList.size()));
794  if (index == -1)
795  return nullptr;
796  auto *Obj = NodesList[index];
797  assert(isa<T>(Obj));
798  return (T *)Obj;
799  }
800 
801 private:
802  /*==--------------------Structures for Inter-procedural
803  * Analysis--------------------==*/
804  SEGCommonReturnNode *CommonReturn = nullptr;
805  kvec<SEGPseudoReturnNode *> PseudoReturns;
806 
807  kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
808  kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
809  kvec<SEGVarArgumentNode *> VarArgumentNodes;
810 
811  // Summary Nodes
812  // SEGNodeBase : the node
813  // int : the corresponding ap-depth (0 means ap-depth larger than considered)
814  //
815  // For each ap-depth, there is only one return summary node with a load mem
816  // node as child,
817  // which collects all values with conditions and confidence score, that
818  // may escape to caller with the corresponding ap-depth
819  // For each ap-depth, there can be multiple arg-summary node,
820  // each has a parent to the argument node that is not inlined
821  // Each summary node has type PTGraph::DEFAULT_NON_POINTER_TYPE
822  // which is currently int64 type
823  std::unordered_map<SEGNodeBase *, int> SummaryArgNodes;
824  std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
825  SummaryArgNodesCache;
826  std::unordered_map<SEGNodeBase *, int> SummaryReturnNodes;
827  std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
828  SummaryReturnNodesCache;
829 
831  std::map<std::string, SEGOperandNode *> NameToPseudoArgNode;
832  std::unordered_map<std::string, SEGOperandNode *> NameToNonArgPseudoNode;
833  std::unordered_map<std::string, std::unique_ptr<PseudoVal>> PseudoValStorage;
834 
835  void addCommonArgumentNodes(SEGCommonArgumentNode *Node);
836 
837  void addPseudoArgumentNodes(SEGPseudoArgumentNode *Node);
838 
839  void addVarArgumentNodes(SEGVarArgumentNode *Node);
840 
841  void setCommonReturnNode(SEGCommonReturnNode *Node);
842 
843  void addPseudoReturnNode(SEGPseudoReturnNode *Node);
844 
845  void addSummaryArgNode(SEGNodeBase *Node, int APDepth);
846 
847  void addSummaryReturnNode(SEGNodeBase *Node, int APDepth);
848 
849 public:
850  size_t getNumCommonArgument() const { return CommonArgumentNodes.size(); }
851 
852  size_t getNumPseudoArgument() const { return PseudoArgumentNodes.size(); }
853 
854  size_t getNumVarArgument() const { return VarArgumentNodes.size(); }
855 
856  size_t getNumPseudoReturn() const { return PseudoReturns.size(); }
857 
858  bool hasCommonReturnNode() const {
859  if (CommonReturn)
860  return true;
861  else
862  return false;
863  }
864 
865  const SEGCommonReturnNode *getCommonReturn() const { return CommonReturn; }
866 
867  const SEGPseudoReturnNode *getPseudoReturn(size_t Index) const {
868  return PseudoReturns[Index];
869  }
870 
871  const SEGCommonArgumentNode *getCommonArgument(size_t Index) const {
872  return CommonArgumentNodes[Index];
873  }
874 
875  const SEGPseudoArgumentNode *getPseudoArgument(size_t Index) const {
876  return PseudoArgumentNodes[Index];
877  }
878 
879  const SEGVarArgumentNode *getVarArgument(size_t Index) const {
880  return VarArgumentNodes[Index];
881  }
882 
883  bool isSummaryArgument(const SEGNodeBase *Node) const;
884 
885  // Return the ap-depth of an SEGNodeBase as summary argument.
886  // If the node is not a summary argument, return -1.
887  int getSummaryArgumentAPDepth(const SEGNodeBase *Node) const;
888 
889  // Get the set of summary argument nodes given APDepth
890  // Return null if not exist
891  std::unordered_set<SEGNodeBase *> *getSummaryArgument(int APDepth) const;
892 
893  bool isSummaryReturn(const SEGNodeBase *Node) const;
894 
895  // Return the ap-depth of an SEGNodeBase as summary return node.
896  // If the node is not a summary return node, return -1.
897  int getSummaryReturnAPDepth(const SEGNodeBase *Node) const;
898 
899  // Get the set of summary return nodes given APDepth
900  // Return null if not exist
901  std::unordered_set<SEGNodeBase *> *getSummaryReturn(int APDepth) const;
902 
903  // Return if the value represented by the Node is directly passed to/from
904  // caller A node is directly passed to/from caller if either it is a common or
905  // pseudo return/argument node or a summary return/argument node. A node is
906  // indirectly passed to/from caller if one of it's ancestor/descendant is
907  // directly passed to/from caller
908  bool isDirectlyPassedToCaller(const SEGNodeBase *Node) const;
909  bool isDirectlyPassedFromCaller(const SEGNodeBase *Node) const;
910 
911 private:
912  // Cache of region nodes to avoid multiple creation of same regions
913  // Positive regions: Value of SEGNodeBase is true
914  // Negative regions: Value of SEGNodeBase is false
915  // compond_regions_cache_and: SEGRegionNode(3) is SEGRegionNode(1) and
916  // SEGRegionNode(2) compond_regions_cache_or: SEGRegionNode(3) is
917  // SEGRegionNode(1) or SEGRegionNode(2) Note, for compound regions, we assume
918  // (pointer) value SEGRegionNode*(1) < SEGRegionNode*(2)
919  std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
920  std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
921  std::unordered_map<SEGRegionNode *,
922  std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
923  compound_regions_cache_and;
924  std::unordered_map<SEGRegionNode *,
925  std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
926  compound_regions_cache_or;
927 
928  // cache the corresponding region nodes for basic blocks
929  std::unordered_map<BasicBlock *, SEGRegionNode *> bb_region_cache;
930 
931 public:
932  void clearRegionNodeCache();
933 
934 private:
935  // All the functions that may change the SEG (i.e. have side-effects on the
936  // SEG) are private) Meaning that the SEG cannot be changed once created. Only
937  // friend class of SEG can modify the SEG, which is used to protect the SEG
938  // from modified by checkers
939 
950  SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
951 
954  template <class OperandNodeTy>
955  OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
956  bool fromDisk = false) {
957  assert(Ty && BB);
958  assert(Val && !Val->getType()->isVoidTy());
959  assert((!(dyn_cast<Instruction>(Val)) ||
960  BB == ((Instruction *)Val)->getParent()) &&
961  "Incorrect BasicBlock detected");
962 
963  auto It = ValueNodesMap.find(Val);
964  if (It != ValueNodesMap.end()) {
965  assert(isa<OperandNodeTy>(It->second));
966  return (OperandNodeTy *)It->second;
967  } else {
968  auto *N = new OperandNodeTy(Val, Ty, this, BB, fromDisk);
969  ValueNodePairs.push_back({Val, N});
970  ValueNodesMap[Val] = N;
971  return N;
972  }
973  }
974 
976 
977  template <class OperandNodeTy>
978  OperandNodeTy *
979  clonePseudoVal(const PseudoVal *Arg,
980  std::function<OperandNodeTy *(const PseudoVal *)> Proc) {
981  const std::string &ArgName = Arg->getName();
982  auto ClonedArg = std::unique_ptr<PseudoVal>(Arg->clone());
983  auto *ArgNode = Proc(ClonedArg.get());
984 
985  if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
986  NameToPseudoArgNode.insert(std::make_pair(ArgName, ArgNode));
987  } else {
988  NameToNonArgPseudoNode.insert(std::make_pair(ArgName, ArgNode));
989  }
990 
991  assert(!PseudoValStorage.count(ArgName));
992  PseudoValStorage.insert({ArgName, std::move(ClonedArg)});
993  return ArgNode;
994  }
995 
996  template <class OperandNodeTy>
997  OperandNodeTy *
998  findOrClonePseudoVal(const PseudoVal *Arg,
999  std::function<OperandNodeTy *(const PseudoVal *)> Proc) {
1000  const std::string &ArgName = Arg->getName();
1001  if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
1002  if (NameToPseudoArgNode.count(ArgName)) {
1003  return cast<OperandNodeTy>(NameToPseudoArgNode.at(ArgName));
1004  }
1005  } else {
1006  if (NameToNonArgPseudoNode.count(ArgName)) {
1007  static_assert(
1008  std::is_base_of<SEGOperandNode, OperandNodeTy>::value,
1009  "OperandNodeTy must be a derived class of SEGOperandNode.");
1010  return cast<OperandNodeTy>(NameToNonArgPseudoNode.at(ArgName));
1011  }
1012  }
1013 
1014  return clonePseudoVal<OperandNodeTy>(Arg, Proc);
1015  }
1016 
1017  SEGPseudoArgumentNode *findOrCreatePseudoArgumentNode(const PseudoVal *Arg,
1018  BasicBlock *BB);
1019  // Call this after all pseudo args have been created.
1020  void finalizePseudoArgumentNodes();
1021  SEGOperandNode *findOrCreateSimpleOperandFromPseudoVal(const PseudoVal *Arg,
1022  BasicBlock *BB);
1023  SEGPseudoReturnNode *createPseudoReturnNode(const PseudoVal *Arg,
1024  BasicBlock *BB);
1025  SEGCallSitePseudoInputNode *createPseudoInputNode(const PseudoVal *Arg,
1026  BasicBlock *BB, CallSite CS,
1027  Function *Callee);
1028  SEGCallSitePseudoOutputNode *createPseudoOutputNode(const PseudoVal *Arg,
1029  BasicBlock *BB,
1030  CallInst *Call,
1031  Function *Callee);
1032 
1033  template <class OperandNodeTy>
1034  OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
1035  bool fromDisk = false) {
1036  assert(Ty && BB);
1037  assert(Val && !Val->getType()->isVoidTy());
1038  assert((!(dyn_cast<Instruction>(Val)) ||
1039  BB == ((Instruction *)Val)->getParent()) &&
1040  "Incorrect BasicBlock detected");
1041 
1042  auto *N = new OperandNodeTy(Val, Ty, this, BB, fromDisk);
1043  ValueNodesMap[Val] = N;
1044  ValueNodePairs.push_back({Val, N});
1045  return N;
1046  }
1047 
1048  template <class OperandNodeTy>
1049  OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB,
1050  bool fromDisk = false) {
1051  assert(Ty);
1052  assert(BB);
1053  auto *Ret = new OperandNodeTy(Ty, this, BB, fromDisk);
1054  NonValueNodes.insert(Ret);
1055  return Ret;
1056  }
1057 
1060  template <class SiteTy>
1061  SiteTy *findOrCreateSite(Instruction *I, bool fromDisk = false) {
1062  assert(I);
1063 
1064  auto It = InstSiteMap.find(I);
1065  if (It != InstSiteMap.end()) {
1066  assert(isa<SiteTy>(It->second));
1067  return (SiteTy *)It->second;
1068  } else {
1069  SiteTy *N = new SiteTy(I, this, fromDisk);
1070  InstSiteMap[I] = N;
1071 
1072  if (SEGCallSite *CS = dyn_cast<SEGCallSite>(N)) {
1073  CallSites.push_back(CS);
1074  }
1075 
1076  return N;
1077  }
1078  }
1079 
1080  // Create callSite argument summary node as operandNode(Type* Ty,
1081  // SymbolicExprGraph* SEG, BasicBlock* BB) for call site Callsite with
1082  // ap-depth APDepth
1084  createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1085  Instruction *Callsite, int APDepth,
1086  bool fromDisk = false);
1087 
1088  // Create callSite return summary node as operandNode(Type* Ty,
1089  // SymbolicExprGraph* SEG, BasicBlock* BB) for call site Callsite, with value
1090  // confidence Confidence
1092  createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1093  Instruction *Callsite, float Confidence,
1094  bool fromDisk = false);
1095 
1096  // find or create a call site output node
1098  findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1099  CallSite CS, Function *Callee, bool IsCommon);
1100 
1101  SEGCallSiteOutputNode *createCallSiteOutputNode(Value *Val, Type *Ty,
1102  BasicBlock *BB, CallSite CS,
1103  Function *Callee,
1104  bool IsCommon,
1105  bool fromDisk = false);
1106 
1107  // find or create a call site pseudo input node
1109  findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1110  CallSite CS, Function *Callee,
1111  bool fromDisk = false);
1112 
1114  SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1115  Value *StoreVal, BasicBlock *BB,
1116  bool fromDisk = false);
1117 
1118  // Create a region node
1119  SEGRegionNode *createRegionNode(SEGNodeBase *cond_node = nullptr,
1120  bool cond = false, bool fromDisk = false);
1121 
1122  // Find or create a Region node from a region unit (with boolean value
1123  // cond_node == cond)
1124  SEGRegionNode *findOrCreateUnitRegion(SEGNodeBase *cond_node, bool cond);
1125 
1126  // Find or create a Region node "region1 and region2"
1127  SEGRegionNode *findOrCreateAndRegion(SEGRegionNode *region1,
1128  SEGRegionNode *region2);
1129 
1130  // Find or create a Region node "region1 or region2"
1131  SEGRegionNode *findOrCreateOrRegion(SEGRegionNode *region1,
1132  SEGRegionNode *region2);
1133 
1134  // Find or create a Region node "not region1"
1135  SEGRegionNode *findOrCreateNotRegion(SEGRegionNode *region1);
1136 
1137  // Find or create a node representing a constant bool value : Constant True or
1138  // Constant False
1139  SEGOperandNode *findOrCreateConstantBoolNode(bool bool_val);
1140 
1144  SEGSimpleOpcodeNode *createExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1145  BasicBlock *BB, SEGNodeBase *FirstOperand,
1146  ...);
1147 
1151  SEGSimpleOpcodeNode *createExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1152  BasicBlock *BB, const kvec<SEGNodeBase *> &,
1153  bool fromDisk = false);
1154 
1156  SEGCastNode *createCastExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1157  BasicBlock *BB, SEGNodeBase *Op, uint64_t OSz,
1158  uint64_t TSz, bool fromDisk = false);
1159 
1162  createBinaryWithIntConstExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1163  BasicBlock *BB, SEGNodeBase *Op, uint64_t TSz,
1164  bool fromDisk = false);
1165 
1167  void addBlockCond(BasicBlock *CurrBB, SEGNodeBase *BrNode, BasicBlock *DepBB,
1168  bool Label);
1169 
1170 public:
1171  SymbolicExprGraph(Function *);
1172  ~SymbolicExprGraph();
1173 
1174  Function *getBaseFunc() const { return BaseFunc; }
1175 
1176  Module *getBaseModule() const { return BaseFunc->getParent(); }
1177 
1180  template <class SiteTy> SiteTy *findSite(Instruction *I) const {
1181  assert(I);
1182 
1183  auto It = InstSiteMap.find(I);
1184  if (It != InstSiteMap.end()) {
1185  // assert(isa<SiteTy>(It->second));
1186  return dyn_cast<SiteTy>(It->second);
1187  } else {
1188  return nullptr;
1189  }
1190  }
1191 
1198  template <class SiteTy> SiteTy *findSite(SEGValue *sValue) const {
1199  Instruction *I = dyn_cast<Instruction>(sValue->getValue());
1200  assert(I);
1201 
1202  auto It = InstSiteMap.find(I);
1203  if (It != InstSiteMap.end()) {
1204  // assert(isa<SiteTy>(It->second));
1205  return dyn_cast<SiteTy>(It->second);
1206  } else {
1207  return nullptr;
1208  }
1209  }
1210 
1213  SEGOperandNode *findNode(Value *) const;
1214 
1215  SEGOperandNode *findNode(SEGValue *) const;
1216 
1217  // Find the Region node from a region unit (with boolean value cond_node ==
1218  // cond)
1220  SEGRegionNode *findUnitRegion(SEGNodeBase *cond_node, bool cond) const;
1221 
1222  // Find the Region node "region1 and region2"
1224  SEGRegionNode *findAndRegion(SEGRegionNode *region1,
1225  SEGRegionNode *region2) const;
1226 
1227  // Find the Region node "region1 or region2"
1229  SEGRegionNode *findOrRegion(SEGRegionNode *region1,
1230  SEGRegionNode *region2) const;
1231 
1232  // Find the Region node "not region1"
1234  SEGRegionNode *findNotRegion(SEGRegionNode *region1) const;
1235 
1239  const std::set<CDGCond> *getBlockCond(BasicBlock *BB) const {
1240  auto It = BlockCondMap.find(BB);
1241  if (It != BlockCondMap.end()) {
1242  return It->second;
1243  }
1244  return nullptr;
1245  }
1246 
1248  void dot(const char *FileName) const;
1249 
1251  void dot(std::vector<const SEGNodeBase *> Srcs, const char *FileName) const;
1252 
1254  void validate();
1255 
1256  // Return the region node for the corresponding basicblock, if not computed,
1257  // we compute and generate a new region
1258  SEGRegionNode *findOrCreateRegionForBB(BasicBlock *BB);
1259 
1260  // Find the region for BB. If the region is not computed, we return null
1261  SEGRegionNode *findRegionForBB(BasicBlock *BB) const;
1262 
1263  /*==------------------------Iterators--------------------==*/
1264 
1265  std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1266  value_node_begin() const {
1267  return ValueNodesMap.begin();
1268  }
1269 
1270  std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1271  value_node_end() const {
1272  return ValueNodesMap.end();
1273  }
1274 
1275  std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1276  value_node_pair_begin() const {
1277  return ValueNodePairs.begin();
1278  }
1279 
1280  std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1281  value_node_pair_end() const {
1282  return ValueNodePairs.end();
1283  }
1284 
1285  std::set<SEGNodeBase *>::const_iterator non_value_node_begin() const {
1286  return NonValueNodes.begin();
1287  }
1288 
1289  std::set<SEGNodeBase *>::const_iterator non_value_node_end() const {
1290  return NonValueNodes.end();
1291  }
1292 
1293  std::map<Instruction *, SEGSiteBase *>::const_iterator
1294  inst_site_begin() const {
1295  return InstSiteMap.begin();
1296  }
1297 
1298  std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end() const {
1299  return InstSiteMap.end();
1300  }
1301 
1302  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>::const_iterator
1303  store_mem_node_begin() const {
1304  return StoreMemNodesMap.begin();
1305  }
1306 
1307  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>::const_iterator
1308  store_mem_node_end() const {
1309  return StoreMemNodesMap.end();
1310  }
1311 
1312  std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin() const {
1313  return InstSiteMap.begin();
1314  }
1315 
1316  std::map<Instruction *, SEGSiteBase *>::const_iterator site_end() const {
1317  return InstSiteMap.end();
1318  }
1319 
1320  std::vector<SEGObject *>::const_iterator node_begin() const {
1321  return NodesList.begin();
1322  }
1323 
1324  std::vector<SEGObject *>::const_iterator node_end() const {
1325  return NodesList.end();
1326  }
1327 
1329  private:
1330  size_t I;
1331  SEGCommonReturnNode *CommonRet;
1332  const kvec<SEGPseudoReturnNode *> &PseudoRets;
1333 
1334  public:
1335  ReturnIterator(size_t Id, SEGCommonReturnNode *CR,
1336  const kvec<SEGPseudoReturnNode *> &PRs)
1337  : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1338 
1339  ReturnIterator(const ReturnIterator &It)
1340  : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1341 
1342  ReturnIterator &operator++() {
1343  I++;
1344  return *this;
1345  }
1346 
1347  ReturnIterator operator++(int) {
1348  ReturnIterator Old(*this);
1349  ++(*this);
1350  return Old;
1351  }
1352 
1353  const SEGReturnNode *operator*() {
1354  if (CommonRet) {
1355  if (I == 0) {
1356  return (const SEGReturnNode *)CommonRet;
1357  } else {
1358  return (const SEGReturnNode *)PseudoRets[I - 1];
1359  }
1360  } else {
1361  return (const SEGReturnNode *)PseudoRets[I];
1362  }
1363  }
1364 
1365  bool operator==(const ReturnIterator &It) { return I == It.I; }
1366 
1367  bool operator!=(const ReturnIterator &It) { return I != It.I; }
1368  };
1369 
1370  ReturnIterator return_begin() const {
1371  return ReturnIterator(0, CommonReturn, PseudoReturns);
1372  }
1373 
1374  ReturnIterator return_end() const {
1375  return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1376  CommonReturn, PseudoReturns);
1377  }
1378 
1379  ReturnIterator pseudo_return_begin() const {
1380  size_t StartIndex = getCommonReturn() ? 1 : 0;
1381  return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1382  }
1383 
1384  ReturnIterator pseudo_return_end() const { return return_end(); }
1385 
1387  private:
1388  size_t I;
1389  const kvec<SEGCommonArgumentNode *> &CommonArgs;
1390  const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1391  const kvec<SEGVarArgumentNode *> &VarArgs;
1392 
1393  public:
1394  ArgumentIterator(size_t Id, const kvec<SEGCommonArgumentNode *> &CA,
1395  const kvec<SEGPseudoArgumentNode *> &PA,
1396  const kvec<SEGVarArgumentNode *> &VA)
1397  : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1398 
1400  : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1401  VarArgs(It.VarArgs) {}
1402 
1403  ArgumentIterator &operator++() {
1404  I++;
1405  return *this;
1406  }
1407 
1408  ArgumentIterator operator++(int) {
1409  ArgumentIterator Old(*this);
1410  ++(*this);
1411  return Old;
1412  }
1413 
1414  const SEGArgumentNode *operator*() {
1415  if (I < (size_t)CommonArgs.size()) {
1416  return (const SEGArgumentNode *)CommonArgs[I];
1417  }
1418 
1419  if (I < (size_t)(CommonArgs.size() + PseudoArgs.size())) {
1420  return (const SEGArgumentNode *)PseudoArgs[I - CommonArgs.size()];
1421  }
1422 
1423  assert(I <
1424  (size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1425  return (const SEGArgumentNode *)
1426  VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1427  }
1428 
1429  bool operator==(const ArgumentIterator &It) { return I == It.I; }
1430 
1431  bool operator!=(const ArgumentIterator &It) { return I != It.I; }
1432  };
1433 
1434  ArgumentIterator arg_begin() const {
1435  return ArgumentIterator(0, CommonArgumentNodes, PseudoArgumentNodes,
1436  VarArgumentNodes);
1437  }
1438 
1439  ArgumentIterator arg_end() const {
1440  size_t NumArgs =
1441  getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1442  return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1443  VarArgumentNodes);
1444  }
1445 
1446  ArgumentIterator common_arg_begin() const { return arg_begin(); }
1447 
1448  ArgumentIterator common_arg_end() const {
1449  size_t NumArgs = getNumCommonArgument();
1450  return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1451  VarArgumentNodes);
1452  }
1453 
1454  ArgumentIterator pseudo_arg_begin() const { return common_arg_end(); }
1455 
1456  ArgumentIterator pseudo_arg_end() const {
1457  size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1458  return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1459  VarArgumentNodes);
1460  }
1461 
1462  ArgumentIterator var_arg_begin() const { return pseudo_arg_end(); }
1463 
1464  ArgumentIterator var_arg_end() const { return arg_end(); }
1465 
1466  typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1467  SEGCallSiteIterator seg_callsite_begin() const { return CallSites.begin(); }
1468 
1469  SEGCallSiteIterator seg_callsite_end() const { return CallSites.end(); }
1470 };
1471 
1472 #endif
SEGStoreMemNode
Definition: SEGStoreMemNode.h:23
SymbolicExprGraph::dot
void dot(const char *FileName) const
Dot this graph to a file with filename.
Definition: SymbolicExprGraph.cpp:894
SEGVarArgumentNode
Definition: SEGArgumentNode.h:89
SymbolicExprGraph::getBlockCond
const std::set< CDGCond > * getBlockCond(BasicBlock *BB) const
Definition: SymbolicExprGraph.h:1239
SymbolicExprGraph::ReturnIterator
Definition: SymbolicExprGraph.h:1328
SEGOpcodeNode::CK_FUGE
@ CK_FUGE
1 0 1 1 True if unordered, greater than, or equal
Definition: SymbolicExprGraph.h:579
SEGOperandNode
Definition: SymbolicExprGraph.h:452
SEGPseudoArgumentNode
Definition: SEGArgumentNode.h:121
SEGOpcodeNode::CK_FOGE
@ CK_FOGE
0 0 1 1 True if ordered and greater than or equal
Definition: SymbolicExprGraph.h:571
SEGOpcodeNode::CK_ISGT
@ CK_ISGT
signed greater than
Definition: SymbolicExprGraph.h:592
SEGOpcodeNode::CK_FOEq
@ CK_FOEq
0 0 0 1 True if ordered and equal
Definition: SymbolicExprGraph.h:569
SEGCallSiteOutputNode
Definition: SEGCallSiteOutputNode.h:19
SEGSimpleOpcodeNode
Definition: SEGSimpleOpcodeNode.h:18
SEGCallSite
Definition: SEGCallSite.h:51
SEGOpcodeNode::CK_FOrd
@ CK_FOrd
0 1 1 1 True if ordered (no nans)
Definition: SymbolicExprGraph.h:575
SEGOpcodeNode::CK_FONE
@ CK_FONE
0 1 1 0 True if ordered and operands are unequal
Definition: SymbolicExprGraph.h:574
SEGOpcodeNode::CodeKind
CodeKind
Definition: SymbolicExprGraph.h:518
SEGOpcodeNode::CK_FOLE
@ CK_FOLE
0 1 0 1 True if ordered and less than or equal
Definition: SymbolicExprGraph.h:573
SEGCallSiteArgumentSummaryNode
Definition: SEGCallSiteArgumentSummaryNode.h:17
SEGCastNode
Definition: SEGCastNode.h:18
SEGCommonArgumentNode
Definition: SEGArgumentNode.h:42
SEGOpcodeNode::CK_FULT
@ CK_FULT
1 1 0 0 True if unordered or less than
Definition: SymbolicExprGraph.h:580
SymbolicExprGraph
Definition: SymbolicExprGraph.h:706
SEGNodeBase::ValueFlowIterator
Definition: SymbolicExprGraph.h:334
SEGOpcodeNode::CK_ISLE
@ CK_ISLE
signed less or equal
Definition: SymbolicExprGraph.h:595
SEGOpcodeNode::CK_IULT
@ CK_IULT
unsigned less than
Definition: SymbolicExprGraph.h:590
SEGOpcodeNode::CK_IULE
@ CK_IULE
unsigned less or equal
Definition: SymbolicExprGraph.h:591
SEGOpcodeNode::CK_IEq
@ CK_IEq
equal
Definition: SymbolicExprGraph.h:586
SymbolicExprGraph::ArgumentIterator
Definition: SymbolicExprGraph.h:1386
SEGArgumentNode
Definition: SEGArgumentNode.h:18
SEGCallSiteReturnSummaryNode
Definition: SEGCallSiteReturnSummaryNode.h:20
SymbolicExprGraph::CDGCond
Definition: SymbolicExprGraph.h:725
SEGOpcodeNode::CK_IUGT
@ CK_IUGT
unsigned greater than
Definition: SymbolicExprGraph.h:588
SEGValue::getValue
Value * getValue()
Get Value.
Definition: SEGValue.h:66
SEGCommonReturnNode
Definition: SEGReturnNode.h:64
SEGOpcodeNode::CK_FUno
@ CK_FUno
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition: SymbolicExprGraph.h:576
SEGOptions
Definition: SymbolicExprGraph.h:70
SymbolicExprGraphBuilder
Definition: SymbolicExprGraphBuilder.h:35
SEGOpcodeNode::CK_ISGE
@ CK_ISGE
signed greater or equal
Definition: SymbolicExprGraph.h:593
SEGObject
Definition: SymbolicExprGraph.h:76
SEGOpcodeNode::CK_IUGE
@ CK_IUGE
unsigned greater or equal
Definition: SymbolicExprGraph.h:589
SEGCallSitePseudoInputNode
Definition: SEGCallSitePseudoInputNode.h:29
OCValueFlowBuilder
Definition: OCValueFlowBuilder.h:25
SEGValue
Definition: SEGValue.h:38
SEGPhiNode
Definition: SEGPhiNode.h:28
SEGOpcodeNode::CK_FOGT
@ CK_FOGT
0 0 1 0 True if ordered and greater than
Definition: SymbolicExprGraph.h:570
SEGOpcodeNode::CK_FUEq
@ CK_FUEq
1 0 0 1 True if unordered or equal
Definition: SymbolicExprGraph.h:577
SEGRegionNode
Definition: SEGRegionNode.h:34
SEGNodeBase::getLLVMType
Type * getLLVMType() const
get the type size of the node
Definition: SymbolicExprGraph.h:280
SEGOpcodeNode::CK_ISLT
@ CK_ISLT
signed less than
Definition: SymbolicExprGraph.h:594
SEGOpcodeNode::CK_FULE
@ CK_FULE
1 1 0 1 True if unordered, less than, or equal
Definition: SymbolicExprGraph.h:581
SEGOpcodeNode::CK_FUGT
@ CK_FUGT
1 0 1 0 True if unordered or greater than
Definition: SymbolicExprGraph.h:578
SEGCallSitePseudoOutputNode
Definition: SEGCallSiteOutputNode.h:76
SEGOpcodeNode::CK_FTrue
@ CK_FTrue
1 1 1 1 Always true (always folded)
Definition: SymbolicExprGraph.h:583
SEGOpcodeNode::CK_FUNE
@ CK_FUNE
1 1 1 0 True if unordered or not equal
Definition: SymbolicExprGraph.h:582
SEGPseudoReturnNode
Definition: SEGReturnNode.h:84
SEGOpcodeNode
Definition: SymbolicExprGraph.h:515
SymbolicExprGraph::findSite
SiteTy * findSite(SEGValue *sValue) const
Get site node based on Value and specific comparison method.
Definition: SymbolicExprGraph.h:1198
SymbolicExprGraph::findSite
SiteTy * findSite(Instruction *I) const
Definition: SymbolicExprGraph.h:1180
SEGSiteBase
Definition: SymbolicExprGraph.h:659
SEGReturnNode
The return node.
Definition: SEGReturnNode.h:25
seg_cmp
Definition: SymbolicExprGraph.h:225
SEGOpcodeNode::CK_INE
@ CK_INE
not equal
Definition: SymbolicExprGraph.h:587
SEGLoadMemNode
Definition: SEGLoadMemNode.h:21
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:240
SEGBinaryWithIntConstNode
Definition: SEGBinaryWithIntConstNode.h:19
SEGOpcodeNode::CK_FOLT
@ CK_FOLT
0 1 0 0 True if ordered and less than
Definition: SymbolicExprGraph.h:572