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 getNumNodes() const { return NodesList.size(); }
857 
858  size_t getNumCommonArgument() const { return CommonArgumentNodes.size(); }
859 
860  size_t getNumPseudoArgument() const { return PseudoArgumentNodes.size(); }
861 
862  size_t getNumVarArgument() const { return VarArgumentNodes.size(); }
863 
864  size_t getNumPseudoReturn() const { return PseudoReturns.size(); }
865 
866  bool hasCommonReturnNode() const {
867  if (CommonReturn)
868  return true;
869  else
870  return false;
871  }
872 
873  const SEGCommonReturnNode *getCommonReturn() const { return CommonReturn; }
874 
875  const SEGPseudoReturnNode *getPseudoReturn(size_t Index) const {
876  return PseudoReturns[Index];
877  }
878 
879  const SEGCommonArgumentNode *getCommonArgument(size_t Index) const {
880  return CommonArgumentNodes[Index];
881  }
882 
883  const SEGPseudoArgumentNode *getPseudoArgument(size_t Index) const {
884  return PseudoArgumentNodes[Index];
885  }
886 
887  const SEGVarArgumentNode *getVarArgument(size_t Index) const {
888  return VarArgumentNodes[Index];
889  }
890 
891  bool isSummaryArgument(const SEGNodeBase *Node) const;
892 
893  // Return the ap-depth of an SEGNodeBase as summary argument.
894  // If the node is not a summary argument, return -1.
895  int getSummaryArgumentAPDepth(const SEGNodeBase *Node) const;
896 
897  // Get the set of summary argument nodes given APDepth
898  // Return null if not exist
899  std::unordered_set<SEGNodeBase *> *getSummaryArgument(int APDepth) const;
900 
901  bool isSummaryReturn(const SEGNodeBase *Node) const;
902 
903  // Return the ap-depth of an SEGNodeBase as summary return node.
904  // If the node is not a summary return node, return -1.
905  int getSummaryReturnAPDepth(const SEGNodeBase *Node) const;
906 
907  // Get the set of summary return nodes given APDepth
908  // Return null if not exist
909  std::unordered_set<SEGNodeBase *> *getSummaryReturn(int APDepth) const;
910 
911  // Return if the value represented by the Node is directly passed to/from
912  // caller A node is directly passed to/from caller if either it is a common or
913  // pseudo return/argument node or a summary return/argument node. A node is
914  // indirectly passed to/from caller if one of it's ancestor/descendant is
915  // directly passed to/from caller
916  bool isDirectlyPassedToCaller(const SEGNodeBase *Node) const;
917  bool isDirectlyPassedFromCaller(const SEGNodeBase *Node) const;
918 
919 private:
920  // Cache of region nodes to avoid multiple creation of same regions
921  // Positive regions: Value of SEGNodeBase is true
922  // Negative regions: Value of SEGNodeBase is false
923  // compond_regions_cache_and: SEGRegionNode(3) is SEGRegionNode(1) and
924  // SEGRegionNode(2) compond_regions_cache_or: SEGRegionNode(3) is
925  // SEGRegionNode(1) or SEGRegionNode(2) Note, for compound regions, we assume
926  // (pointer) value SEGRegionNode*(1) < SEGRegionNode*(2)
927  std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
928  std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
929  std::unordered_map<SEGRegionNode *,
930  std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
931  compound_regions_cache_and;
932  std::unordered_map<SEGRegionNode *,
933  std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
934  compound_regions_cache_or;
935 
936  // cache the corresponding region nodes for basic blocks
937  std::unordered_map<BasicBlock *, SEGRegionNode *> bb_region_cache;
938 
939 public:
940  void clearRegionNodeCache();
941 
942 private:
943  // All the functions that may change the SEG (i.e. have side-effects on the
944  // SEG) are private) Meaning that the SEG cannot be changed once created. Only
945  // friend class of SEG can modify the SEG, which is used to protect the SEG
946  // from modified by checkers
947 
958  SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
959 
962  template <class OperandNodeTy>
963  OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
964  bool fromDisk = false) {
965  assert(Ty && BB);
966  assert(Val && !Val->getType()->isVoidTy());
967  assert((!(dyn_cast<Instruction>(Val)) ||
968  BB == ((Instruction *)Val)->getParent()) &&
969  "Incorrect BasicBlock detected");
970 
971  auto It = ValueNodesMap.find(Val);
972  if (It != ValueNodesMap.end()) {
973  assert(isa<OperandNodeTy>(It->second));
974  return (OperandNodeTy *)It->second;
975  } else {
976  auto *N = new OperandNodeTy(Val, Ty, this, BB, fromDisk);
977  ValueNodePairs.push_back({Val, N});
978  ValueNodesMap[Val] = N;
979  return N;
980  }
981  }
982 
984 
985  template <class OperandNodeTy>
986  OperandNodeTy *
987  clonePseudoVal(const PseudoVal *Arg,
988  std::function<OperandNodeTy *(const PseudoVal *)> Proc) {
989  const std::string &ArgName = Arg->getName();
990  auto ClonedArg = std::unique_ptr<PseudoVal>(Arg->clone());
991  auto *ArgNode = Proc(ClonedArg.get());
992 
993  if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
994  NameToPseudoArgNode.insert(std::make_pair(ArgName, ArgNode));
995  } else {
996  NameToNonArgPseudoNode.insert(std::make_pair(ArgName, ArgNode));
997  }
998 
999  assert(!PseudoValStorage.count(ArgName));
1000  PseudoValStorage.insert({ArgName, std::move(ClonedArg)});
1001  return ArgNode;
1002  }
1003 
1004  template <class OperandNodeTy>
1005  OperandNodeTy *
1006  findOrClonePseudoVal(const PseudoVal *Arg,
1007  std::function<OperandNodeTy *(const PseudoVal *)> Proc) {
1008  const std::string &ArgName = Arg->getName();
1009  if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
1010  if (NameToPseudoArgNode.count(ArgName)) {
1011  return cast<OperandNodeTy>(NameToPseudoArgNode.at(ArgName));
1012  }
1013  } else {
1014  if (NameToNonArgPseudoNode.count(ArgName)) {
1015  static_assert(
1016  std::is_base_of<SEGOperandNode, OperandNodeTy>::value,
1017  "OperandNodeTy must be a derived class of SEGOperandNode.");
1018  return cast<OperandNodeTy>(NameToNonArgPseudoNode.at(ArgName));
1019  }
1020  }
1021 
1022  return clonePseudoVal<OperandNodeTy>(Arg, Proc);
1023  }
1024 
1025  SEGPseudoArgumentNode *findOrCreatePseudoArgumentNode(const PseudoVal *Arg,
1026  BasicBlock *BB);
1027  // Call this after all pseudo args have been created.
1028  void finalizePseudoArgumentNodes();
1029  SEGOperandNode *findOrCreateSimpleOperandFromPseudoVal(const PseudoVal *Arg,
1030  BasicBlock *BB);
1031  SEGPseudoReturnNode *createPseudoReturnNode(const PseudoVal *Arg,
1032  BasicBlock *BB);
1033  SEGCallSitePseudoInputNode *createPseudoInputNode(const PseudoVal *Arg,
1034  BasicBlock *BB, CallSite CS,
1035  Function *Callee);
1036  SEGCallSitePseudoOutputNode *createPseudoOutputNode(const PseudoVal *Arg,
1037  BasicBlock *BB,
1038  CallInst *Call,
1039  Function *Callee);
1040 
1041  template <class OperandNodeTy>
1042  OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
1043  bool fromDisk = false) {
1044  assert(Ty && BB);
1045  assert(Val && !Val->getType()->isVoidTy());
1046  assert((!(dyn_cast<Instruction>(Val)) ||
1047  BB == ((Instruction *)Val)->getParent()) &&
1048  "Incorrect BasicBlock detected");
1049 
1050  auto *N = new OperandNodeTy(Val, Ty, this, BB, fromDisk);
1051  ValueNodesMap[Val] = N;
1052  ValueNodePairs.push_back({Val, N});
1053  return N;
1054  }
1055 
1056  template <class OperandNodeTy>
1057  OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB,
1058  bool fromDisk = false) {
1059  assert(Ty);
1060  assert(BB);
1061  auto *Ret = new OperandNodeTy(Ty, this, BB, fromDisk);
1062  NonValueNodes.insert(Ret);
1063  return Ret;
1064  }
1065 
1068  template <class SiteTy>
1069  SiteTy *findOrCreateSite(Instruction *I, bool fromDisk = false) {
1070  assert(I);
1071 
1072  auto It = InstSiteMap.find(I);
1073  if (It != InstSiteMap.end()) {
1074  assert(isa<SiteTy>(It->second));
1075  return (SiteTy *)It->second;
1076  } else {
1077  SiteTy *N = new SiteTy(I, this, fromDisk);
1078  InstSiteMap[I] = N;
1079 
1080  if (SEGCallSite *CS = dyn_cast<SEGCallSite>(N)) {
1081  CallSites.push_back(CS);
1082  }
1083 
1084  return N;
1085  }
1086  }
1087 
1088  // Create callSite argument summary node as operandNode(Type* Ty,
1089  // SymbolicExprGraph* SEG, BasicBlock* BB) for call site Callsite with
1090  // ap-depth APDepth
1092  createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1093  Instruction *Callsite, int APDepth,
1094  bool fromDisk = false);
1095 
1096  // Create callSite return summary node as operandNode(Type* Ty,
1097  // SymbolicExprGraph* SEG, BasicBlock* BB) for call site Callsite, with value
1098  // confidence Confidence
1100  createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1101  Instruction *Callsite, float Confidence,
1102  bool fromDisk = false);
1103 
1104  // find or create a call site output node
1106  findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1107  CallSite CS, Function *Callee, bool IsCommon);
1108 
1109  SEGCallSiteOutputNode *createCallSiteOutputNode(Value *Val, Type *Ty,
1110  BasicBlock *BB, CallSite CS,
1111  Function *Callee,
1112  bool IsCommon,
1113  bool fromDisk = false);
1114 
1115  // find or create a call site pseudo input node
1117  findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1118  CallSite CS, Function *Callee,
1119  bool fromDisk = false);
1120 
1122  SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1123  Value *StoreVal, BasicBlock *BB,
1124  bool fromDisk = false);
1125 
1126  // Create a region node
1127  SEGRegionNode *createRegionNode(SEGNodeBase *cond_node = nullptr,
1128  bool cond = false, bool fromDisk = false);
1129 
1130  // Find or create a Region node from a region unit (with boolean value
1131  // cond_node == cond)
1132  SEGRegionNode *findOrCreateUnitRegion(SEGNodeBase *cond_node, bool cond);
1133 
1134  // Find or create a Region node "region1 and region2"
1135  SEGRegionNode *findOrCreateAndRegion(SEGRegionNode *region1,
1136  SEGRegionNode *region2);
1137 
1138  // Find or create a Region node "region1 or region2"
1139  SEGRegionNode *findOrCreateOrRegion(SEGRegionNode *region1,
1140  SEGRegionNode *region2);
1141 
1142  // Find or create a Region node "not region1"
1143  SEGRegionNode *findOrCreateNotRegion(SEGRegionNode *region1);
1144 
1145  // Find or create a node representing a constant bool value : Constant True or
1146  // Constant False
1147  SEGOperandNode *findOrCreateConstantBoolNode(bool bool_val);
1148 
1152  SEGSimpleOpcodeNode *createExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1153  BasicBlock *BB, SEGNodeBase *FirstOperand,
1154  ...);
1155 
1159  SEGSimpleOpcodeNode *createExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1160  BasicBlock *BB, const kvec<SEGNodeBase *> &,
1161  bool fromDisk = false);
1162 
1164  SEGCastNode *createCastExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1165  BasicBlock *BB, SEGNodeBase *Op, uint64_t OSz,
1166  uint64_t TSz, bool fromDisk = false);
1167 
1170  createBinaryWithIntConstExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1171  BasicBlock *BB, SEGNodeBase *Op, uint64_t TSz,
1172  bool fromDisk = false);
1173 
1175  void addBlockCond(BasicBlock *CurrBB, SEGNodeBase *BrNode, BasicBlock *DepBB,
1176  bool Label);
1177 
1178 public:
1179  SymbolicExprGraph(Function *);
1180  ~SymbolicExprGraph();
1181 
1182  Function *getBaseFunc() const { return BaseFunc; }
1183 
1186  template <class SiteTy> SiteTy *findSite(Instruction *I) const {
1187  assert(I);
1188 
1189  auto It = InstSiteMap.find(I);
1190  if (It != InstSiteMap.end()) {
1191  // assert(isa<SiteTy>(It->second));
1192  return dyn_cast<SiteTy>(It->second);
1193  } else {
1194  return nullptr;
1195  }
1196  }
1197 
1204  template <class SiteTy> SiteTy *findSite(SEGValue *sValue) const {
1205  Instruction *I = dyn_cast<Instruction>(sValue->getValue());
1206  assert(I);
1207 
1208  auto It = InstSiteMap.find(I);
1209  if (It != InstSiteMap.end()) {
1210  // assert(isa<SiteTy>(It->second));
1211  return dyn_cast<SiteTy>(It->second);
1212  } else {
1213  return nullptr;
1214  }
1215  }
1216 
1219  SEGOperandNode *findNode(Value *) const;
1220 
1221  SEGOperandNode *findNode(SEGValue *) const;
1222 
1223  // Find the Region node from a region unit (with boolean value cond_node ==
1224  // cond)
1226  SEGRegionNode *findUnitRegion(SEGNodeBase *cond_node, bool cond) const;
1227 
1228  // Find the Region node "region1 and region2"
1230  SEGRegionNode *findAndRegion(SEGRegionNode *region1,
1231  SEGRegionNode *region2) const;
1232 
1233  // Find the Region node "region1 or region2"
1235  SEGRegionNode *findOrRegion(SEGRegionNode *region1,
1236  SEGRegionNode *region2) const;
1237 
1238  // Find the Region node "not region1"
1240  SEGRegionNode *findNotRegion(SEGRegionNode *region1) const;
1241 
1245  const std::set<CDGCond> *getBlockCond(BasicBlock *BB) const {
1246  auto It = BlockCondMap.find(BB);
1247  if (It != BlockCondMap.end()) {
1248  return It->second;
1249  }
1250  return nullptr;
1251  }
1252 
1254  void dot(const char *FileName) const;
1255 
1257  void dot(std::vector<const SEGNodeBase *> Srcs, const char *FileName) const;
1258 
1260  void validate();
1261 
1262  // Return the region node for the corresponding basicblock, if not computed,
1263  // we compute and generate a new region
1264  SEGRegionNode *findOrCreateRegionForBB(BasicBlock *BB);
1265 
1266  // Find the region for BB. If the region is not computed, we return null
1267  SEGRegionNode *findRegionForBB(BasicBlock *BB) const;
1268 
1269  /*==------------------------Iterators--------------------==*/
1270 
1271  std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1272  value_node_begin() const {
1273  return ValueNodesMap.begin();
1274  }
1275 
1276  std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1277  value_node_end() const {
1278  return ValueNodesMap.end();
1279  }
1280 
1281  std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1282  value_node_pair_begin() const {
1283  return ValueNodePairs.begin();
1284  }
1285 
1286  std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1287  value_node_pair_end() const {
1288  return ValueNodePairs.end();
1289  }
1290 
1291  std::set<SEGNodeBase *>::const_iterator non_value_node_begin() const {
1292  return NonValueNodes.begin();
1293  }
1294 
1295  std::set<SEGNodeBase *>::const_iterator non_value_node_end() const {
1296  return NonValueNodes.end();
1297  }
1298 
1299  std::map<Instruction *, SEGSiteBase *>::const_iterator
1300  inst_site_begin() const {
1301  return InstSiteMap.begin();
1302  }
1303 
1304  std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end() const {
1305  return InstSiteMap.end();
1306  }
1307 
1308  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>::const_iterator
1309  store_mem_node_begin() const {
1310  return StoreMemNodesMap.begin();
1311  }
1312 
1313  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>::const_iterator
1314  store_mem_node_end() const {
1315  return StoreMemNodesMap.end();
1316  }
1317 
1318  std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin() const {
1319  return InstSiteMap.begin();
1320  }
1321 
1322  std::map<Instruction *, SEGSiteBase *>::const_iterator site_end() const {
1323  return InstSiteMap.end();
1324  }
1325 
1326  std::vector<SEGObject *>::const_iterator node_begin() const {
1327  return NodesList.begin();
1328  }
1329 
1330  std::vector<SEGObject *>::const_iterator node_end() const {
1331  return NodesList.end();
1332  }
1333 
1335  private:
1336  size_t I;
1337  SEGCommonReturnNode *CommonRet;
1338  const kvec<SEGPseudoReturnNode *> &PseudoRets;
1339 
1340  public:
1341  ReturnIterator(size_t Id, SEGCommonReturnNode *CR,
1342  const kvec<SEGPseudoReturnNode *> &PRs)
1343  : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1344 
1345  ReturnIterator(const ReturnIterator &It)
1346  : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1347 
1348  ReturnIterator &operator++() {
1349  I++;
1350  return *this;
1351  }
1352 
1353  ReturnIterator operator++(int) {
1354  ReturnIterator Old(*this);
1355  ++(*this);
1356  return Old;
1357  }
1358 
1359  const SEGReturnNode *operator*() {
1360  if (CommonRet) {
1361  if (I == 0) {
1362  return (const SEGReturnNode *)CommonRet;
1363  } else {
1364  return (const SEGReturnNode *)PseudoRets[I - 1];
1365  }
1366  } else {
1367  return (const SEGReturnNode *)PseudoRets[I];
1368  }
1369  }
1370 
1371  bool operator==(const ReturnIterator &It) { return I == It.I; }
1372 
1373  bool operator!=(const ReturnIterator &It) { return I != It.I; }
1374  };
1375 
1376  ReturnIterator return_begin() const {
1377  return ReturnIterator(0, CommonReturn, PseudoReturns);
1378  }
1379 
1380  ReturnIterator return_end() const {
1381  return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1382  CommonReturn, PseudoReturns);
1383  }
1384 
1385  ReturnIterator pseudo_return_begin() const {
1386  size_t StartIndex = getCommonReturn() ? 1 : 0;
1387  return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1388  }
1389 
1390  ReturnIterator pseudo_return_end() const { return return_end(); }
1391 
1393  private:
1394  size_t I;
1395  const kvec<SEGCommonArgumentNode *> &CommonArgs;
1396  const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1397  const kvec<SEGVarArgumentNode *> &VarArgs;
1398 
1399  public:
1400  ArgumentIterator(size_t Id, const kvec<SEGCommonArgumentNode *> &CA,
1401  const kvec<SEGPseudoArgumentNode *> &PA,
1402  const kvec<SEGVarArgumentNode *> &VA)
1403  : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1404 
1406  : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1407  VarArgs(It.VarArgs) {}
1408 
1409  ArgumentIterator &operator++() {
1410  I++;
1411  return *this;
1412  }
1413 
1414  ArgumentIterator operator++(int) {
1415  ArgumentIterator Old(*this);
1416  ++(*this);
1417  return Old;
1418  }
1419 
1420  const SEGArgumentNode *operator*() {
1421  if (I < (size_t)CommonArgs.size()) {
1422  return (const SEGArgumentNode *)CommonArgs[I];
1423  }
1424 
1425  if (I < (size_t)(CommonArgs.size() + PseudoArgs.size())) {
1426  return (const SEGArgumentNode *)PseudoArgs[I - CommonArgs.size()];
1427  }
1428 
1429  assert(I <
1430  (size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1431  return (const SEGArgumentNode *)
1432  VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1433  }
1434 
1435  bool operator==(const ArgumentIterator &It) { return I == It.I; }
1436 
1437  bool operator!=(const ArgumentIterator &It) { return I != It.I; }
1438  };
1439 
1440  ArgumentIterator arg_begin() const {
1441  return ArgumentIterator(0, CommonArgumentNodes, PseudoArgumentNodes,
1442  VarArgumentNodes);
1443  }
1444 
1445  ArgumentIterator arg_end() const {
1446  size_t NumArgs =
1447  getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1448  return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1449  VarArgumentNodes);
1450  }
1451 
1452  ArgumentIterator common_arg_begin() const { return arg_begin(); }
1453 
1454  ArgumentIterator common_arg_end() const {
1455  size_t NumArgs = getNumCommonArgument();
1456  return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1457  VarArgumentNodes);
1458  }
1459 
1460  ArgumentIterator pseudo_arg_begin() const { return common_arg_end(); }
1461 
1462  ArgumentIterator pseudo_arg_end() const {
1463  size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1464  return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1465  VarArgumentNodes);
1466  }
1467 
1468  ArgumentIterator var_arg_begin() const { return pseudo_arg_end(); }
1469 
1470  ArgumentIterator var_arg_end() const { return arg_end(); }
1471 
1472  typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1473  SEGCallSiteIterator seg_callsite_begin() const { return CallSites.begin(); }
1474 
1475  SEGCallSiteIterator seg_callsite_end() const { return CallSites.end(); }
1476 };
1477 
1478 #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:1245
SymbolicExprGraph::ReturnIterator
Definition: SymbolicExprGraph.h:1334
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:1392
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:1204
SymbolicExprGraph::findSite
SiteTy * findSite(Instruction *I) const
Definition: SymbolicExprGraph.h:1186
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