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"
72 static bool EnableValueToString;
73 static bool EnableArithmeticFlow;
77 friend class SEGSerializer;
87 SEGOBJK_ArgumentBegin,
88 SEGOBJK_CommonArgument,
90 SEGOBJK_PseudoArgument,
93 SEGOBJK_CallSiteOutputBegin,
94 SEGOBJK_CallSiteCommonOutput,
95 SEGOBJK_CallSitePseudoOutput,
96 SEGOBJK_CallSiteOutputEnd,
100 SEGOBJK_PseudoReturn,
107 SEGOBJK_SimpleOperand,
109 SEGOBJK_CallSitePseudoInput,
110 SEGOBJK_CallSiteSummaryArgument,
111 SEGOBJK_CallSiteSummaryReturn,
117 SEGOBJK_BinaryWithIntConst,
119 SEGOBJK_SimpleOpcode,
130 SEGOBJK_SimpleSiteBegin,
132 SEGOBJK_DereferenceSite,
136 SEGOBJK_SimpleSiteEnd,
142 const SEGObjectKind ObjKind;
148 BasicBlock *ParentBasicBlock =
nullptr;
151 int64_t ObjIndex = -1;
154 int64_t SEGIndex = -1;
182 virtual Value *getLLVMDbgValue()
const {
return nullptr; }
191 virtual Instruction *getLLVMDbgInstruction()
const {
192 Value *val = getLLVMDbgValue();
193 if (val !=
nullptr) {
194 return dyn_cast<Instruction>(val);
200 SEGObjectKind getKind()
const {
return ObjKind; }
202 int64_t getSEGIndex()
const {
203 assert(SEGIndex != -1 &&
"Index should not be -1");
207 void setObjIndex(int64_t index) { ObjIndex = index; }
209 int64_t getObjIndex()
const {
210 assert(ObjIndex != -1 &&
"Index should not be -1");
214 const char *getKindName()
const;
216 BasicBlock *getParentBasicBlock()
const {
return ParentBasicBlock; }
218 Function *getParentFunction()
const {
return ParentBasicBlock->getParent(); }
223 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGObject &N);
227 LLVMValueManager *instance;
228 seg_cmp() : instance(LLVMValueManager::get()) {}
231 int64_t indexSEGA = A ? A->getSEGIndex() : -1;
232 int64_t indexSEGB = B ? B->getSEGIndex() : -1;
233 if (indexSEGA != indexSEGB || (indexSEGA == -1 && indexSEGB == -1)) {
234 return indexSEGA < indexSEGB;
236 int64_t indexA = A ? A->getObjIndex() : -1;
237 int64_t indexB = B ? B->getObjIndex() : -1;
238 return indexA < indexB;
245 friend class SEGSerializer;
246 friend class SEGHash;
255 void setDescription(std::string &Desc) { Description = Desc; }
261 std::string Description;
265 std::vector<SEGNodeBase *> Children;
268 std::map<const SEGNodeBase *, float, seg_cmp> Parents;
271 std::vector<SEGSiteBase *> UseSites;
272 std::set<SEGSiteBase *> UseSiteSet;
275 Type *LLVMType =
nullptr;
287 assert(Children.size() > I &&
288 "Invalid child index when querying SEG edges");
292 float getConfidence(
const SEGNodeBase *ParentNode)
const {
293 auto It = Parents.find(ParentNode);
294 assert(It != Parents.end() &&
295 "Invalid parent node when querying SEG edges");
299 unsigned getNumChildren()
const {
return Children.size(); }
301 unsigned getNumParents()
const {
return Parents.size(); }
303 void addChild(
SEGNodeBase *N,
float Confidence = 1.0f) {
304 Children.push_back(N);
305 N->Parents.insert(std::make_pair(
this, Confidence));
308 void eraseAllChildren() {
309 for (
auto *Child : Children) {
310 Child->Parents.erase(
this);
316 if (!UseSiteSet.count(U)) {
317 UseSiteSet.insert(U);
318 UseSites.push_back(U);
322 virtual bool isTerminalNode()
const {
return Children.empty(); }
326 bool containsParentNode(
const SEGNodeBase *N)
const {
327 return Parents.count(N);
330 const std::string &getDescription()
const {
return Description; }
333 virtual void dot(raw_fd_ostream &O)
const = 0;
335 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGNodeBase &N);
341 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
346 It = N->parent_end();
348 It = N->parent_begin();
354 : Node(VFIt.Node), It(VFIt.It) {}
358 this->Node = VFIt.Node;
388 ValueFlowIterator vflow_end()
const {
return {
this,
true}; }
390 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
391 parent_begin()
const {
392 return {Parents.begin()};
395 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
397 return {Parents.end()};
400 iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
402 return {Parents.begin(), Parents.end()};
405 std::vector<SEGNodeBase *>::const_iterator child_begin()
const {
406 return Children.begin();
409 std::vector<SEGNodeBase *>::const_iterator child_end()
const {
410 return Children.end();
413 iterator_range<std::vector<SEGNodeBase *>::const_iterator> children()
const {
414 return {Children.begin(), Children.end()};
417 std::map<const SEGNodeBase *, float>::const_iterator
418 parent_confidence_begin()
const {
419 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
423 std::map<const SEGNodeBase *, float>::const_iterator
424 parent_confidence_end()
const {
425 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
429 size_t child_size()
const {
return Children.size(); }
431 size_t parent_size()
const {
return Parents.size(); }
433 std::vector<SEGSiteBase *>::const_iterator use_site_begin()
const {
434 return UseSites.begin();
437 std::vector<SEGSiteBase *>::const_iterator use_site_end()
const {
438 return UseSites.end();
441 iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
442 return {UseSites.begin(), UseSites.end()};
445 size_t use_site_size()
const {
return UseSites.size(); }
448 static bool classof(
const SEGObject *N) {
449 return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
460 Value *LLVMValue =
nullptr;
466 BasicBlock *BB,
bool fromDisk);
480 BasicBlock *BB,
bool fromDisk);
484 friend class SEGHash;
489 Value *getLLVMValue()
const {
return LLVMValue; }
491 SEGValue *getSEGValue()
const {
return segValue; }
493 void dot(raw_fd_ostream &O)
const override;
495 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
497 if (Value *Val = N.getLLVMValue()) {
500 Out << N.getDescription();
505 virtual Value *getLLVMDbgValue()
const override {
return getLLVMValue(); }
508 static bool classof(
const SEGObject *N) {
509 return N->getKind() >= SEGOBJK_OperandBegin &&
510 N->getKind() <= SEGOBJK_OperandEnd;
514 void initialize(Value *Val);
524 CK_URem = CK_BinaryBegin,
542 CK_BinaryEnd = CK_AShr,
545 CK_AddressCast = CK_CastBegin,
558 CK_CastEnd = CK_FP2UI,
572 CK_FFalse = CK_CmpBegin,
618 CodeKind getOpcode()
const {
return Opcode; }
620 virtual void dot(raw_fd_ostream &O)
const;
622 bool isCmpNode()
const {
623 return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
626 bool isSignedCmp()
const {
return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
628 bool isUnSignedCmp()
const {
return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
630 bool isFloatCmp()
const {
return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
632 bool isAddNode()
const {
return Opcode == CK_Add; }
634 bool isSubNode()
const {
return Opcode == CK_Sub; }
636 bool isGEPNode()
const {
return Opcode == CK_GetElmtPtr; }
638 bool isSelectNode()
const {
return Opcode == CK_Select; }
640 bool isCastNode()
const {
641 return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
644 bool isBinaryNode()
const {
645 return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
648 bool isExtractElmtNode()
const {
return Opcode == CK_ExtractElmt; }
650 bool isInsertElmtNode()
const {
return Opcode == CK_InsertElmt; }
652 bool isConcatNode()
const {
return Opcode == CK_Concat; }
655 static bool classof(
const SEGObject *N) {
656 return N->getKind() >= SEGOBJK_OpcodeBegin &&
657 N->getKind() <= SEGOBJK_OpcodeEnd;
660 static const char *getOpcodeName(CodeKind CK);
666 Instruction *User =
nullptr;
678 CallSite getLLVMCallSite()
const {
return CallSite(User); }
680 Instruction *getInstruction()
const {
return User; }
682 SEGValue *getSEGValue()
const {
return segValue; }
684 virtual Value *getLLVMDbgValue()
const override {
return getInstruction(); }
686 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
693 static bool classof(
const SEGObject *O) {
694 return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
698 namespace FalconPlus {
704 class AbstractCondPtr;
712 friend class IntraFalcon;
713 friend class MantaIntraFalcon;
714 friend class PTGraph;
717 friend class SEGSerializer;
719 friend class FalconPlus::AbstractCond;
720 friend class FalconPlus::RegionCond;
721 friend class FalconPlus::FreeCond;
722 friend class FalconPlus::BitCondVec;
723 friend class FalconPlus::IntraFalcon;
724 friend class FalconPlus::AbstractCondPtr;
725 friend class FalconPlus::FalconAA;
735 : CondNode(CN), BB(B), Cond(C) {}
737 bool operator<(
const CDGCond &RHS)
const {
738 return (CondNode < RHS.CondNode) ||
739 (CondNode == RHS.CondNode && BB < RHS.BB) ||
740 (CondNode == RHS.CondNode && BB == RHS.BB && Cond < RHS.Cond);
743 bool operator==(
const CDGCond &RHS)
const {
744 return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
747 BasicBlock *getBB()
const {
return BB; }
752 Function *BaseFunc =
nullptr;
755 std::vector<SEGObject *> NodesList;
758 std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
763 std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
767 std::set<SEGNodeBase *> NonValueNodes;
774 std::map<Instruction *, SEGSiteBase *> InstSiteMap;
775 std::vector<SEGCallSite *> CallSites;
784 std::map<BasicBlock *, std::set<CDGCond> *> BlockCondMap;
786 int64_t SEGIndex = -1;
790 int64_t getSEGIndex()
const {
return SEGIndex; }
792 template <
class T> T *getSEGObject(int64_t index) {
793 assert(index == -1 || (index >= 0 && index < NodesList.size()));
796 auto *Obj = NodesList[index];
805 kvec<SEGPseudoReturnNode *> PseudoReturns;
807 kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
808 kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
809 kvec<SEGVarArgumentNode *> VarArgumentNodes;
823 std::unordered_map<SEGNodeBase *, int> SummaryArgNodes;
824 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
825 SummaryArgNodesCache;
826 std::unordered_map<SEGNodeBase *, int> SummaryReturnNodes;
827 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
828 SummaryReturnNodesCache;
831 std::map<std::string, SEGOperandNode *> NameToPseudoArgNode;
832 std::unordered_map<std::string, SEGOperandNode *> NameToNonArgPseudoNode;
833 std::unordered_map<std::string, std::unique_ptr<FalconPlus::PseudoVal>>
846 void addSummaryArgNode(
SEGNodeBase *Node,
int APDepth);
848 void addSummaryReturnNode(
SEGNodeBase *Node,
int APDepth);
851 size_t getNumCommonArgument()
const {
return CommonArgumentNodes.size(); }
853 size_t getNumPseudoArgument()
const {
return PseudoArgumentNodes.size(); }
855 size_t getNumVarArgument()
const {
return VarArgumentNodes.size(); }
857 size_t getNumPseudoReturn()
const {
return PseudoReturns.size(); }
859 bool hasCommonReturnNode()
const {
869 return PseudoReturns[Index];
873 return CommonArgumentNodes[Index];
877 return PseudoArgumentNodes[Index];
881 return VarArgumentNodes[Index];
884 bool isSummaryArgument(
const SEGNodeBase *Node)
const;
888 int getSummaryArgumentAPDepth(
const SEGNodeBase *Node)
const;
892 std::unordered_set<SEGNodeBase *> *getSummaryArgument(
int APDepth)
const;
894 bool isSummaryReturn(
const SEGNodeBase *Node)
const;
898 int getSummaryReturnAPDepth(
const SEGNodeBase *Node)
const;
902 std::unordered_set<SEGNodeBase *> *getSummaryReturn(
int APDepth)
const;
909 bool isDirectlyPassedToCaller(
const SEGNodeBase *Node)
const;
910 bool isDirectlyPassedFromCaller(
const SEGNodeBase *Node)
const;
920 std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
921 std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
923 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
924 compound_regions_cache_and;
926 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
927 compound_regions_cache_or;
930 std::unordered_map<BasicBlock *, SEGRegionNode *> bb_region_cache;
948 SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
952 template <
class OperandNodeTy>
953 OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
954 bool fromDisk =
false) {
956 assert(Val && !Val->getType()->isVoidTy());
957 assert((!(dyn_cast<Instruction>(Val)) ||
958 BB == ((Instruction *)Val)->getParent()) &&
959 "Incorrect BasicBlock detected");
961 auto It = ValueNodesMap.find(Val);
962 if (It != ValueNodesMap.end()) {
963 assert(isa<OperandNodeTy>(It->second));
964 return (OperandNodeTy *)It->second;
966 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
967 ValueNodePairs.push_back({Val, N});
968 ValueNodesMap[Val] = N;
975 template <
class OperandNodeTy>
976 OperandNodeTy *clonePseudoVal(
977 const FalconPlus::PseudoVal *Arg,
978 std::function<OperandNodeTy *(
const FalconPlus::PseudoVal *)> Proc) {
979 const std::string &ArgName = Arg->getName();
980 auto ClonedArg = std::unique_ptr<FalconPlus::PseudoVal>(Arg->clone());
981 auto *ArgNode = Proc(ClonedArg.get());
983 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
984 NameToPseudoArgNode.insert(std::make_pair(ArgName, ArgNode));
986 NameToNonArgPseudoNode.insert(std::make_pair(ArgName, ArgNode));
989 assert(!PseudoValStorage.count(ArgName));
990 PseudoValStorage.insert({ArgName, std::move(ClonedArg)});
994 template <
class OperandNodeTy>
995 OperandNodeTy *findOrClonePseudoVal(
996 const FalconPlus::PseudoVal *Arg,
997 std::function<OperandNodeTy *(
const FalconPlus::PseudoVal *)> Proc) {
998 const std::string &ArgName = Arg->getName();
999 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
1000 if (NameToPseudoArgNode.count(ArgName)) {
1001 return cast<OperandNodeTy>(NameToPseudoArgNode.at(ArgName));
1004 if (NameToNonArgPseudoNode.count(ArgName)) {
1006 std::is_base_of<SEGOperandNode, OperandNodeTy>::value,
1007 "OperandNodeTy must be a derived class of SEGOperandNode.");
1008 return cast<OperandNodeTy>(NameToNonArgPseudoNode.at(ArgName));
1012 return clonePseudoVal<OperandNodeTy>(Arg, Proc);
1016 findOrCreatePseudoArgumentNode(
const FalconPlus::PseudoVal *Arg,
1019 void finalizePseudoArgumentNodes();
1021 findOrCreateSimpleOperandFromPseudoVal(
const FalconPlus::PseudoVal *Arg,
1026 createPseudoInputNode(
const FalconPlus::PseudoVal *Arg, BasicBlock *BB,
1027 CallSite CS, Function *Callee);
1029 createPseudoOutputNode(
const FalconPlus::PseudoVal *Arg, BasicBlock *BB,
1030 CallInst *Call, Function *Callee);
1032 template <
class OperandNodeTy>
1033 OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
1034 bool fromDisk =
false) {
1036 assert(Val && !Val->getType()->isVoidTy());
1037 assert((!(dyn_cast<Instruction>(Val)) ||
1038 BB == ((Instruction *)Val)->getParent()) &&
1039 "Incorrect BasicBlock detected");
1041 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
1042 ValueNodesMap[Val] = N;
1043 ValueNodePairs.push_back({Val, N});
1047 template <
class OperandNodeTy>
1048 OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB,
1049 bool fromDisk =
false) {
1052 auto *Ret =
new OperandNodeTy(Ty,
this, BB, fromDisk);
1053 NonValueNodes.insert(Ret);
1059 template <
class SiteTy>
1060 SiteTy *findOrCreateSite(Instruction *I,
bool fromDisk =
false) {
1063 auto It = InstSiteMap.find(I);
1064 if (It != InstSiteMap.end()) {
1065 assert(isa<SiteTy>(It->second));
1066 return (SiteTy *)It->second;
1068 SiteTy *N =
new SiteTy(I,
this, fromDisk);
1072 CallSites.push_back(CS);
1083 createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1084 Instruction *Callsite,
int APDepth,
1085 bool fromDisk =
false);
1091 createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1092 Instruction *Callsite,
float Confidence,
1093 bool fromDisk =
false);
1097 findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1098 CallSite CS, Function *Callee,
bool IsCommon);
1101 BasicBlock *BB, CallSite CS,
1104 bool fromDisk =
false);
1108 findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1109 CallSite CS, Function *Callee,
1110 bool fromDisk =
false);
1113 SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1114 Value *StoreVal, BasicBlock *BB,
1115 bool fromDisk =
false);
1119 bool cond =
false,
bool fromDisk =
false);
1151 BasicBlock *BB,
const kvec<SEGNodeBase *> &,
1152 bool fromDisk =
false);
1157 uint64_t TSz,
bool fromDisk =
false);
1163 bool fromDisk =
false);
1166 void addBlockCond(BasicBlock *CurrBB,
SEGNodeBase *BrNode, BasicBlock *DepBB,
1173 Function *getBaseFunc()
const {
return BaseFunc; }
1177 template <
class SiteTy> SiteTy *
findSite(Instruction *I)
const {
1180 auto It = InstSiteMap.find(I);
1181 if (It != InstSiteMap.end()) {
1183 return dyn_cast<SiteTy>(It->second);
1196 Instruction *I = dyn_cast<Instruction>(sValue->
getValue());
1199 auto It = InstSiteMap.find(I);
1200 if (It != InstSiteMap.end()) {
1202 return dyn_cast<SiteTy>(It->second);
1237 auto It = BlockCondMap.find(BB);
1238 if (It != BlockCondMap.end()) {
1245 void dot(
const char *FileName)
const;
1248 void dot(std::vector<const SEGNodeBase *> Srcs,
const char *FileName)
const;
1262 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1263 value_node_begin()
const {
1264 return ValueNodesMap.begin();
1267 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1268 value_node_end()
const {
1269 return ValueNodesMap.end();
1272 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1273 value_node_pair_begin()
const {
1274 return ValueNodePairs.begin();
1277 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1278 value_node_pair_end()
const {
1279 return ValueNodePairs.end();
1282 std::set<SEGNodeBase *>::const_iterator non_value_node_begin()
const {
1283 return NonValueNodes.begin();
1286 std::set<SEGNodeBase *>::const_iterator non_value_node_end()
const {
1287 return NonValueNodes.end();
1290 std::map<Instruction *, SEGSiteBase *>::const_iterator
1291 inst_site_begin()
const {
1292 return InstSiteMap.begin();
1295 std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end()
const {
1296 return InstSiteMap.end();
1299 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1300 store_mem_node_begin()
const {
1301 return StoreMemNodesMap.begin();
1304 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1305 store_mem_node_end()
const {
1306 return StoreMemNodesMap.end();
1309 std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin()
const {
1310 return InstSiteMap.begin();
1313 std::map<Instruction *, SEGSiteBase *>::const_iterator site_end()
const {
1314 return InstSiteMap.end();
1317 std::vector<SEGObject *>::const_iterator node_begin()
const {
1318 return NodesList.begin();
1321 std::vector<SEGObject *>::const_iterator node_end()
const {
1322 return NodesList.end();
1329 const kvec<SEGPseudoReturnNode *> &PseudoRets;
1333 const kvec<SEGPseudoReturnNode *> &PRs)
1334 : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1337 : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1371 ReturnIterator return_end()
const {
1372 return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1373 CommonReturn, PseudoReturns);
1376 ReturnIterator pseudo_return_begin()
const {
1377 size_t StartIndex = getCommonReturn() ? 1 : 0;
1378 return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1381 ReturnIterator pseudo_return_end()
const {
return return_end(); }
1386 const kvec<SEGCommonArgumentNode *> &CommonArgs;
1387 const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1388 const kvec<SEGVarArgumentNode *> &VarArgs;
1392 const kvec<SEGPseudoArgumentNode *> &PA,
1393 const kvec<SEGVarArgumentNode *> &VA)
1394 : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1397 : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1398 VarArgs(It.VarArgs) {}
1412 if (I < (
size_t)CommonArgs.size()) {
1416 if (I < (
size_t)(CommonArgs.size() + PseudoArgs.size())) {
1421 (
size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1423 VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1436 ArgumentIterator arg_end()
const {
1438 getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1439 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1443 ArgumentIterator common_arg_begin()
const {
return arg_begin(); }
1445 ArgumentIterator common_arg_end()
const {
1446 size_t NumArgs = getNumCommonArgument();
1447 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1451 ArgumentIterator pseudo_arg_begin()
const {
return common_arg_end(); }
1453 ArgumentIterator pseudo_arg_end()
const {
1454 size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1455 return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1459 ArgumentIterator var_arg_begin()
const {
return pseudo_arg_end(); }
1461 ArgumentIterator var_arg_end()
const {
return arg_end(); }
1463 typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1464 SEGCallSiteIterator seg_callsite_begin()
const {
return CallSites.begin(); }
1466 SEGCallSiteIterator seg_callsite_end()
const {
return CallSites.end(); }