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/FalconPlus/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 #include "IR/LLVMWrapper/CallsiteWrapper.h"
36 #include "IR/LLVMWrapper/InstructionWrapper.h"
37 #include "IR/LLVMWrapper/SEGType.h"
38 #include "IR/LLVMWrapper/ValueWrapper.h"
39 
40 using namespace llvm;
41 
42 class SEGCallSite;
48 
49 class SEGOpcodeNode;
50 class SEGOperandNode;
51 class SEGRegionNode;
52 class SEGPhiNode;
53 class SEGLoadMemNode;
54 class SEGStoreMemNode;
55 
56 class SEGReturnNode;
59 
60 class SEGArgumentNode;
63 class SEGVarArgumentNode;
64 
65 class SEGCastNode;
67 
68 class SEGSiteBase;
69 
70 class SymbolicExprGraph;
72 class OCValueFlowBuilder;
73 
74 class PersistedSEGObject;
75 class PersistedSEGNodeBase;
76 class PersistedSEGOpcodeNode;
77 class PersistedSEGOperandNode;
78 class PersistedSEGSiteBase;
79 class PersistedSymbolicExprGraph;
80 
81 class SEGOptions {
82 public:
83  static bool EnableValueToString;
84  static bool EnableArithmeticFlow;
85 };
86 
87 class SEGObject {
88 public:
89  enum SEGObjectKind {
90  // nodes
91  SEGOBJK_NodeBegin,
92  // operand nodes
93  SEGOBJK_OperandBegin,
94 
95  SEGOBJK_ArgumentBegin,
96  SEGOBJK_CommonArgument,
97  SEGOBJK_VarArgument,
98  SEGOBJK_PseudoArgument,
99  SEGOBJK_ArgumentEnd,
100 
101  SEGOBJK_CallSiteOutputBegin,
102  SEGOBJK_CallSiteCommonOutput,
103  SEGOBJK_CallSitePseudoOutput,
104  SEGOBJK_CallSiteOutputEnd,
105 
106  SEGOBJK_ReturnBegin,
107  SEGOBJK_CommonReturn,
108  SEGOBJK_PseudoReturn,
109  SEGOBJK_ReturnEnd,
110 
111  SEGOBJK_LoadMem,
112  SEGOBJK_StoreMem,
113  SEGOBJK_Phi,
114  SEGOBJK_Region,
115  SEGOBJK_SimpleOperand,
116  SEGOBJK_Undef,
117  SEGOBJK_CallSitePseudoInput,
118  SEGOBJK_CallSiteSummaryArgument,
119  SEGOBJK_CallSiteSummaryReturn,
120 
121  SEGOBJK_OperandEnd,
122 
123  // opcode nodes
124  SEGOBJK_OpcodeBegin,
125  SEGOBJK_BinaryWithIntConst,
126  SEGOBJK_Cast,
127  SEGOBJK_SimpleOpcode,
128  SEGOBJK_OpcodeEnd,
129 
130  SEGOBJK_NodeEnd,
131 
132  // use sites
133  SEGOBJK_SiteBegin,
134 
135  SEGOBJK_CallSite,
136  SEGOBJK_ReturnSite,
137 
138  SEGOBJK_SimpleSiteBegin,
139  SEGOBJK_GEPSite,
140  SEGOBJK_DereferenceSite,
141  SEGOBJK_DivSite,
142  SEGOBJK_CmpSite,
143  SEGOBJK_AllocSite,
144  SEGOBJK_SimpleSiteEnd,
145 
146  SEGOBJK_SiteEnd,
147  };
148 
149 private:
150  const SEGObjectKind ObjKind;
151 
153  SymbolicExprGraph *ParentGraph;
154 
156  BasicBlock *ParentBasicBlock = nullptr;
157 
158  // Index of this SEGObject
159  int ObjIndex;
160 
161  // Index of this SEG
162  int SEGIndex;
163 
165  WrappedBasicBlock *WrappedParentBasicBlock = nullptr;
166 
167 protected:
169  PersistedSEGObject *PersistedObj = nullptr;
170 
171 public:
172  SEGObject(SEGObjectKind OK, SymbolicExprGraph *SEG, BasicBlock *BB);
173 
176  SEGObject(PersistedSEGObject *Obj, SymbolicExprGraph *SEG);
177 
179  virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap) = 0;
180 
181  virtual ~SEGObject() = 0;
182 
183  // getLLVMDbgValue and getLLVMDbgInstruction are used for printing human
184  // readable info for SEGObjects This design is to eliminate the enumerating of
185  // SEG object types to print the required corresponding info for SEGObjects We
186  // try best to collect such info, For example, for callsite output nodes, if
187  // we want to distinguish the output values, we can use getLLVMDbgValue to get
188  // the value if we want to get the line number in the source code, we can use
189  // getLLVMDbgInstruction This function returns the callsite instruction
190  // containing the output node, which can be used to get the line number to
191  // find the callsite
192  //
193  // getLLVMDbgValue and getLLVMDbgInstruction are virtual functions in
194  // SEGObject. Thus, we can use them on each node in SEG, to print human
195  // readable debug info and still eliminate enumerating SEG Object types
196 
197  // Try best to collect the llvm value corresponding to the SEGObject
198  // For printing human readable Debug info relative to values
199  // SEGOperandNode : the value of the node
200  // SEGSite : the instruction
201  // Default : null
202  virtual Value *getLLVMDbgValue() const { return nullptr; }
203 
204  virtual WrappedValue *getWrappedLLVMDbgValue() const { return nullptr; }
205 
206  // Try best to collect the llvm instruction corresponding to the SEGObject
207  // For printing human readable Debug info requiring instructions
208  // In detail,
209  // For callsite pseudo-output nodes, we return the callsite
210  // For store mem node, we return the store site
211  // Otherwise, we return the instruction for the value if value exists or
212  // otherwise return null
213  virtual Instruction *getLLVMDbgInstruction() const {
214  Value *val = getLLVMDbgValue();
215  if (val != nullptr) {
216  return dyn_cast<Instruction>(val);
217  }
218 
219  return nullptr;
220  }
221 
222  virtual WrappedInstruction *getWrappedLLVMDbgInstruction() const {
223  WrappedValue *Val = getWrappedLLVMDbgValue();
224  if (Val != nullptr) {
225  return dyn_cast<WrappedInstruction>(Val);
226  }
227  return nullptr;
228  }
229 
230  SEGObjectKind getKind() const { return ObjKind; }
231 
232  int getSEGIndex() const {
233  assert(SEGIndex && "Index should not be 0");
234  return SEGIndex;
235  }
236 
237  int getObjIndex() const {
238  assert(ObjIndex && "Index should not be 0");
239  return ObjIndex;
240  }
241 
242  const char *getKindName() const;
243 
244  BasicBlock *getParentBasicBlock() const { return ParentBasicBlock; }
245 
246  WrappedBasicBlock *getWrappedParentBasicBlock() const {
247  return WrappedParentBasicBlock;
248  }
249 
250  Function *getParentFunction() const { return ParentBasicBlock->getParent(); }
251 
252  const SymbolicExprGraph *getParentGraph() const { return ParentGraph; }
253  SymbolicExprGraph *getParentGraph() { return ParentGraph; }
254 
255  friend raw_ostream &operator<<(llvm::raw_ostream &Out, const SEGObject &N);
256 
257  virtual PersistedSEGObject *createPersistedObject() const = 0;
258 
259  virtual void persistSEGData(PersistedSymbolicExprGraph *PersistedSEG);
260 
261  bool isFromLibrary() const;
262 
263  virtual std::string getSrcFile() const;
264 
265  virtual std::int32_t getSrcLine() const { return 0; }
266 
267  virtual std::string getAuxiliaryDebugStr() const;
268 };
269 
270 struct seg_cmp {
271  LLVMValueIndex *instance;
272  seg_cmp() : instance(LLVMValueIndex::get()) {}
273 
274  bool operator()(const SEGObject *A, const SEGObject *B) const {
275  int indexSEGA = A ? A->getSEGIndex() : -1;
276  int indexSEGB = B ? B->getSEGIndex() : -1;
277  if (indexSEGA != indexSEGB || (indexSEGA == -1 && indexSEGB == -1)) {
278  return indexSEGA < indexSEGB;
279  } else {
280  int indexA = A ? A->getObjIndex() : 0;
281  int indexB = B ? B->getObjIndex() : 0;
282  return indexA < indexB;
283  }
284  }
285 };
286 
288 class SEGNodeBase : public SEGObject {
289 public:
292  SEGNodeBase(PersistedSEGNodeBase *Node, SymbolicExprGraph *SEG);
293 
295  virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap);
296 
297 protected:
301  SEGNodeBase(SEGObjectKind K, Type *Ty, SymbolicExprGraph *SEG,
302  BasicBlock *BB);
303 
304  void setDescription(std::string &Desc) { Description = Desc; }
305 
306  friend class SymbolicExprGraph;
307 
308 private:
309  // This is useful for debugging
310  std::string Description;
311 
314  std::vector<SEGNodeBase *> Children;
315 
317  std::map<const SEGNodeBase *, float, seg_cmp> Parents;
318 
320  std::vector<SEGSiteBase *> UseSites;
321  std::set<SEGSiteBase *> UseSiteSet;
322 
324  Type *LLVMType = nullptr;
325 
327  SEGRegionNode *Region;
328 
329  // for persistence usage
330  SEGType *SEGTy = nullptr;
331 
332 public:
333  virtual ~SEGNodeBase() {}
334 
336  Type *getLLVMType() const {
337  if (LLVMType) {
338  return LLVMType;
339  } else {
340  if (SEGTy) {
341  return SEGTy->getRealType();
342  }
343  }
344  return nullptr;
345  }
346 
348  uint64_t getTypeSize() const {
349  assert(SEGTy && "SEGTy is nullptr");
350  return SEGTy->getTypeSize();
351  }
352 
354  bool isVectorTy() const { return SEGTy->isVectorTy(); }
355 
356  bool isPointerTy() const { return SEGTy->isPointerTy(); }
357 
358  bool isSized() const { return SEGTy->isSized(); }
359 
360  bool isStructTy() const { return SEGTy->isStructTy(); }
361 
362  SEGType *getSEGType() const { return SEGTy; }
363 
365  unsigned getVectorNumElements() const {
366  return SEGTy->getVectorNumElements();
367  }
368 
369  SEGNodeBase *getChild(unsigned I) const {
370  assert(Children.size() > I &&
371  "Invalid child index when querying SEG edges");
372  return Children[I];
373  }
374 
375  float getConfidence(const SEGNodeBase *ParentNode) const {
376  auto It = Parents.find(ParentNode);
377  assert(It != Parents.end() &&
378  "Invalid parent node when querying SEG edges");
379  return It->second;
380  }
381 
382  unsigned getNumChildren() const { return Children.size(); }
383 
384  unsigned getNumParents() const { return Parents.size(); }
385 
386  void addChild(SEGNodeBase *N, float Confidence = 1.0f) {
387  Children.push_back(N);
388  N->Parents.insert(std::make_pair(this, Confidence));
389  }
390 
391  void eraseAllChildren() {
392  for (auto *Child : Children) {
393  Child->Parents.erase(this);
394  }
395  Children.clear();
396  }
397 
398  void addUseSite(SEGSiteBase *U) {
399  if (!UseSiteSet.count(U)) {
400  UseSiteSet.insert(U);
401  UseSites.push_back(U);
402  }
403  }
404 
405  virtual bool isTerminalNode() const { return Children.empty(); }
406 
407  SEGRegionNode *getRegion() const { return Region; }
408 
409  bool containsParentNode(const SEGNodeBase *N) const {
410  return Parents.count(N);
411  }
412 
413  const std::string &getDescription() const { return Description; }
414 
416  virtual void dot(raw_fd_ostream &O) const = 0;
417 
418  friend raw_ostream &operator<<(llvm::raw_ostream &Out, const SEGNodeBase &N);
419 
420  /*==-------Iterators------==*/
422  private:
423  const SEGNodeBase *Node;
424  key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
425 
426  public:
427  ValueFlowIterator(const SEGNodeBase *N, bool End) : Node(N) {
428  if (End) {
429  It = N->parent_end();
430  } else {
431  It = N->parent_begin();
432  increment();
433  }
434  }
435 
437  : Node(VFIt.Node), It(VFIt.It) {}
438 
439  ValueFlowIterator &operator=(const ValueFlowIterator &VFIt) {
440  if (this != &VFIt) {
441  this->Node = VFIt.Node;
442  this->It = VFIt.It;
443  }
444  return *this;
445  }
446 
447  ValueFlowIterator operator++(int) {
448  ValueFlowIterator Old(*this);
449  ++(*this);
450  return Old;
451  }
452 
453  ValueFlowIterator &operator++() {
454  It++;
455  increment();
456  return *this;
457  }
458 
459  const SEGNodeBase *operator*() { return *It; }
460 
461  bool operator==(const ValueFlowIterator &VFIt) { return It == VFIt.It; }
462 
463  bool operator!=(const ValueFlowIterator &VFIt) { return It != VFIt.It; }
464 
465  private:
466  void increment();
467  };
468 
469  ValueFlowIterator vflow_begin() const { return {this, false}; }
470 
471  ValueFlowIterator vflow_end() const { return {this, true}; }
472 
473  key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
474  parent_begin() const {
475  return {Parents.begin()};
476  }
477 
478  key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
479  parent_end() const {
480  return {Parents.end()};
481  }
482 
483  iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
484  parents() const {
485  return {Parents.begin(), Parents.end()};
486  }
487 
488  std::vector<SEGNodeBase *>::const_iterator child_begin() const {
489  return Children.begin();
490  }
491 
492  std::vector<SEGNodeBase *>::const_iterator child_end() const {
493  return Children.end();
494  }
495 
496  iterator_range<std::vector<SEGNodeBase *>::const_iterator> children() const {
497  return {Children.begin(), Children.end()};
498  }
499 
500  std::map<const SEGNodeBase *, float>::const_iterator
501  parent_confidence_begin() const {
502  return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
503  Parents.begin());
504  }
505 
506  std::map<const SEGNodeBase *, float>::const_iterator
507  parent_confidence_end() const {
508  return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
509  Parents.end());
510  }
511 
512  size_t child_size() const { return Children.size(); }
513 
514  size_t parent_size() const { return Parents.size(); }
515 
516  std::vector<SEGSiteBase *>::const_iterator use_site_begin() const {
517  return UseSites.begin();
518  }
519 
520  std::vector<SEGSiteBase *>::const_iterator use_site_end() const {
521  return UseSites.end();
522  }
523 
524  iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
525  return {UseSites.begin(), UseSites.end()};
526  };
527 
528  size_t use_site_size() const { return UseSites.size(); }
529 
530 public:
531  static bool classof(const SEGObject *N) {
532  return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
533  }
534 };
535 
539 class SEGOperandNode : public SEGNodeBase {
540 public:
543  SEGOperandNode(PersistedSEGOperandNode *Node, SymbolicExprGraph *SEG);
544 
545  virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap) {
546  SEGNodeBase::assembleSEGObject(FuncSEGObjMap);
547  }
548 
549 protected:
552  Value *LLVMValue = nullptr;
553 
554  SEGValue *segValue = nullptr;
555 
556  WrappedValue *WrappedLLVMValue = nullptr;
557 
559  SEGOperandNode(SEGObjectKind K, Type *Ty, SymbolicExprGraph *SEG,
560  BasicBlock *BB);
561 
573  SEGOperandNode(SEGObjectKind K, Value *Val, Type *Ty, SymbolicExprGraph *SEG,
574  BasicBlock *BB);
575 
577  friend class SymbolicExprGraph;
578 
579 public:
580  virtual ~SEGOperandNode() = 0;
581 
582  Value *getLLVMValue() const { return LLVMValue; }
583 
584  SEGValue *getSEGValue() const { return segValue; }
585 
586  WrappedValue *getWrappedLLVMValue() const { return WrappedLLVMValue; }
587 
588  void dot(raw_fd_ostream &O) const override;
589 
590  friend raw_ostream &operator<<(llvm::raw_ostream &Out,
591  const SEGOperandNode &N) {
592  if (Value *Val = N.getLLVMValue()) {
593  Out << *Val;
594  } else {
595  Out << N.getDescription();
596  }
597  return Out;
598  }
599 
600  virtual Value *getLLVMDbgValue() const override { return getLLVMValue(); }
601 
602  virtual std::int32_t getSrcLine() const {
603  auto *Val = getWrappedLLVMValue();
604  if (Val) {
605  return Val->getSrcLine();
606  }
607  return SEGNodeBase::getSrcLine();
608  }
609 
610 public:
611  static bool classof(const SEGObject *N) {
612  return N->getKind() >= SEGOBJK_OperandBegin &&
613  N->getKind() <= SEGOBJK_OperandEnd;
614  }
615 
616 private:
617  void initialize(Value *Val);
618 
619  void initializeFromWrappedValue(WrappedValue *WV);
620 };
621 
624 class SEGOpcodeNode : public SEGNodeBase {
625 public:
628  SEGOpcodeNode(PersistedSEGOpcodeNode *Node, SymbolicExprGraph *SEG);
629 
630  virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap) {
631  SEGNodeBase::assembleSEGObject(FuncSEGObjMap);
632  }
633 
634 public:
635  enum CodeKind {
636  CK_BinaryBegin,
637  CK_URem = CK_BinaryBegin,
638  CK_FRem,
639  CK_SRem,
640  CK_UDiv,
641  CK_FDiv,
642  CK_SDiv,
643  CK_And,
644  CK_Or,
645  CK_Xor,
646  CK_Add,
647  CK_FAdd,
648  CK_Sub,
649  CK_FSub,
650  CK_Mul,
651  CK_FMul,
652  CK_Shl,
653  CK_LShr,
654  CK_AShr,
655  CK_BinaryEnd = CK_AShr,
656 
657  CK_CastBegin,
658  CK_AddressCast = CK_CastBegin,
659  CK_Int2Ptr,
660  CK_Ptr2Int,
661  CK_Bitcast,
662  CK_Trunc,
663  CK_FPTrunc,
664  CK_SExt,
665  CK_ZExt,
666  CK_FPExt,
667  CK_SI2FP,
668  CK_FP2SI,
669  CK_UI2FP,
670  CK_FP2UI,
671  CK_CastEnd = CK_FP2UI,
672 
673  CK_ExtractElmt,
674  CK_InsertElmt,
675 
676  CK_Select,
677 
678  CK_GetElmtPtr,
679 
680  CK_Concat,
681 
682  CK_CmpBegin,
683  // Predicates for comparing floating numbers
684  // U L G E Intuitive operation
685  CK_FFalse = CK_CmpBegin,
701 
702  // Predicates for comparing integers
713  CK_CmpEnd = CK_ISLE,
714 
715  CK_InvalidCode,
716  };
717 
718 protected:
719  CodeKind Opcode;
720 
722  SEGOpcodeNode(SEGObjectKind K, CodeKind Opcode, Type *Ty,
723  SymbolicExprGraph *SEG, BasicBlock *BB);
724 
726  friend class SymbolicExprGraph;
727 
728 public:
729  virtual ~SEGOpcodeNode() = 0;
730 
731  CodeKind getOpcode() const { return Opcode; }
732 
733  virtual void dot(raw_fd_ostream &O) const;
734 
735  bool isCmpNode() const {
736  return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
737  }
738 
739  bool isSignedCmp() const { return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
740 
741  bool isUnSignedCmp() const { return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
742 
743  bool isFloatCmp() const { return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
744 
745  bool isAddNode() const { return Opcode == CK_Add; }
746 
747  bool isSubNode() const { return Opcode == CK_Sub; }
748 
749  bool isGEPNode() const { return Opcode == CK_GetElmtPtr; }
750 
751  bool isSelectNode() const { return Opcode == CK_Select; }
752 
753  bool isCastNode() const {
754  return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
755  }
756 
757  bool isBinaryNode() const {
758  return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
759  }
760 
761  bool isExtractElmtNode() const { return Opcode == CK_ExtractElmt; }
762 
763  bool isInsertElmtNode() const { return Opcode == CK_InsertElmt; }
764 
765  bool isConcatNode() const { return Opcode == CK_Concat; }
766 
767 public:
768  static bool classof(const SEGObject *N) {
769  return N->getKind() >= SEGOBJK_OpcodeBegin &&
770  N->getKind() <= SEGOBJK_OpcodeEnd;
771  }
772 
773  static const char *getOpcodeName(CodeKind CK);
774 };
775 
776 class SEGSiteBase : public SEGObject {
777 public:
780  SEGSiteBase(PersistedSEGSiteBase *Site, SymbolicExprGraph *SEG);
781 
783  virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap);
784 
785 private:
786  Instruction *User = nullptr;
787 
788  WrappedInstruction *WrappedUser = nullptr;
789 
790  SEGValue *segValue = nullptr;
791 
792 protected:
793  SEGSiteBase(SEGObjectKind K, Instruction *User, SymbolicExprGraph *G);
794  friend class SymbolicExprGraph;
795 
796 public:
797  virtual ~SEGSiteBase() = 0;
798 
799  CallSite getLLVMCallSite() const { return CallSite(User); }
800 
801  WrappedCallSite getWrappedLLVMCallSite() const {
802  return WrappedCallSite(WrappedUser);
803  }
804 
805  Instruction *getInstruction() const { return User; }
806 
807  WrappedInstruction *getWrappedInstruction() const { return WrappedUser; }
808 
809  SEGValue *getSEGValue() const { return segValue; }
810 
811  virtual Value *getLLVMDbgValue() const override { return getInstruction(); }
812 
813  virtual WrappedValue *getWrappedLLVMDbgValue() const override {
814  return getWrappedInstruction();
815  }
816 
817  friend raw_ostream &operator<<(llvm::raw_ostream &Out,
818  const SEGSiteBase &US) {
819  Out << *US.User;
820  return Out;
821  }
822 
823  virtual std::string getSrcFile() const {
824  if (WrappedUser) {
825  return WrappedUser->getSrcFileName();
826  } else {
827  return "NA";
828  }
829  }
830 
831  virtual std::int32_t getSrcLine() const {
832  if (WrappedUser) {
833  return WrappedUser->getSrcLine();
834  } else {
835  return 0;
836  }
837  }
838 
839 public:
840  static bool classof(const SEGObject *O) {
841  return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
842  }
843 };
844 
845 namespace FalconPlus {
846 class AbstractCond;
847 class RegionCond;
848 class FreeCond;
849 class BitCondVec;
850 class IntraFalcon;
851 class AbstractCondPtr;
852 class FalconAA;
853 } // namespace FalconPlus
854 
856 
857  friend class SEGRegionNode;
858  friend class SymbolicExprGraphBuilder;
859  friend class IntraFalcon;
860  friend class MantaIntraFalcon;
861  friend class PTGraph;
862  friend class SEGObject;
863  friend class OCValueFlowBuilder;
864 
865  friend class FalconPlus::AbstractCond;
866  friend class FalconPlus::RegionCond;
867  friend class FalconPlus::FreeCond;
868  friend class FalconPlus::BitCondVec;
869  friend class FalconPlus::IntraFalcon;
870  friend class FalconPlus::AbstractCondPtr;
871  friend class FalconPlus::FalconAA;
872 
873 public:
874  struct CDGCond {
875  SEGNodeBase *CondNode;
876  WrappedBasicBlock *BB;
877  bool Cond;
878 
879  public:
880  CDGCond(SEGNodeBase *CN, BasicBlock *B, bool C)
881  : CondNode(CN), BB(WrappedValue::findWrappedBasicBlock(B)), Cond(C) {}
882 
883  CDGCond(SEGNodeBase *CN, WrappedBasicBlock *B, bool C)
884  : CondNode(CN), BB(B), Cond(C) {}
885 
886  bool operator<(const CDGCond &RHS) const {
887  return (CondNode < RHS.CondNode) ||
888  (CondNode == RHS.CondNode && BB < RHS.BB) ||
889  (CondNode == RHS.CondNode && BB == RHS.BB && Cond < RHS.Cond);
890  }
891 
892  bool operator==(const CDGCond &RHS) const {
893  return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
894  }
895 
896  BasicBlock *getBB() const { return BB->getRealBlock(); }
897  };
898 
899 private:
900  // The base function for this SEG
901  Function *BaseFunc = nullptr;
902 
903  // TODO: Can not Recover this maps from persistence for libraries. Need to use
904  // wrapped value in the future.
905  // TODO: This will invovle so many mondules and need to be confirmed.
906 
908  std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
909 
913  std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
914 
917  std::set<SEGNodeBase *, seg_cmp> NonValueNodes;
918 
920  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>
921  StoreMemNodesMap;
922 
924  std::map<Instruction *, SEGSiteBase *> InstSiteMap;
925  std::vector<SEGCallSite *> CallSites;
926 
934  std::map<WrappedBasicBlock *, std::set<CDGCond> *, CmpPointerOfValue>
935  BlockCondMap;
936 
938  std::map<std::string, SEGPseudoArgumentNode *> PseudoArgNameToNode;
939  std::unordered_map<std::string, SEGOperandNode *> PseudoArgNameToOperandNode;
940  std::unordered_map<std::string, std::unique_ptr<FalconPlus::PseudoVal>>
941  PseudoValStorage;
942 
943  int SEGIndex = 1;
944 
945  int SEGObjIndexIter = 1;
946 
947 private:
948  /*==--------------------Structures for Inter-procedural
949  * Analysis--------------------==*/
950  SEGCommonReturnNode *CommonReturn = nullptr;
951  kvec<SEGPseudoReturnNode *> PseudoReturns;
952 
953  kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
954  kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
955  kvec<SEGVarArgumentNode *> VarArgumentNodes;
956 
957  // Summary Nodes
958  // SEGNodeBase : the node
959  // int : the corresponding ap-depth (0 means ap-depth larger than considered)
960  //
961  // For each ap-depth, there is only one return summary node with a load mem
962  // node as child,
963  // which collects all values with conditions and confidence score, that
964  // may escape to caller with the corresponding ap-depth
965  // For each ap-depth, there can be multiple arg-summary node,
966  // each has a parent to the argument node that is not inlined
967  // Each summary node has type PTGraph::DEFAULT_NON_POINTER_TYPE
968  // which is currently int64 type
969  std::unordered_map<SEGNodeBase *, int> SummaryArgNodes;
970  std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
971  SummaryArgNodesCache;
972  std::unordered_map<SEGNodeBase *, int> SummaryReturnNodes;
973  std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
974  SummaryReturnNodesCache;
975 
976  void addCommonArgumentNodes(SEGCommonArgumentNode *Node);
977 
978  void addPseudoArgumentNodes(SEGPseudoArgumentNode *Node);
979 
980  void addVarArgumentNodes(SEGVarArgumentNode *Node);
981 
982  void setCommonReturnNode(SEGCommonReturnNode *Node);
983 
984  void addPseudoReturnNode(SEGPseudoReturnNode *Node);
985 
986  void addSummaryArgNode(SEGNodeBase *Node, int APDepth);
987 
988  void addSummaryReturnNode(SEGNodeBase *Node, int APDepth);
989 
990 public:
993  SEGObject *findSEGObject(int SEGObjID);
994 
995  size_t getNumCommonArgument() const { return CommonArgumentNodes.size(); }
996 
997  size_t getNumPseudoArgument() const { return PseudoArgumentNodes.size(); }
998 
999  size_t getNumVarArgument() const { return VarArgumentNodes.size(); }
1000 
1001  size_t getNumPseudoReturn() const { return PseudoReturns.size(); }
1002 
1003  bool hasCommonReturnNode() const {
1004  if (CommonReturn)
1005  return true;
1006  else
1007  return false;
1008  }
1009 
1010  const SEGCommonReturnNode *getCommonReturn() const { return CommonReturn; }
1011 
1012  const SEGPseudoReturnNode *getPseudoReturn(size_t Index) const {
1013  return PseudoReturns[Index];
1014  }
1015 
1016  const SEGCommonArgumentNode *getCommonArgument(size_t Index) const {
1017  return CommonArgumentNodes[Index];
1018  }
1019 
1020  const SEGPseudoArgumentNode *getPseudoArgument(size_t Index) const {
1021  return PseudoArgumentNodes[Index];
1022  }
1023 
1024  const SEGVarArgumentNode *getVarArgument(size_t Index) const {
1025  return VarArgumentNodes[Index];
1026  }
1027 
1028  // void setSEGIndex(int SEGIndex) { this->SEGIndex = SEGIndex; }
1029 
1030  int getSEGIndex() { return SEGIndex; }
1031 
1032  bool isSummaryArgument(const SEGNodeBase *Node) const;
1033 
1034  // Return the ap-depth of an SEGNodeBase as summary argument.
1035  // If the node is not a summary argument, return -1.
1036  int getSummaryArgumentAPDepth(const SEGNodeBase *Node) const;
1037 
1038  // Get the set of summary argument nodes given APDepth
1039  // Return null if not exist
1040  std::unordered_set<SEGNodeBase *> *getSummaryArgument(int APDepth) const;
1041 
1042  bool isSummaryReturn(const SEGNodeBase *Node) const;
1043 
1044  // Return the ap-depth of an SEGNodeBase as summary return node.
1045  // If the node is not a summary return node, return -1.
1046  int getSummaryReturnAPDepth(const SEGNodeBase *Node) const;
1047 
1048  // Get the set of summary return nodes given APDepth
1049  // Return null if not exist
1050  std::unordered_set<SEGNodeBase *> *getSummaryReturn(int APDepth) const;
1051 
1052  // Return if the value represented by the Node is directly passed to/from
1053  // caller A node is directly passed to/from caller if either it is a common or
1054  // pseudo return/argument node or a summary return/argument node. A node is
1055  // indirectly passed to/from caller if one of it's ancestor/descendant is
1056  // directly passed to/from caller
1057  bool isDirectlyPassedToCaller(const SEGNodeBase *Node) const;
1058  bool isDirectlyPassedFromCaller(const SEGNodeBase *Node) const;
1059 
1060 private:
1061  // Cache of region nodes to avoid multiple creation of same regions
1062  // Positive regions: Value of SEGNodeBase is true
1063  // Negative regions: Value of SEGNodeBase is false
1064  // compond_regions_cache_and: SEGRegionNode(3) is SEGRegionNode(1) and
1065  // SEGRegionNode(2) compond_regions_cache_or: SEGRegionNode(3) is
1066  // SEGRegionNode(1) or SEGRegionNode(2) Note, for compound regions, we assume
1067  // (pointer) value SEGRegionNode*(1) < SEGRegionNode*(2)
1068  std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
1069  std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
1070  std::unordered_map<SEGRegionNode *,
1071  std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
1072  compound_regions_cache_and;
1073  std::unordered_map<SEGRegionNode *,
1074  std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
1075  compound_regions_cache_or;
1076 
1077  // cache the corresponding region nodes for basic blocks
1078  std::unordered_map<WrappedBasicBlock *, SEGRegionNode *> bb_region_cache;
1079 
1080 private:
1081  // All the functions that may change the SEG (i.e. have side-effects on the
1082  // SEG) are private) Meaning that the SEG cannot be changed once created. Only
1083  // friend class of SEG can modify the SEG, which is used to protect the SEG
1084  // from modified by checkers
1085 
1096  SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
1097 
1100  template <class OperandNodeTy>
1101  OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB) {
1102  assert(Ty && BB);
1103  assert(Val && !Val->getType()->isVoidTy());
1104  assert((!(dyn_cast<Instruction>(Val)) ||
1105  BB == ((Instruction *)Val)->getParent()) &&
1106  "Incorrect BasicBlock detected");
1107 
1108  auto It = ValueNodesMap.find(Val);
1109  if (It != ValueNodesMap.end()) {
1110  assert(isa<OperandNodeTy>(It->second));
1111  return (OperandNodeTy *)It->second;
1112  } else {
1113  OperandNodeTy *N = new OperandNodeTy(Val, Ty, this, BB);
1114  ValueNodePairs.push_back({Val, N});
1115  ValueNodesMap[Val] = N;
1116  return N;
1117  }
1118  }
1119 
1122  findOrCreatePseudoArgumentNode(const FalconPlus::PseudoVal *Arg,
1123  BasicBlock *BB);
1124  // Call this after all pseudo args have been created.
1125  void finalizePseudoArgumentNodes();
1126  SEGOperandNode *
1127  findOrCreateSimpleOperandFromPseudoVal(const FalconPlus::PseudoVal *Arg,
1128  BasicBlock *BB);
1129  SEGPseudoReturnNode *createPseudoReturnNode(const FalconPlus::PseudoVal *Arg,
1130  BasicBlock *BB);
1132  createPseudoInputNode(const FalconPlus::PseudoVal *Arg, BasicBlock *BB,
1133  CallSite CS, Function *Callee);
1135  createPseudoOutputNode(const FalconPlus::PseudoVal *Arg, BasicBlock *BB,
1136  CallInst *Call, Function *Callee);
1137 
1138  template <class OperandNodeTy>
1139  OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB) {
1140  assert(Ty && BB);
1141  assert(Val && !Val->getType()->isVoidTy());
1142  assert((!(dyn_cast<Instruction>(Val)) ||
1143  BB == ((Instruction *)Val)->getParent()) &&
1144  "Incorrect BasicBlock detected");
1145 
1146  OperandNodeTy *N = new OperandNodeTy(Val, Ty, this, BB);
1147  ValueNodesMap[Val] = N;
1148  ValueNodePairs.push_back({Val, N});
1149  return N;
1150  }
1151 
1152  template <class OperandNodeTy>
1153  OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB) {
1154  assert(Ty && BB);
1155  OperandNodeTy *Ret = new OperandNodeTy(Ty, this, BB);
1156  NonValueNodes.insert(Ret);
1157  return Ret;
1158  }
1159 
1162  template <class SiteTy> SiteTy *findOrCreateSite(Instruction *I) {
1163  assert(I);
1164 
1165  auto It = InstSiteMap.find(I);
1166  if (It != InstSiteMap.end()) {
1167  assert(isa<SiteTy>(It->second));
1168  return (SiteTy *)It->second;
1169  } else {
1170  SiteTy *N = new SiteTy(I, this);
1171  InstSiteMap[I] = N;
1172 
1173  if (SEGCallSite *CS = dyn_cast<SEGCallSite>(N)) {
1174  CallSites.push_back(CS);
1175  }
1176 
1177  return N;
1178  }
1179  }
1180 
1181  // Create callSite argument summary node as operandNode(Type* Ty,
1182  // SymbolicExprGraph* SEG, BasicBlock* BB) for call site Callsite with
1183  // ap-depth APDepth
1185  createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1186  Instruction *Callsite, int APDepth);
1187 
1188  // Create callSite return summary node as operandNode(Type* Ty,
1189  // SymbolicExprGraph* SEG, BasicBlock* BB) for call site Callsite, with value
1190  // confidence Confidence
1192  createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1193  Instruction *Callsite, float Confidence);
1194 
1195  // find or create a call site output node
1197  findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1198  CallSite CS, Function *Callee, bool IsCommon);
1199 
1200  // find or create a call site pseudo input node
1202  findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1203  CallSite CS, Function *Callee);
1204 
1206  SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1207  Value *StoreVal, BasicBlock *BB);
1208 
1209  // Find or create a Region node from a region unit (with boolean value
1210  // cond_node == cond)
1211  SEGRegionNode *findOrCreateUnitRegion(SEGNodeBase *cond_node, bool cond);
1212 
1213  // Find or create a Region node "region1 and region2"
1214  SEGRegionNode *findOrCreateAndRegion(SEGRegionNode *region1,
1215  SEGRegionNode *region2);
1216 
1217  // Find or create a Region node "region1 or region2"
1218  SEGRegionNode *findOrCreateOrRegion(SEGRegionNode *region1,
1219  SEGRegionNode *region2);
1220 
1221  // Find or create a Region node "not region1"
1222  SEGRegionNode *findOrCreateNotRegion(SEGRegionNode *region1);
1223 
1224  // Find or create a node representing a constant bool value : Constant True or
1225  // Constant False
1226  SEGOperandNode *findOrCreateConstantBoolNode(bool bool_val);
1227 
1231  SEGOpcodeNode *createExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1232  BasicBlock *BB, SEGNodeBase *FirstOperand, ...);
1233 
1237  SEGOpcodeNode *createExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1238  BasicBlock *BB, const kvec<SEGNodeBase *> &);
1239 
1241  SEGOpcodeNode *createCastExpr(SEGOpcodeNode::CodeKind Opcode, Type *Ty,
1242  BasicBlock *BB, SEGNodeBase *Op, uint64_t OSz,
1243  uint64_t);
1244 
1246  SEGOpcodeNode *createBinaryWithIntConstExpr(SEGOpcodeNode::CodeKind Opcode,
1247  Type *Ty, BasicBlock *BB,
1248  SEGNodeBase *Op, uint64_t);
1249 
1251  void addBlockCond(BasicBlock *CurrBB, SEGNodeBase *BrNode, BasicBlock *DepBB,
1252  bool Label);
1253 
1254 public:
1255  SymbolicExprGraph(Function *);
1256  ~SymbolicExprGraph();
1257 
1258  Function *getBaseFunc() const { return BaseFunc; }
1259 
1262  template <class SiteTy> SiteTy *findSite(Instruction *I) const {
1263  assert(I);
1264 
1265  auto It = InstSiteMap.find(I);
1266  if (It != InstSiteMap.end()) {
1267  // assert(isa<SiteTy>(It->second));
1268  return dyn_cast<SiteTy>(It->second);
1269  } else {
1270  return nullptr;
1271  }
1272  }
1273 
1280  template <class SiteTy> SiteTy *findSite(SEGValue *sValue) const {
1281  Instruction *I = dyn_cast<Instruction>(sValue->getValue());
1282  assert(I);
1283 
1284  auto It = InstSiteMap.find(I);
1285  if (It != InstSiteMap.end()) {
1286  // assert(isa<SiteTy>(It->second));
1287  return dyn_cast<SiteTy>(It->second);
1288  } else {
1289  return nullptr;
1290  }
1291  }
1292 
1295  SEGOperandNode *findNode(Value *) const;
1296 
1297  SEGOperandNode *findNode(SEGValue *) const;
1298 
1299  // Find the Region node from a region unit (with boolean value cond_node ==
1300  // cond)
1302  SEGRegionNode *findUnitRegion(SEGNodeBase *cond_node, bool cond) const;
1303 
1304  // Find the Region node "region1 and region2"
1306  SEGRegionNode *findAndRegion(SEGRegionNode *region1,
1307  SEGRegionNode *region2) const;
1308 
1309  // Find the Region node "region1 or region2"
1311  SEGRegionNode *findOrRegion(SEGRegionNode *region1,
1312  SEGRegionNode *region2) const;
1313 
1314  // Find the Region node "not region1"
1316  SEGRegionNode *findNotRegion(SEGRegionNode *region1) const;
1317 
1321  const std::set<CDGCond> *getBlockCond(WrappedBasicBlock *BB) const {
1322  auto It = BlockCondMap.find(BB);
1323  if (It != BlockCondMap.end()) {
1324  return It->second;
1325  }
1326  return nullptr;
1327  }
1328 
1329  const std::set<CDGCond> *getBlockCond(BasicBlock *BB) const {
1330  auto *WBB = WrappedValue::findWrappedBasicBlock(BB);
1331  auto It = BlockCondMap.find(WBB);
1332  if (It != BlockCondMap.end()) {
1333  return It->second;
1334  }
1335  return nullptr;
1336  }
1337 
1339  void dot(const char *FileName) const;
1340 
1342  void dot(std::vector<const SEGNodeBase *> Srcs, const char *FileName) const;
1343 
1345  void validate();
1346 
1347  // Return the region node for the corresponding basicblock, if not computed,
1348  // we compute and generate a new region
1349  SEGRegionNode *findOrCreateRegionForBB(BasicBlock *BB);
1350 
1351  SEGRegionNode *findOrCreateRegionForBB(WrappedBasicBlock *BB);
1352 
1353  // Find the region for BB. If the region is not computed, we return null
1354  SEGRegionNode *findRegionForBB(BasicBlock *BB) const;
1355 
1356  SEGRegionNode *findRegionForBB(WrappedBasicBlock *BB) const;
1357 
1358  /*==------------------------Iterators--------------------==*/
1359 
1360  std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1361  value_node_begin() const {
1362  return ValueNodesMap.begin();
1363  }
1364 
1365  std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1366  value_node_end() const {
1367  return ValueNodesMap.end();
1368  }
1369 
1370  std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1371  value_node_pair_begin() const {
1372  return ValueNodePairs.begin();
1373  }
1374 
1375  std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1376  value_node_pair_end() const {
1377  return ValueNodePairs.end();
1378  }
1379 
1380  std::set<SEGNodeBase *>::const_iterator non_value_node_begin() const {
1381  return NonValueNodes.begin();
1382  }
1383 
1384  std::set<SEGNodeBase *>::const_iterator non_value_node_end() const {
1385  return NonValueNodes.end();
1386  }
1387 
1388  std::map<Instruction *, SEGSiteBase *>::const_iterator
1389  inst_site_begin() const {
1390  return InstSiteMap.begin();
1391  }
1392 
1393  std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end() const {
1394  return InstSiteMap.end();
1395  }
1396 
1397  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>::const_iterator
1398  store_mem_node_begin() const {
1399  return StoreMemNodesMap.begin();
1400  }
1401 
1402  std::map<std::pair<Instruction *, Value *>, SEGStoreMemNode *>::const_iterator
1403  store_mem_node_end() const {
1404  return StoreMemNodesMap.end();
1405  }
1406 
1407  std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin() const {
1408  return InstSiteMap.begin();
1409  }
1410 
1411  std::map<Instruction *, SEGSiteBase *>::const_iterator site_end() const {
1412  return InstSiteMap.end();
1413  }
1414 
1416  private:
1417  size_t I;
1418  SEGCommonReturnNode *CommonRet;
1419  const kvec<SEGPseudoReturnNode *> &PseudoRets;
1420 
1421  public:
1422  ReturnIterator(size_t Id, SEGCommonReturnNode *CR,
1423  const kvec<SEGPseudoReturnNode *> &PRs)
1424  : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1425 
1426  ReturnIterator(const ReturnIterator &It)
1427  : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1428 
1429  ReturnIterator &operator++() {
1430  I++;
1431  return *this;
1432  }
1433 
1434  ReturnIterator operator++(int) {
1435  ReturnIterator Old(*this);
1436  ++(*this);
1437  return Old;
1438  }
1439 
1440  const SEGReturnNode *operator*() {
1441  if (CommonRet) {
1442  if (I == 0) {
1443  return (const SEGReturnNode *)CommonRet;
1444  } else {
1445  return (const SEGReturnNode *)PseudoRets[I - 1];
1446  }
1447  } else {
1448  return (const SEGReturnNode *)PseudoRets[I];
1449  }
1450  }
1451 
1452  bool operator==(const ReturnIterator &It) { return I == It.I; }
1453 
1454  bool operator!=(const ReturnIterator &It) { return I != It.I; }
1455  };
1456 
1457  ReturnIterator return_begin() const {
1458  return ReturnIterator(0, CommonReturn, PseudoReturns);
1459  }
1460 
1461  ReturnIterator return_end() const {
1462  return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1463  CommonReturn, PseudoReturns);
1464  }
1465 
1466  ReturnIterator pseudo_return_begin() const {
1467  size_t StartIndex = getCommonReturn() ? 1 : 0;
1468  return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1469  }
1470 
1471  ReturnIterator pseudo_return_end() const { return return_end(); }
1472 
1474  private:
1475  size_t I;
1476  const kvec<SEGCommonArgumentNode *> &CommonArgs;
1477  const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1478  const kvec<SEGVarArgumentNode *> &VarArgs;
1479 
1480  public:
1481  ArgumentIterator(size_t Id, const kvec<SEGCommonArgumentNode *> &CA,
1482  const kvec<SEGPseudoArgumentNode *> &PA,
1483  const kvec<SEGVarArgumentNode *> &VA)
1484  : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1485 
1487  : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1488  VarArgs(It.VarArgs) {}
1489 
1490  ArgumentIterator &operator++() {
1491  I++;
1492  return *this;
1493  }
1494 
1495  ArgumentIterator operator++(int) {
1496  ArgumentIterator Old(*this);
1497  ++(*this);
1498  return Old;
1499  }
1500 
1501  const SEGArgumentNode *operator*() {
1502  if (I < (size_t)CommonArgs.size()) {
1503  return (const SEGArgumentNode *)CommonArgs[I];
1504  }
1505 
1506  if (I < (size_t)(CommonArgs.size() + PseudoArgs.size())) {
1507  return (const SEGArgumentNode *)PseudoArgs[I - CommonArgs.size()];
1508  }
1509 
1510  assert(I <
1511  (size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1512  return (const SEGArgumentNode *)
1513  VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1514  }
1515 
1516  bool operator==(const ArgumentIterator &It) { return I == It.I; }
1517 
1518  bool operator!=(const ArgumentIterator &It) { return I != It.I; }
1519  };
1520 
1521  ArgumentIterator arg_begin() const {
1522  return ArgumentIterator(0, CommonArgumentNodes, PseudoArgumentNodes,
1523  VarArgumentNodes);
1524  }
1525 
1526  ArgumentIterator arg_end() const {
1527  size_t NumArgs =
1528  getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1529  return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1530  VarArgumentNodes);
1531  }
1532 
1533  ArgumentIterator common_arg_begin() const { return arg_begin(); }
1534 
1535  ArgumentIterator common_arg_end() const {
1536  size_t NumArgs = getNumCommonArgument();
1537  return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1538  VarArgumentNodes);
1539  }
1540 
1541  ArgumentIterator pseudo_arg_begin() const { return common_arg_end(); }
1542 
1543  ArgumentIterator pseudo_arg_end() const {
1544  size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1545  return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1546  VarArgumentNodes);
1547  }
1548 
1549  ArgumentIterator var_arg_begin() const { return pseudo_arg_end(); }
1550 
1551  ArgumentIterator var_arg_end() const { return arg_end(); }
1552 
1553  typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1554  SEGCallSiteIterator seg_callsite_begin() const { return CallSites.begin(); }
1555 
1556  SEGCallSiteIterator seg_callsite_end() const { return CallSites.end(); }
1557 
1558  /*==------------------------For persistence usage--------------------==*/
1559 private:
1561  WrappedFunction *WrappedBasefunc = nullptr;
1562  WrappedModule *WrappedMod = nullptr;
1563  std::map<int, SEGObject *> SEGObjectMap;
1564  std::map<const SEGObject *, int> ReverseSEGObjectMap;
1565 
1566  template <class IndexedNode> void SortByIndex(kvec<IndexedNode *> &Nodes) {
1567  if (Nodes.size() == 0) {
1568  return;
1569  }
1570 
1571  kvec<IndexedNode *> OrderedNodes;
1572  OrderedNodes.push_empty(Nodes.size());
1573 
1574  for (auto *Node : Nodes) {
1575  OrderedNodes[Node->getIndex()] = Node;
1576  }
1577  Nodes.clear();
1578  Nodes.push_back(OrderedNodes);
1579  }
1580 
1581 public:
1582  explicit SymbolicExprGraph(PersistedSymbolicExprGraph *PersistedSEG);
1583 
1584  bool compareLoadedSEG(const SymbolicExprGraph *LoadedSEG) const;
1585 
1586  bool comparePersistedSEG(PersistedSymbolicExprGraph *PersistedSEG);
1587 
1588  const WrappedModule *getWrappedMod() const { return WrappedMod; }
1589 
1590  WrappedFunction *getWrappedBaseFunc() const { return WrappedBasefunc; }
1591 
1592  int getSEGObjectID(const SEGObject *SEGObj) const {
1593  if (ReverseSEGObjectMap.find(SEGObj) != ReverseSEGObjectMap.end()) {
1594  return ReverseSEGObjectMap.at(SEGObj);
1595  }
1596  return 0;
1597  }
1598 };
1599 
1600 #endif
SEGStoreMemNode
Definition: SEGStoreMemNode.h:25
SymbolicExprGraph::dot
void dot(const char *FileName) const
Dot this graph to a file with filename.
Definition: SymbolicExprGraph.cpp:1539
SEGVarArgumentNode
Definition: SEGArgumentNode.h:109
SymbolicExprGraph::ReturnIterator
Definition: SymbolicExprGraph.h:1415
SEGOpcodeNode::CK_FUGE
@ CK_FUGE
1 0 1 1 True if unordered, greater than, or equal
Definition: SymbolicExprGraph.h:696
SEGOperandNode
Definition: SymbolicExprGraph.h:539
SEGPseudoArgumentNode
Definition: SEGArgumentNode.h:155
SEGOpcodeNode::CK_FOGE
@ CK_FOGE
0 0 1 1 True if ordered and greater than or equal
Definition: SymbolicExprGraph.h:688
SEGOpcodeNode::CK_ISGT
@ CK_ISGT
signed greater than
Definition: SymbolicExprGraph.h:709
SEGOpcodeNode::CK_FOEq
@ CK_FOEq
0 0 0 1 True if ordered and equal
Definition: SymbolicExprGraph.h:686
SEGCallSiteOutputNode
Definition: SEGCallSiteOutputNode.h:20
SEGCallSite
Definition: SEGCallSite.h:53
SEGOpcodeNode::CK_FOrd
@ CK_FOrd
0 1 1 1 True if ordered (no nans)
Definition: SymbolicExprGraph.h:692
SEGNodeBase::getTypeSize
uint64_t getTypeSize() const
get the type size of the node
Definition: SymbolicExprGraph.h:348
SEGOpcodeNode::CK_FONE
@ CK_FONE
0 1 1 0 True if ordered and operands are unequal
Definition: SymbolicExprGraph.h:691
SEGOpcodeNode::CodeKind
CodeKind
Definition: SymbolicExprGraph.h:635
SEGOpcodeNode::CK_FOLE
@ CK_FOLE
0 1 0 1 True if ordered and less than or equal
Definition: SymbolicExprGraph.h:690
SEGCallSiteArgumentSummaryNode
Definition: SEGCallSiteArgumentSummaryNode.h:18
SEGCastNode
Definition: SEGCastNode.h:20
SEGCommonArgumentNode
Definition: SEGArgumentNode.h:53
SEGOpcodeNode::CK_FULT
@ CK_FULT
1 1 0 0 True if unordered or less than
Definition: SymbolicExprGraph.h:697
SymbolicExprGraph
Definition: SymbolicExprGraph.h:855
SEGNodeBase::ValueFlowIterator
Definition: SymbolicExprGraph.h:421
SEGOpcodeNode::CK_ISLE
@ CK_ISLE
signed less or equal
Definition: SymbolicExprGraph.h:712
SEGOpcodeNode::CK_IULT
@ CK_IULT
unsigned less than
Definition: SymbolicExprGraph.h:707
SymbolicExprGraph::getBlockCond
const std::set< CDGCond > * getBlockCond(WrappedBasicBlock *BB) const
Definition: SymbolicExprGraph.h:1321
SEGOpcodeNode::CK_IULE
@ CK_IULE
unsigned less or equal
Definition: SymbolicExprGraph.h:708
SEGOpcodeNode::CK_IEq
@ CK_IEq
equal
Definition: SymbolicExprGraph.h:703
SymbolicExprGraph::ArgumentIterator
Definition: SymbolicExprGraph.h:1473
SEGArgumentNode
Definition: SEGArgumentNode.h:19
SEGCallSiteReturnSummaryNode
Definition: SEGCallSiteReturnSummaryNode.h:21
SEGOpcodeNode::assembleSEGObject
virtual void assembleSEGObject(std::map< int, SEGObject * > &FuncSEGObjMap)
Assemble the SEG object's related objects.
Definition: SymbolicExprGraph.h:630
SymbolicExprGraph::CDGCond
Definition: SymbolicExprGraph.h:874
SEGNodeBase::assembleSEGObject
virtual void assembleSEGObject(std::map< int, SEGObject * > &FuncSEGObjMap)
Assemble the SEG object's related objects.
Definition: SymbolicExprGraph.cpp:225
SEGOpcodeNode::CK_IUGT
@ CK_IUGT
unsigned greater than
Definition: SymbolicExprGraph.h:705
SEGValue::getValue
Value * getValue()
Get Value.
Definition: SEGValue.h:66
SEGCommonReturnNode
Definition: SEGReturnNode.h:66
SEGOpcodeNode::CK_FUno
@ CK_FUno
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition: SymbolicExprGraph.h:693
SEGOptions
Definition: SymbolicExprGraph.h:81
SymbolicExprGraphBuilder
Definition: SymbolicExprGraphBuilder.h:38
SEGOpcodeNode::CK_ISGE
@ CK_ISGE
signed greater or equal
Definition: SymbolicExprGraph.h:710
SEGObject
Definition: SymbolicExprGraph.h:87
SEGOpcodeNode::CK_IUGE
@ CK_IUGE
unsigned greater or equal
Definition: SymbolicExprGraph.h:706
SEGCallSitePseudoInputNode
Definition: SEGCallSitePseudoInputNode.h:30
OCValueFlowBuilder
Definition: OCValueFlowBuilder.h:25
SEGNodeBase::getVectorNumElements
unsigned getVectorNumElements() const
check the number of elements in LLVMType
Definition: SymbolicExprGraph.h:365
SEGValue
Definition: SEGValue.h:38
SEGPhiNode
Definition: SEGPhiNode.h:31
SEGOpcodeNode::CK_FOGT
@ CK_FOGT
0 0 1 0 True if ordered and greater than
Definition: SymbolicExprGraph.h:687
SEGOpcodeNode::CK_FUEq
@ CK_FUEq
1 0 0 1 True if unordered or equal
Definition: SymbolicExprGraph.h:694
SEGRegionNode
Definition: SEGRegionNode.h:36
SEGNodeBase::getLLVMType
Type * getLLVMType() const
get the type size of the node
Definition: SymbolicExprGraph.h:336
SEGOpcodeNode::CK_ISLT
@ CK_ISLT
signed less than
Definition: SymbolicExprGraph.h:711
SEGOpcodeNode::CK_FULE
@ CK_FULE
1 1 0 1 True if unordered, less than, or equal
Definition: SymbolicExprGraph.h:698
SEGOpcodeNode::CK_FUGT
@ CK_FUGT
1 0 1 0 True if unordered or greater than
Definition: SymbolicExprGraph.h:695
SEGCallSitePseudoOutputNode
Definition: SEGCallSiteOutputNode.h:96
SEGOpcodeNode::CK_FTrue
@ CK_FTrue
1 1 1 1 Always true (always folded)
Definition: SymbolicExprGraph.h:700
SEGOpcodeNode::CK_FUNE
@ CK_FUNE
1 1 1 0 True if unordered or not equal
Definition: SymbolicExprGraph.h:699
SEGPseudoReturnNode
Definition: SEGReturnNode.h:96
SEGOpcodeNode
Definition: SymbolicExprGraph.h:624
SymbolicExprGraph::findSite
SiteTy * findSite(SEGValue *sValue) const
Get site node based on Value and specific comparison method.
Definition: SymbolicExprGraph.h:1280
SymbolicExprGraph::findSite
SiteTy * findSite(Instruction *I) const
Definition: SymbolicExprGraph.h:1262
SEGSiteBase
Definition: SymbolicExprGraph.h:776
SEGReturnNode
The return node.
Definition: SEGReturnNode.h:31
SEGNodeBase::isVectorTy
bool isVectorTy() const
check whether LLVMType is vector type
Definition: SymbolicExprGraph.h:354
seg_cmp
Definition: SymbolicExprGraph.h:270
SEGOperandNode::assembleSEGObject
virtual void assembleSEGObject(std::map< int, SEGObject * > &FuncSEGObjMap)
Assemble the SEG object's related objects.
Definition: SymbolicExprGraph.h:545
SEGOpcodeNode::CK_INE
@ CK_INE
not equal
Definition: SymbolicExprGraph.h:704
SEGLoadMemNode
Definition: SEGLoadMemNode.h:23
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:288
SEGBinaryWithIntConstNode
Definition: SEGBinaryWithIntConstNode.h:21
SEGOpcodeNode::CK_FOLT
@ CK_FOLT
0 1 0 0 True if ordered and less than
Definition: SymbolicExprGraph.h:689