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