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