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