7 #ifndef SYMBOLIC_EXPR_GRAPH_H
8 #define SYMBOLIC_EXPR_GRAPH_H
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>
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>
25 #include <unordered_map>
26 #include <unordered_set>
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"
35 #include "IR/LLVMWrapper/CallsiteWrapper.h"
36 #include "IR/LLVMWrapper/InstructionWrapper.h"
37 #include "IR/LLVMWrapper/SEGType.h"
38 #include "IR/LLVMWrapper/ValueWrapper.h"
74 class PersistedSEGObject;
75 class PersistedSEGNodeBase;
76 class PersistedSEGOpcodeNode;
77 class PersistedSEGOperandNode;
78 class PersistedSEGSiteBase;
79 class PersistedSymbolicExprGraph;
83 static bool EnableValueToString;
84 static bool EnableArithmeticFlow;
95 SEGOBJK_ArgumentBegin,
96 SEGOBJK_CommonArgument,
98 SEGOBJK_PseudoArgument,
101 SEGOBJK_CallSiteOutputBegin,
102 SEGOBJK_CallSiteCommonOutput,
103 SEGOBJK_CallSitePseudoOutput,
104 SEGOBJK_CallSiteOutputEnd,
107 SEGOBJK_CommonReturn,
108 SEGOBJK_PseudoReturn,
115 SEGOBJK_SimpleOperand,
117 SEGOBJK_CallSitePseudoInput,
118 SEGOBJK_CallSiteSummaryArgument,
119 SEGOBJK_CallSiteSummaryReturn,
125 SEGOBJK_BinaryWithIntConst,
127 SEGOBJK_SimpleOpcode,
138 SEGOBJK_SimpleSiteBegin,
140 SEGOBJK_DereferenceSite,
144 SEGOBJK_SimpleSiteEnd,
150 const SEGObjectKind ObjKind;
156 BasicBlock *ParentBasicBlock =
nullptr;
165 WrappedBasicBlock *WrappedParentBasicBlock =
nullptr;
169 PersistedSEGObject *PersistedObj =
nullptr;
179 virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap) = 0;
202 virtual Value *getLLVMDbgValue()
const {
return nullptr; }
204 virtual WrappedValue *getWrappedLLVMDbgValue()
const {
return nullptr; }
213 virtual Instruction *getLLVMDbgInstruction()
const {
214 Value *val = getLLVMDbgValue();
215 if (val !=
nullptr) {
216 return dyn_cast<Instruction>(val);
222 virtual WrappedInstruction *getWrappedLLVMDbgInstruction()
const {
223 WrappedValue *Val = getWrappedLLVMDbgValue();
224 if (Val !=
nullptr) {
225 return dyn_cast<WrappedInstruction>(Val);
230 SEGObjectKind getKind()
const {
return ObjKind; }
232 int getSEGIndex()
const {
233 assert(SEGIndex &&
"Index should not be 0");
237 int getObjIndex()
const {
238 assert(ObjIndex &&
"Index should not be 0");
242 const char *getKindName()
const;
244 BasicBlock *getParentBasicBlock()
const {
return ParentBasicBlock; }
246 WrappedBasicBlock *getWrappedParentBasicBlock()
const {
247 return WrappedParentBasicBlock;
250 Function *getParentFunction()
const {
return ParentBasicBlock->getParent(); }
255 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGObject &N);
257 virtual PersistedSEGObject *createPersistedObject()
const = 0;
259 virtual void persistSEGData(PersistedSymbolicExprGraph *PersistedSEG);
261 bool isFromLibrary()
const;
263 virtual std::string getSrcFile()
const;
265 virtual std::int32_t getSrcLine()
const {
return 0; }
267 virtual std::string getAuxiliaryDebugStr()
const;
271 LLVMValueIndex *instance;
272 seg_cmp() : instance(LLVMValueIndex::get()) {}
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;
280 int indexA = A ? A->getObjIndex() : 0;
281 int indexB = B ? B->getObjIndex() : 0;
282 return indexA < indexB;
295 virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap);
304 void setDescription(std::string &Desc) { Description = Desc; }
310 std::string Description;
314 std::vector<SEGNodeBase *> Children;
317 std::map<const SEGNodeBase *, float, seg_cmp> Parents;
320 std::vector<SEGSiteBase *> UseSites;
321 std::set<SEGSiteBase *> UseSiteSet;
324 Type *LLVMType =
nullptr;
330 SEGType *SEGTy =
nullptr;
341 return SEGTy->getRealType();
349 assert(SEGTy &&
"SEGTy is nullptr");
350 return SEGTy->getTypeSize();
356 bool isPointerTy()
const {
return SEGTy->isPointerTy(); }
358 bool isSized()
const {
return SEGTy->isSized(); }
360 bool isStructTy()
const {
return SEGTy->isStructTy(); }
362 SEGType *getSEGType()
const {
return SEGTy; }
366 return SEGTy->getVectorNumElements();
370 assert(Children.size() > I &&
371 "Invalid child index when querying SEG edges");
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");
382 unsigned getNumChildren()
const {
return Children.size(); }
384 unsigned getNumParents()
const {
return Parents.size(); }
386 void addChild(
SEGNodeBase *N,
float Confidence = 1.0f) {
387 Children.push_back(N);
388 N->Parents.insert(std::make_pair(
this, Confidence));
391 void eraseAllChildren() {
392 for (
auto *Child : Children) {
393 Child->Parents.erase(
this);
399 if (!UseSiteSet.count(U)) {
400 UseSiteSet.insert(U);
401 UseSites.push_back(U);
405 virtual bool isTerminalNode()
const {
return Children.empty(); }
409 bool containsParentNode(
const SEGNodeBase *N)
const {
410 return Parents.count(N);
413 const std::string &getDescription()
const {
return Description; }
416 virtual void dot(raw_fd_ostream &O)
const = 0;
418 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGNodeBase &N);
424 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
429 It = N->parent_end();
431 It = N->parent_begin();
437 : Node(VFIt.Node), It(VFIt.It) {}
441 this->Node = VFIt.Node;
471 ValueFlowIterator vflow_end()
const {
return {
this,
true}; }
473 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
474 parent_begin()
const {
475 return {Parents.begin()};
478 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
480 return {Parents.end()};
483 iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
485 return {Parents.begin(), Parents.end()};
488 std::vector<SEGNodeBase *>::const_iterator child_begin()
const {
489 return Children.begin();
492 std::vector<SEGNodeBase *>::const_iterator child_end()
const {
493 return Children.end();
496 iterator_range<std::vector<SEGNodeBase *>::const_iterator> children()
const {
497 return {Children.begin(), Children.end()};
500 std::map<const SEGNodeBase *, float>::const_iterator
501 parent_confidence_begin()
const {
502 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
506 std::map<const SEGNodeBase *, float>::const_iterator
507 parent_confidence_end()
const {
508 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
512 size_t child_size()
const {
return Children.size(); }
514 size_t parent_size()
const {
return Parents.size(); }
516 std::vector<SEGSiteBase *>::const_iterator use_site_begin()
const {
517 return UseSites.begin();
520 std::vector<SEGSiteBase *>::const_iterator use_site_end()
const {
521 return UseSites.end();
524 iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
525 return {UseSites.begin(), UseSites.end()};
528 size_t use_site_size()
const {
return UseSites.size(); }
531 static bool classof(
const SEGObject *N) {
532 return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
552 Value *LLVMValue =
nullptr;
556 WrappedValue *WrappedLLVMValue =
nullptr;
582 Value *getLLVMValue()
const {
return LLVMValue; }
584 SEGValue *getSEGValue()
const {
return segValue; }
586 WrappedValue *getWrappedLLVMValue()
const {
return WrappedLLVMValue; }
588 void dot(raw_fd_ostream &O)
const override;
590 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
592 if (Value *Val = N.getLLVMValue()) {
595 Out << N.getDescription();
600 virtual Value *getLLVMDbgValue()
const override {
return getLLVMValue(); }
602 virtual std::int32_t getSrcLine()
const {
603 auto *Val = getWrappedLLVMValue();
605 return Val->getSrcLine();
607 return SEGNodeBase::getSrcLine();
611 static bool classof(
const SEGObject *N) {
612 return N->getKind() >= SEGOBJK_OperandBegin &&
613 N->getKind() <= SEGOBJK_OperandEnd;
617 void initialize(Value *Val);
619 void initializeFromWrappedValue(WrappedValue *WV);
637 CK_URem = CK_BinaryBegin,
655 CK_BinaryEnd = CK_AShr,
658 CK_AddressCast = CK_CastBegin,
671 CK_CastEnd = CK_FP2UI,
685 CK_FFalse = CK_CmpBegin,
731 CodeKind getOpcode()
const {
return Opcode; }
733 virtual void dot(raw_fd_ostream &O)
const;
735 bool isCmpNode()
const {
736 return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
739 bool isSignedCmp()
const {
return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
741 bool isUnSignedCmp()
const {
return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
743 bool isFloatCmp()
const {
return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
745 bool isAddNode()
const {
return Opcode == CK_Add; }
747 bool isSubNode()
const {
return Opcode == CK_Sub; }
749 bool isGEPNode()
const {
return Opcode == CK_GetElmtPtr; }
751 bool isSelectNode()
const {
return Opcode == CK_Select; }
753 bool isCastNode()
const {
754 return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
757 bool isBinaryNode()
const {
758 return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
761 bool isExtractElmtNode()
const {
return Opcode == CK_ExtractElmt; }
763 bool isInsertElmtNode()
const {
return Opcode == CK_InsertElmt; }
765 bool isConcatNode()
const {
return Opcode == CK_Concat; }
768 static bool classof(
const SEGObject *N) {
769 return N->getKind() >= SEGOBJK_OpcodeBegin &&
770 N->getKind() <= SEGOBJK_OpcodeEnd;
773 static const char *getOpcodeName(CodeKind CK);
783 virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap);
786 Instruction *User =
nullptr;
788 WrappedInstruction *WrappedUser =
nullptr;
799 CallSite getLLVMCallSite()
const {
return CallSite(User); }
801 WrappedCallSite getWrappedLLVMCallSite()
const {
802 return WrappedCallSite(WrappedUser);
805 Instruction *getInstruction()
const {
return User; }
807 WrappedInstruction *getWrappedInstruction()
const {
return WrappedUser; }
809 SEGValue *getSEGValue()
const {
return segValue; }
811 virtual Value *getLLVMDbgValue()
const override {
return getInstruction(); }
813 virtual WrappedValue *getWrappedLLVMDbgValue()
const override {
814 return getWrappedInstruction();
817 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
823 virtual std::string getSrcFile()
const {
825 return WrappedUser->getSrcFileName();
831 virtual std::int32_t getSrcLine()
const {
833 return WrappedUser->getSrcLine();
840 static bool classof(
const SEGObject *O) {
841 return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
845 namespace FalconPlus {
851 class AbstractCondPtr;
859 friend class IntraFalcon;
860 friend class MantaIntraFalcon;
861 friend class PTGraph;
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;
876 WrappedBasicBlock *BB;
881 : CondNode(CN), BB(WrappedValue::findWrappedBasicBlock(B)), Cond(C) {}
884 : CondNode(CN), BB(B), Cond(C) {}
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);
892 bool operator==(
const CDGCond &RHS)
const {
893 return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
896 BasicBlock *getBB()
const {
return BB->getRealBlock(); }
901 Function *BaseFunc =
nullptr;
908 std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
913 std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
917 std::set<SEGNodeBase *, seg_cmp> NonValueNodes;
924 std::map<Instruction *, SEGSiteBase *> InstSiteMap;
925 std::vector<SEGCallSite *> CallSites;
934 std::map<WrappedBasicBlock *, std::set<CDGCond> *, CmpPointerOfValue>
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>>
945 int SEGObjIndexIter = 1;
951 kvec<SEGPseudoReturnNode *> PseudoReturns;
953 kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
954 kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
955 kvec<SEGVarArgumentNode *> VarArgumentNodes;
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;
986 void addSummaryArgNode(
SEGNodeBase *Node,
int APDepth);
988 void addSummaryReturnNode(
SEGNodeBase *Node,
int APDepth);
995 size_t getNumCommonArgument()
const {
return CommonArgumentNodes.size(); }
997 size_t getNumPseudoArgument()
const {
return PseudoArgumentNodes.size(); }
999 size_t getNumVarArgument()
const {
return VarArgumentNodes.size(); }
1001 size_t getNumPseudoReturn()
const {
return PseudoReturns.size(); }
1003 bool hasCommonReturnNode()
const {
1013 return PseudoReturns[Index];
1017 return CommonArgumentNodes[Index];
1021 return PseudoArgumentNodes[Index];
1025 return VarArgumentNodes[Index];
1030 int getSEGIndex() {
return SEGIndex; }
1032 bool isSummaryArgument(
const SEGNodeBase *Node)
const;
1036 int getSummaryArgumentAPDepth(
const SEGNodeBase *Node)
const;
1040 std::unordered_set<SEGNodeBase *> *getSummaryArgument(
int APDepth)
const;
1042 bool isSummaryReturn(
const SEGNodeBase *Node)
const;
1046 int getSummaryReturnAPDepth(
const SEGNodeBase *Node)
const;
1050 std::unordered_set<SEGNodeBase *> *getSummaryReturn(
int APDepth)
const;
1057 bool isDirectlyPassedToCaller(
const SEGNodeBase *Node)
const;
1058 bool isDirectlyPassedFromCaller(
const SEGNodeBase *Node)
const;
1068 std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
1069 std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
1071 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
1072 compound_regions_cache_and;
1074 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
1075 compound_regions_cache_or;
1078 std::unordered_map<WrappedBasicBlock *, SEGRegionNode *> bb_region_cache;
1096 SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
1100 template <
class OperandNodeTy>
1101 OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB) {
1103 assert(Val && !Val->getType()->isVoidTy());
1104 assert((!(dyn_cast<Instruction>(Val)) ||
1105 BB == ((Instruction *)Val)->getParent()) &&
1106 "Incorrect BasicBlock detected");
1108 auto It = ValueNodesMap.find(Val);
1109 if (It != ValueNodesMap.end()) {
1110 assert(isa<OperandNodeTy>(It->second));
1111 return (OperandNodeTy *)It->second;
1113 OperandNodeTy *N =
new OperandNodeTy(Val, Ty,
this, BB);
1114 ValueNodePairs.push_back({Val, N});
1115 ValueNodesMap[Val] = N;
1122 findOrCreatePseudoArgumentNode(
const FalconPlus::PseudoVal *Arg,
1125 void finalizePseudoArgumentNodes();
1127 findOrCreateSimpleOperandFromPseudoVal(
const FalconPlus::PseudoVal *Arg,
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);
1138 template <
class OperandNodeTy>
1139 OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB) {
1141 assert(Val && !Val->getType()->isVoidTy());
1142 assert((!(dyn_cast<Instruction>(Val)) ||
1143 BB == ((Instruction *)Val)->getParent()) &&
1144 "Incorrect BasicBlock detected");
1146 OperandNodeTy *N =
new OperandNodeTy(Val, Ty,
this, BB);
1147 ValueNodesMap[Val] = N;
1148 ValueNodePairs.push_back({Val, N});
1152 template <
class OperandNodeTy>
1153 OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB) {
1155 OperandNodeTy *Ret =
new OperandNodeTy(Ty,
this, BB);
1156 NonValueNodes.insert(Ret);
1162 template <
class SiteTy> SiteTy *findOrCreateSite(Instruction *I) {
1165 auto It = InstSiteMap.find(I);
1166 if (It != InstSiteMap.end()) {
1167 assert(isa<SiteTy>(It->second));
1168 return (SiteTy *)It->second;
1170 SiteTy *N =
new SiteTy(I,
this);
1174 CallSites.push_back(CS);
1185 createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1186 Instruction *Callsite,
int APDepth);
1192 createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1193 Instruction *Callsite,
float Confidence);
1197 findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1198 CallSite CS, Function *Callee,
bool IsCommon);
1202 findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1203 CallSite CS, Function *Callee);
1206 SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1207 Value *StoreVal, BasicBlock *BB);
1238 BasicBlock *BB,
const kvec<SEGNodeBase *> &);
1247 Type *Ty, BasicBlock *BB,
1251 void addBlockCond(BasicBlock *CurrBB,
SEGNodeBase *BrNode, BasicBlock *DepBB,
1258 Function *getBaseFunc()
const {
return BaseFunc; }
1262 template <
class SiteTy> SiteTy *
findSite(Instruction *I)
const {
1265 auto It = InstSiteMap.find(I);
1266 if (It != InstSiteMap.end()) {
1268 return dyn_cast<SiteTy>(It->second);
1281 Instruction *I = dyn_cast<Instruction>(sValue->
getValue());
1284 auto It = InstSiteMap.find(I);
1285 if (It != InstSiteMap.end()) {
1287 return dyn_cast<SiteTy>(It->second);
1322 auto It = BlockCondMap.find(BB);
1323 if (It != BlockCondMap.end()) {
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()) {
1339 void dot(
const char *FileName)
const;
1342 void dot(std::vector<const SEGNodeBase *> Srcs,
const char *FileName)
const;
1351 SEGRegionNode *findOrCreateRegionForBB(WrappedBasicBlock *BB);
1356 SEGRegionNode *findRegionForBB(WrappedBasicBlock *BB)
const;
1360 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1361 value_node_begin()
const {
1362 return ValueNodesMap.begin();
1365 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1366 value_node_end()
const {
1367 return ValueNodesMap.end();
1370 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1371 value_node_pair_begin()
const {
1372 return ValueNodePairs.begin();
1375 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1376 value_node_pair_end()
const {
1377 return ValueNodePairs.end();
1380 std::set<SEGNodeBase *>::const_iterator non_value_node_begin()
const {
1381 return NonValueNodes.begin();
1384 std::set<SEGNodeBase *>::const_iterator non_value_node_end()
const {
1385 return NonValueNodes.end();
1388 std::map<Instruction *, SEGSiteBase *>::const_iterator
1389 inst_site_begin()
const {
1390 return InstSiteMap.begin();
1393 std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end()
const {
1394 return InstSiteMap.end();
1397 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1398 store_mem_node_begin()
const {
1399 return StoreMemNodesMap.begin();
1402 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1403 store_mem_node_end()
const {
1404 return StoreMemNodesMap.end();
1407 std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin()
const {
1408 return InstSiteMap.begin();
1411 std::map<Instruction *, SEGSiteBase *>::const_iterator site_end()
const {
1412 return InstSiteMap.end();
1419 const kvec<SEGPseudoReturnNode *> &PseudoRets;
1423 const kvec<SEGPseudoReturnNode *> &PRs)
1424 : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1427 : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1461 ReturnIterator return_end()
const {
1462 return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1463 CommonReturn, PseudoReturns);
1466 ReturnIterator pseudo_return_begin()
const {
1467 size_t StartIndex = getCommonReturn() ? 1 : 0;
1468 return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1471 ReturnIterator pseudo_return_end()
const {
return return_end(); }
1476 const kvec<SEGCommonArgumentNode *> &CommonArgs;
1477 const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1478 const kvec<SEGVarArgumentNode *> &VarArgs;
1482 const kvec<SEGPseudoArgumentNode *> &PA,
1483 const kvec<SEGVarArgumentNode *> &VA)
1484 : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1487 : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1488 VarArgs(It.VarArgs) {}
1502 if (I < (
size_t)CommonArgs.size()) {
1506 if (I < (
size_t)(CommonArgs.size() + PseudoArgs.size())) {
1511 (
size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1513 VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1526 ArgumentIterator arg_end()
const {
1528 getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1529 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1533 ArgumentIterator common_arg_begin()
const {
return arg_begin(); }
1535 ArgumentIterator common_arg_end()
const {
1536 size_t NumArgs = getNumCommonArgument();
1537 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1541 ArgumentIterator pseudo_arg_begin()
const {
return common_arg_end(); }
1543 ArgumentIterator pseudo_arg_end()
const {
1544 size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1545 return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1549 ArgumentIterator var_arg_begin()
const {
return pseudo_arg_end(); }
1551 ArgumentIterator var_arg_end()
const {
return arg_end(); }
1553 typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1554 SEGCallSiteIterator seg_callsite_begin()
const {
return CallSites.begin(); }
1556 SEGCallSiteIterator seg_callsite_end()
const {
return CallSites.end(); }
1561 WrappedFunction *WrappedBasefunc =
nullptr;
1562 WrappedModule *WrappedMod =
nullptr;
1563 std::map<int, SEGObject *> SEGObjectMap;
1564 std::map<const SEGObject *, int> ReverseSEGObjectMap;
1566 template <
class IndexedNode>
void SortByIndex(kvec<IndexedNode *> &Nodes) {
1567 if (Nodes.size() == 0) {
1571 kvec<IndexedNode *> OrderedNodes;
1572 OrderedNodes.push_empty(Nodes.size());
1574 for (
auto *Node : Nodes) {
1575 OrderedNodes[Node->getIndex()] = Node;
1578 Nodes.push_back(OrderedNodes);
1586 bool comparePersistedSEG(PersistedSymbolicExprGraph *PersistedSEG);
1588 const WrappedModule *getWrappedMod()
const {
return WrappedMod; }
1590 WrappedFunction *getWrappedBaseFunc()
const {
return WrappedBasefunc; }
1592 int getSEGObjectID(
const SEGObject *SEGObj)
const {
1593 if (ReverseSEGObjectMap.find(SEGObj) != ReverseSEGObjectMap.end()) {
1594 return ReverseSEGObjectMap.at(SEGObj);