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