From 6d0d168b19fb465c3dc48a94cdc38dcb36980163 Mon Sep 17 00:00:00 2001 From: Xiao Date: Mon, 10 Feb 2025 15:50:56 +1100 Subject: [PATCH] remove svfmodule and value in svfcore (#1651) * remove svfmodule in dda * remove svfmodule in saber * remove more svfmodule * move svfmodule to llvm * move svfvalue to llvm --- svf-llvm/include/SVF-LLVM/BreakConstantExpr.h | 2 +- svf-llvm/include/SVF-LLVM/CppUtil.h | 2 +- svf-llvm/include/SVF-LLVM/DCHG.h | 2 +- svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h | 2 +- svf-llvm/include/SVF-LLVM/LLVMModule.h | 4 +- svf-llvm/include/SVF-LLVM/LLVMUtil.h | 2 +- svf-llvm/include/SVF-LLVM/ObjTypeInference.h | 2 +- .../include/SVF-LLVM}/SVFModule.h | 37 +- svf-llvm/include/SVF-LLVM/SVFValue.h | 805 +++++++++++++ svf-llvm/lib/CHGBuilder.cpp | 2 +- svf-llvm/lib/LLVMLoopAnalysis.cpp | 4 +- svf-llvm/lib/LLVMModule.cpp | 17 +- svf-llvm/lib/SVFIRBuilder.cpp | 15 +- {svf/lib/SVFIR => svf-llvm/lib}/SVFModule.cpp | 3 +- svf-llvm/lib/SVFValue.cpp | 71 ++ svf-llvm/lib/SymbolTableBuilder.cpp | 2 +- svf/include/DDA/DDAClient.h | 17 +- svf/include/DDA/DDAPass.h | 2 +- svf/include/Graphs/CHG.h | 5 +- svf/include/Graphs/GenericGraph.h | 287 +---- svf/include/MTA/MTA.h | 4 +- svf/include/MTA/TCT.h | 6 - svf/include/MemoryModel/PointerAnalysis.h | 8 +- svf/include/SABER/DoubleFreeChecker.h | 2 +- svf/include/SABER/FileChecker.h | 2 +- svf/include/SABER/LeakChecker.h | 2 +- svf/include/SABER/SaberCondAllocator.h | 3 +- svf/include/SABER/SrcSnkDDA.h | 4 +- svf/include/SVFIR/ObjTypeInfo.h | 1 - svf/include/SVFIR/SVFIR.h | 48 +- svf/include/SVFIR/SVFStatements.h | 1 + svf/include/SVFIR/SVFValue.h | 1002 ++++------------- svf/include/Util/CDGBuilder.h | 2 +- svf/include/Util/GeneralType.h | 1 + svf/include/Util/SVFLoopAndDomInfo.h | 168 +++ svf/include/Util/SVFUtil.h | 4 +- svf/include/Util/ThreadAPI.h | 3 +- svf/include/WPA/FlowSensitive.h | 2 +- svf/lib/DDA/DDAPass.cpp | 14 +- svf/lib/Graphs/ConsG.cpp | 2 +- svf/lib/Graphs/ICFG.cpp | 1 - svf/lib/Graphs/SVFG.cpp | 2 +- svf/lib/Graphs/SVFGReadWrite.cpp | 1 - svf/lib/Graphs/ThreadCallGraph.cpp | 1 - svf/lib/Graphs/VFG.cpp | 1 - svf/lib/MSSA/MemRegion.cpp | 1 - svf/lib/MSSA/SVFGBuilder.cpp | 1 - svf/lib/MTA/MTA.cpp | 8 +- svf/lib/MemoryModel/PointerAnalysis.cpp | 11 +- svf/lib/MemoryModel/PointerAnalysisImpl.cpp | 2 +- svf/lib/SABER/SaberCondAllocator.cpp | 2 +- svf/lib/SABER/SrcSnkDDA.cpp | 8 +- svf/lib/SVFIR/SVFIR.cpp | 6 +- svf/lib/SVFIR/SVFValue.cpp | 60 +- svf/lib/Util/CDGBuilder.cpp | 5 +- svf/lib/Util/SVFStat.cpp | 2 +- svf/lib/Util/ThreadAPI.cpp | 4 +- svf/lib/WPA/FlowSensitive.cpp | 1 - svf/lib/WPA/WPAPass.cpp | 1 - 59 files changed, 1375 insertions(+), 1305 deletions(-) rename {svf/include/SVFIR => svf-llvm/include/SVF-LLVM}/SVFModule.h (84%) create mode 100644 svf-llvm/include/SVF-LLVM/SVFValue.h rename {svf/lib/SVFIR => svf-llvm/lib}/SVFModule.cpp (96%) create mode 100644 svf-llvm/lib/SVFValue.cpp create mode 100644 svf/include/Util/SVFLoopAndDomInfo.h diff --git a/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h b/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h index c02bd55fa..e049b54ce 100644 --- a/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h +++ b/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h @@ -15,7 +15,7 @@ #ifndef BREAKCONSTANTGEPS_H #define BREAKCONSTANTGEPS_H -#include "SVFIR/SVFValue.h" +#include "SVF-LLVM/SVFValue.h" namespace SVF { diff --git a/svf-llvm/include/SVF-LLVM/CppUtil.h b/svf-llvm/include/SVF-LLVM/CppUtil.h index f0ee9bbb9..488443147 100644 --- a/svf-llvm/include/SVF-LLVM/CppUtil.h +++ b/svf-llvm/include/SVF-LLVM/CppUtil.h @@ -30,7 +30,7 @@ #ifndef CPPUtil_H_ #define CPPUtil_H_ -#include "SVFIR/SVFValue.h" +#include "SVF-LLVM/SVFValue.h" #include "SVF-LLVM/BasicTypes.h" namespace SVF diff --git a/svf-llvm/include/SVF-LLVM/DCHG.h b/svf-llvm/include/SVF-LLVM/DCHG.h index a0c3c6b5d..6bc520625 100644 --- a/svf-llvm/include/SVF-LLVM/DCHG.h +++ b/svf-llvm/include/SVF-LLVM/DCHG.h @@ -17,7 +17,7 @@ #include "Graphs/GenericGraph.h" #include "Graphs/CHG.h" #include "SVF-LLVM/BasicTypes.h" -#include "SVFIR/SVFModule.h" +#include "SVF-LLVM/SVFModule.h" #include "Util/SVFUtil.h" #include "Util/WorkList.h" diff --git a/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h b/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h index 21a5984b3..5b917def8 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h +++ b/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h @@ -47,7 +47,7 @@ class LLVMLoopAnalysis virtual ~LLVMLoopAnalysis() = default; /// Build llvm loops based on LoopInfo analysis - virtual void buildLLVMLoops(SVFModule *mod, ICFG* icfg); + virtual void buildLLVMLoops(ICFG* icfg); /// Start from here virtual void build(ICFG *icfg); diff --git a/svf-llvm/include/SVF-LLVM/LLVMModule.h b/svf-llvm/include/SVF-LLVM/LLVMModule.h index e96d576d7..1c5e78815 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMModule.h +++ b/svf-llvm/include/SVF-LLVM/LLVMModule.h @@ -31,8 +31,8 @@ #define INCLUDE_SVF_FE_LLVMMODULE_H_ #include "SVF-LLVM/BasicTypes.h" -#include "SVFIR/SVFValue.h" -#include "SVFIR/SVFModule.h" +#include "SVF-LLVM/SVFValue.h" +#include "SVF-LLVM/SVFModule.h" #include "Util/Options.h" #include "Graphs/BasicBlockG.h" diff --git a/svf-llvm/include/SVF-LLVM/LLVMUtil.h b/svf-llvm/include/SVF-LLVM/LLVMUtil.h index 909115a62..62f679b7c 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMUtil.h +++ b/svf-llvm/include/SVF-LLVM/LLVMUtil.h @@ -32,7 +32,7 @@ #include "Util/SVFUtil.h" #include "SVF-LLVM/BasicTypes.h" -#include "SVFIR/SVFValue.h" +#include "SVF-LLVM/SVFValue.h" #include "Util/ThreadAPI.h" namespace SVF diff --git a/svf-llvm/include/SVF-LLVM/ObjTypeInference.h b/svf-llvm/include/SVF-LLVM/ObjTypeInference.h index 4aa64ae35..9cb623091 100644 --- a/svf-llvm/include/SVF-LLVM/ObjTypeInference.h +++ b/svf-llvm/include/SVF-LLVM/ObjTypeInference.h @@ -32,7 +32,7 @@ #include "Util/SVFUtil.h" #include "SVF-LLVM/BasicTypes.h" -#include "SVFIR/SVFValue.h" +#include "SVF-LLVM/SVFValue.h" #include "Util/ThreadAPI.h" namespace SVF diff --git a/svf/include/SVFIR/SVFModule.h b/svf-llvm/include/SVF-LLVM/SVFModule.h similarity index 84% rename from svf/include/SVFIR/SVFModule.h rename to svf-llvm/include/SVF-LLVM/SVFModule.h index c4735cb19..98803bae7 100644 --- a/svf/include/SVFIR/SVFModule.h +++ b/svf-llvm/include/SVF-LLVM/SVFModule.h @@ -30,7 +30,7 @@ #ifndef INCLUDE_SVFMODULE_H_ #define INCLUDE_SVFMODULE_H_ -#include "SVFIR/SVFValue.h" +#include "SVF-LLVM/SVFValue.h" #include "Util/NodeIDAllocator.h" #include "Util/ThreadAPI.h" @@ -63,8 +63,6 @@ class SVFModule private: static SVFModule* svfModule; - static std::string pagReadFromTxt; - std::string moduleIdentifier; FunctionSetType FunctionSet; ///< The Functions in the module GlobalSetType GlobalSet; ///< The Global Variables in the module AliasSetType AliasSet; ///< The Aliases in the module @@ -80,25 +78,6 @@ class SVFModule ~SVFModule(); - static inline void setPagFromTXT(const std::string& txt) - { - pagReadFromTxt = txt; - } - - inline void setModuleIdentifier(const std::string& moduleIdentifier) - { - this->moduleIdentifier = moduleIdentifier; - } - - static inline std::string pagFileName() - { - return pagReadFromTxt; - } - - static inline bool pagReadFromTXT() - { - return !pagReadFromTxt.empty(); - } const SVFFunction* getSVFFunction(const std::string& name); @@ -182,20 +161,6 @@ class SVFModule } ///@} - const std::string& getModuleIdentifier() const - { - if (pagReadFromTxt.empty()) - { - assert(!moduleIdentifier.empty() && - "No module found! Reading from a file other than LLVM-IR?"); - return moduleIdentifier; - } - else - { - return pagReadFromTxt; - } - } - inline const FunctionSetType& getFunctionSet() const { return FunctionSet; diff --git a/svf-llvm/include/SVF-LLVM/SVFValue.h b/svf-llvm/include/SVF-LLVM/SVFValue.h new file mode 100644 index 000000000..7a41fc56c --- /dev/null +++ b/svf-llvm/include/SVF-LLVM/SVFValue.h @@ -0,0 +1,805 @@ +//===- BasicTypes.h -- Basic types used in SVF-------------------------------// +// +// SVF: Static Value-Flow Analysis +// +// Copyright (C) <2013-2017> +// + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//===----------------------------------------------------------------------===// + +/* + * BasicTypes.h + * + * Created on: Apr 1, 2014 + * Author: Yulei Sui + */ + +#ifndef INCLUDE_SVFLLVM_SVFVALUE_H_ +#define INCLUDE_SVFLLVM_SVFVALUE_H_ + +#include "SVFIR/SVFType.h" +#include "Graphs/GraphPrinter.h" +#include "Util/Casting.h" +#include "Graphs/BasicBlockG.h" +#include "SVFIR/SVFValue.h" +#include "Util/SVFLoopAndDomInfo.h" + +namespace SVF +{ + +/// LLVM Aliases and constants +typedef SVF::GraphPrinter GraphPrinter; + +class CallGraphNode; +class SVFInstruction; +class SVFBasicBlock; +class SVFArgument; +class SVFFunction; +class SVFType; + +class SVFValue +{ + friend class SVFIRWriter; + friend class SVFIRReader; + friend class LLVMModuleSet; + +public: + typedef s64_t GNodeK; + + enum SVFValKind + { + SVFVal, + SVFFunc, + SVFBB, + SVFInst, + SVFCall, + SVFVCall, + SVFGlob, + SVFArg, + SVFConst, + SVFConstData, + SVFConstInt, + SVFConstFP, + SVFNullPtr, + SVFBlackHole, + SVFMetaAsValue, + SVFOther + }; + +private: + GNodeK kind; ///< used for classof + bool ptrInUncalledFun; ///< true if this pointer is in an uncalled function + bool constDataOrAggData; ///< true if this value is a ConstantData (e.g., numbers, string, floats) or a constantAggregate + +protected: + const SVFType* type; ///< Type of this SVFValue + std::string name; ///< Short name of value for printing & debugging + std::string sourceLoc; ///< Source code information of this value + /// Constructor without name + SVFValue(const SVFType* ty, SVFValKind k) + : kind(k), ptrInUncalledFun(false), + constDataOrAggData(SVFConstData == k), type(ty), sourceLoc("NoLoc") + { + } + + ///@{ attributes to be set only through Module builders e.g., + /// LLVMModule + inline void setConstDataOrAggData() + { + constDataOrAggData = true; + } + inline void setPtrInUncalledFunction() + { + ptrInUncalledFun = true; + } + ///@} +public: + SVFValue() = delete; + virtual ~SVFValue() = default; + + /// Get the type of this SVFValue + inline GNodeK getKind() const + { + return kind; + } + + inline const std::string &getName() const + { + return name; + } + + inline void setName(std::string&& n) + { + name = std::move(n); + } + + inline virtual const SVFType* getType() const + { + return type; + } + inline bool isConstDataOrAggData() const + { + return constDataOrAggData; + } + inline bool ptrInUncalledFunction() const + { + return ptrInUncalledFun; + } + inline bool isblackHole() const + { + return getKind() == SVFBlackHole;; + } + inline bool isNullPtr() const + { + return getKind() == SVFNullPtr; + } + inline virtual void setSourceLoc(const std::string& sourceCodeInfo) + { + sourceLoc = sourceCodeInfo; + } + inline virtual const std::string getSourceLoc() const + { + return sourceLoc; + } + + /// Needs to be implemented by a SVF front end + std::string toString() const; + + /// Overloading operator << for dumping ICFG node ID + //@{ + friend OutStream& operator<<(OutStream &os, const SVFValue &value) + { + return os << value.toString(); + } + //@} +}; + +class ArgValVar; + +class SVFFunction : public SVFValue +{ + friend class LLVMModuleSet; + friend class SVFIRWriter; + friend class SVFIRReader; + friend class SVFIRBuilder; + +public: + typename BasicBlockGraph::IDToNodeMapTy::iterator iterator; + typedef BasicBlockGraph::IDToNodeMapTy::const_iterator const_iterator; + typedef SVFLoopAndDomInfo::BBSet BBSet; + typedef SVFLoopAndDomInfo::BBList BBList; + typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; + +private: + bool isDecl; /// return true if this function does not have a body + bool intrinsic; /// return true if this function is an intrinsic function (e.g., llvm.dbg), which does not reside in the application code + bool addrTaken; /// return true if this function is address-taken (for indirect call purposes) + bool isUncalled; /// return true if this function is never called + bool isNotRet; /// return true if this function never returns + bool varArg; /// return true if this function supports variable arguments + const SVFFunctionType* funcType; /// FunctionType, which is different from the type (PointerType) of this SVFFunction + SVFLoopAndDomInfo* loopAndDom; /// the loop and dominate information + const SVFFunction* realDefFun; /// the definition of a function across multiple modules + std::vector allArgs; /// all formal arguments of this function + SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function + BasicBlockGraph* bbGraph; /// the basic block graph of this function + +protected: + + inline void addArgument(const ArgValVar* arg) + { + allArgs.push_back(arg); + } + + inline void setIsUncalledFunction(bool uncalledFunction) + { + isUncalled = uncalledFunction; + } + + inline void setIsNotRet(bool notRet) + { + isNotRet = notRet; + } + + inline void setDefFunForMultipleModule(const SVFFunction* deffun) + { + realDefFun = deffun; + } + /// @} + +public: + SVFFunction(const SVFType* ty,const SVFFunctionType* ft, bool declare, bool intrinsic, bool addrTaken, bool varg, SVFLoopAndDomInfo* ld); + SVFFunction(void) = delete; + virtual ~SVFFunction(); + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFFunc; + } + + inline SVFLoopAndDomInfo* getLoopAndDomInfo() + { + return loopAndDom; + } + inline bool isDeclaration() const + { + return isDecl; + } + + void setBasicBlockGraph(BasicBlockGraph* graph) + { + this->bbGraph = graph; + } + + BasicBlockGraph* getBasicBlockGraph() + { + return bbGraph; + } + + const BasicBlockGraph* getBasicBlockGraph() const + { + return bbGraph; + } + + inline bool isIntrinsic() const + { + return intrinsic; + } + + inline bool hasAddressTaken() const + { + return addrTaken; + } + + /// Returns the FunctionType + inline const SVFFunctionType* getFunctionType() const + { + return funcType; + } + + /// Returns the FunctionType + inline const SVFType* getReturnType() const + { + return funcType->getReturnType(); + } + + inline const SVFFunction* getDefFunForMultipleModule() const + { + if(realDefFun==nullptr) + return this; + return realDefFun; + } + + u32_t arg_size() const; + const ArgValVar* getArg(u32_t idx) const; + bool isVarArg() const; + + inline bool hasBasicBlock() const + { + return bbGraph && bbGraph->begin() != bbGraph->end(); + } + + inline const SVFBasicBlock* getEntryBlock() const + { + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + assert(bbGraph->begin()->second->getInEdges().size() == 0 && "the first basic block is not entry block"); + return bbGraph->begin()->second; + } + + /// Carefully! when you call getExitBB, you need ensure the function has return instruction + /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 + const SVFBasicBlock* getExitBB() const; + + void setExitBlock(SVFBasicBlock *bb); + + inline const SVFBasicBlock* front() const + { + return getEntryBlock(); + } + + inline const SVFBasicBlock* back() const + { + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + /// Carefully! 'back' is just the last basic block of function, + /// but not necessarily a exit basic block + /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 + return std::prev(bbGraph->end())->second; + } + + inline const_iterator begin() const + { + return bbGraph->begin(); + } + + inline const_iterator end() const + { + return bbGraph->end(); + } + + + inline const std::vector& getReachableBBs() const + { + return loopAndDom->getReachableBBs(); + } + + inline bool isUncalledFunction() const + { + return isUncalled; + } + + inline bool hasReturn() const + { + return !isNotRet; + } + + inline void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const + { + return loopAndDom->getExitBlocksOfLoop(bb,exitbbs); + } + + inline bool hasLoopInfo(const SVFBasicBlock* bb) const + { + return loopAndDom->hasLoopInfo(bb); + } + + const LoopBBs& getLoopInfo(const SVFBasicBlock* bb) const + { + return loopAndDom->getLoopInfo(bb); + } + + inline const SVFBasicBlock* getLoopHeader(const BBList& lp) const + { + return loopAndDom->getLoopHeader(lp); + } + + inline bool loopContainsBB(const BBList& lp, const SVFBasicBlock* bb) const + { + return loopAndDom->loopContainsBB(lp,bb); + } + + inline const Map& getDomTreeMap() const + { + return loopAndDom->getDomTreeMap(); + } + + inline const Map& getDomFrontierMap() const + { + return loopAndDom->getDomFrontierMap(); + } + + inline bool isLoopHeader(const SVFBasicBlock* bb) const + { + return loopAndDom->isLoopHeader(bb); + } + + inline bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const + { + return loopAndDom->dominate(bbKey,bbValue); + } + + inline bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const + { + return loopAndDom->postDominate(bbKey,bbValue); + } +}; + +class ICFGNode; +class FunObjVar; + +class SVFInstruction : public SVFValue +{ + friend class SVFIRWriter; + friend class SVFIRReader; + +private: + const SVFBasicBlock* bb; /// The BasicBlock where this Instruction resides + bool terminator; /// return true if this is a terminator instruction + bool ret; /// return true if this is an return instruction of a function + +public: + /// Constructor without name, set name with setName() + SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, bool tm, + bool isRet, SVFValKind k = SVFInst); + SVFInstruction(void) = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFInst || + node->getKind() == SVFCall || + node->getKind() == SVFVCall; + } + + inline const SVFBasicBlock* getParent() const + { + return bb; + } + + inline const FunObjVar* getFunction() const + { + return bb->getParent(); + } + + inline bool isRetInst() const + { + return ret; + } +}; + +class SVFCallInst : public SVFInstruction +{ + friend class SVFIRWriter; + friend class SVFIRReader; + friend class LLVMModuleSet; + friend class SVFIRBuilder; + +private: + std::vector args; + bool varArg; + const SVFValue* calledVal; + +protected: + ///@{ attributes to be set only through Module builders e.g., LLVMModule + inline void addArgument(const SVFValue* a) + { + args.push_back(a); + } + inline void setCalledOperand(const SVFValue* v) + { + calledVal = v; + } + /// @} + +public: + SVFCallInst(const SVFType* ty, const SVFBasicBlock* b, bool va, bool tm, SVFValKind k = SVFCall) : + SVFInstruction(ty, b, tm, false, k), varArg(va), calledVal(nullptr) + { + } + SVFCallInst(void) = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFCall || node->getKind() == SVFVCall; + } + static inline bool classof(const SVFInstruction *node) + { + return node->getKind() == SVFCall || node->getKind() == SVFVCall; + } + inline u32_t arg_size() const + { + return args.size(); + } + inline bool arg_empty() const + { + return args.empty(); + } + inline const SVFValue* getArgOperand(u32_t i) const + { + assert(i < arg_size() && "out of bound access of the argument"); + return args[i]; + } + inline u32_t getNumArgOperands() const + { + return arg_size(); + } + inline const SVFValue* getCalledOperand() const + { + return calledVal; + } + inline bool isVarArg() const + { + return varArg; + } + inline const SVFFunction* getCalledFunction() const + { + return SVFUtil::dyn_cast(calledVal); + } + inline const FunObjVar* getCaller() const + { + return getFunction(); + } +}; + +class SVFConstant : public SVFValue +{ + friend class SVFIRWriter; + friend class SVFIRReader; +public: + SVFConstant(const SVFType* ty, SVFValKind k = SVFConst): SVFValue(ty, k) + { + } + SVFConstant() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFConst || + node->getKind() == SVFGlob || + node->getKind() == SVFConstData || + node->getKind() == SVFConstInt || + node->getKind() == SVFConstFP || + node->getKind() == SVFNullPtr || + node->getKind() == SVFBlackHole; + } + +}; + +class SVFGlobalValue : public SVFConstant +{ + friend class SVFIRWriter; + friend class SVFIRReader; + friend class LLVMModuleSet; + +private: + const SVFValue* realDefGlobal; /// the definition of a function across multiple modules + +protected: + inline void setDefGlobalForMultipleModule(const SVFValue* defg) + { + realDefGlobal = defg; + } + +public: + SVFGlobalValue(const SVFType* ty): SVFConstant(ty, SVFValue::SVFGlob), realDefGlobal(nullptr) + { + } + SVFGlobalValue(std::string&& name, const SVFType* ty) : SVFGlobalValue(ty) + { + setName(std::move(name)); + } + SVFGlobalValue() = delete; + + inline const SVFValue* getDefGlobalForMultipleModule() const + { + if(realDefGlobal==nullptr) + return this; + return realDefGlobal; + } + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFGlob; + } + static inline bool classof(const SVFConstant *node) + { + return node->getKind() == SVFGlob; + } +}; + +class SVFArgument : public SVFValue +{ + friend class SVFIRWriter; + friend class SVFIRReader; +private: + const SVFFunction* fun; + u32_t argNo; + bool uncalled; +public: + SVFArgument(const SVFType* ty, const SVFFunction* fun, u32_t argNo, + bool uncalled) + : SVFValue(ty, SVFValue::SVFArg), fun(fun), argNo(argNo), + uncalled(uncalled) + { + } + SVFArgument() = delete; + + inline const SVFFunction* getParent() const + { + return fun; + } + + /// Return the index of this formal argument in its containing function. + /// For example in "void foo(int a, float b)" a is 0 and b is 1. + inline u32_t getArgNo() const + { + return argNo; + } + + inline bool isArgOfUncalledFunction() const + { + return uncalled; + } + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFArg; + } +}; + +class SVFConstantData : public SVFConstant +{ + friend class SVFIRWriter; + friend class SVFIRReader; +public: + SVFConstantData(const SVFType* ty, SVFValKind k = SVFConstData) + : SVFConstant(ty, k) + { + } + SVFConstantData() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFConstData || + node->getKind() == SVFConstInt || + node->getKind() == SVFConstFP || + node->getKind() == SVFNullPtr || + node->getKind() == SVFBlackHole; + } + static inline bool classof(const SVFConstantData *node) + { + return node->getKind() == SVFConstData || + node->getKind() == SVFConstInt || + node->getKind() == SVFConstFP || + node->getKind() == SVFNullPtr || + node->getKind() == SVFBlackHole; + } +}; + +class SVFConstantInt : public SVFConstantData +{ + friend class SVFIRWriter; + friend class SVFIRReader; +private: + u64_t zval; + s64_t sval; +public: + SVFConstantInt(const SVFType* ty, u64_t z, s64_t s) + : SVFConstantData(ty, SVFValue::SVFConstInt), zval(z), sval(s) + { + } + SVFConstantInt() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFConstInt; + } + static inline bool classof(const SVFConstantData *node) + { + return node->getKind() == SVFConstInt; + } + // Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate for the type of this constant. + inline u64_t getZExtValue () const + { + return zval; + } + // Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the type of this constant + inline s64_t getSExtValue () const + { + return sval; + } +}; + +class SVFConstantFP : public SVFConstantData +{ + friend class SVFIRWriter; + friend class SVFIRReader; +private: + float dval; +public: + SVFConstantFP(const SVFType* ty, double d) + : SVFConstantData(ty, SVFValue::SVFConstFP), dval(d) + { + } + SVFConstantFP() = delete; + + inline double getFPValue () const + { + return dval; + } + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFConstFP; + } + static inline bool classof(const SVFConstantData *node) + { + return node->getKind() == SVFConstFP; + } +}; + +class SVFConstantNullPtr : public SVFConstantData +{ + friend class SVFIRWriter; + friend class SVFIRReader; + +public: + SVFConstantNullPtr(const SVFType* ty) + : SVFConstantData(ty, SVFValue::SVFNullPtr) + { + } + SVFConstantNullPtr() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFNullPtr; + } + static inline bool classof(const SVFConstantData *node) + { + return node->getKind() == SVFNullPtr; + } +}; + +class SVFBlackHoleValue : public SVFConstantData +{ + friend class SVFIRWriter; + friend class SVFIRReader; + +public: + SVFBlackHoleValue(const SVFType* ty) + : SVFConstantData(ty, SVFValue::SVFBlackHole) + { + } + SVFBlackHoleValue() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFBlackHole; + } + static inline bool classof(const SVFConstantData *node) + { + return node->getKind() == SVFBlackHole; + } +}; + +class SVFOtherValue : public SVFValue +{ + friend class SVFIRWriter; + friend class SVFIRReader; +public: + SVFOtherValue(const SVFType* ty, SVFValKind k = SVFValue::SVFOther) + : SVFValue(ty, k) + { + } + SVFOtherValue() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFOther || node->getKind() == SVFMetaAsValue; + } +}; + +/* + * This class is only for LLVM's MetadataAsValue +*/ +class SVFMetadataAsValue : public SVFOtherValue +{ + friend class SVFIRWriter; + friend class SVFIRReader; +public: + SVFMetadataAsValue(const SVFType* ty) + : SVFOtherValue(ty, SVFValue::SVFMetaAsValue) + { + } + SVFMetadataAsValue() = delete; + + static inline bool classof(const SVFValue *node) + { + return node->getKind() == SVFMetaAsValue; + } + static inline bool classof(const SVFOtherValue *node) + { + return node->getKind() == SVFMetaAsValue; + } +}; + + +/// [FOR DEBUG ONLY, DON'T USE IT UNSIDE `svf`!] +/// Converts an SVFValue to corresponding LLVM::Value, then get the string +/// representation of it. Use it only when you are debugging. Don't use +/// it in any SVF algorithm because it relies on information stored in LLVM bc. +std::string dumpLLVMValue(const SVFValue* svfValue); + + + +} // End namespace SVF + +#endif /* INCLUDE_SVFLLVM_SVFVALUE_H_ */ diff --git a/svf-llvm/lib/CHGBuilder.cpp b/svf-llvm/lib/CHGBuilder.cpp index 2434630eb..95d5d92a2 100644 --- a/svf-llvm/lib/CHGBuilder.cpp +++ b/svf-llvm/lib/CHGBuilder.cpp @@ -42,7 +42,7 @@ #include "SVFIR/ObjTypeInfo.h" #include "Util/SVFUtil.h" #include "SVF-LLVM/LLVMUtil.h" -#include "SVFIR/SVFModule.h" +#include "SVF-LLVM/SVFModule.h" #include "Util/PTAStat.h" #include "SVF-LLVM/LLVMModule.h" #include "SVF-LLVM/ObjTypeInference.h" diff --git a/svf-llvm/lib/LLVMLoopAnalysis.cpp b/svf-llvm/lib/LLVMLoopAnalysis.cpp index c909cf40b..bcd5f54bb 100644 --- a/svf-llvm/lib/LLVMLoopAnalysis.cpp +++ b/svf-llvm/lib/LLVMLoopAnalysis.cpp @@ -46,7 +46,7 @@ using namespace SVFUtil; * @param mod SVF module * @param llvmLoops output llvm loops */ -void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg) +void LLVMLoopAnalysis::buildLLVMLoops(ICFG* icfg) { std::vector loop_stack; for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) @@ -89,7 +89,7 @@ void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg) void LLVMLoopAnalysis::build(ICFG *icfg) { std::vector llvmLoops; - buildLLVMLoops(PAG::getPAG()->getModule(), icfg); + buildLLVMLoops(icfg); } /*! diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index ee9c5bc8e..70c0ede35 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -29,7 +29,7 @@ #include #include -#include "SVFIR/SVFModule.h" +#include "SVF-LLVM/SVFModule.h" #include "Util/SVFUtil.h" #include "SVF-LLVM/BasicTypes.h" #include "SVF-LLVM/LLVMUtil.h" @@ -98,6 +98,9 @@ LLVMModuleSet::~LLVMModuleSet() } delete typeInference; typeInference = nullptr; + + SVFModule::releaseSVFModule(); + svfModule = nullptr; } ObjTypeInference* LLVMModuleSet::getTypeInference() @@ -119,7 +122,7 @@ SVFModule* LLVMModuleSet::buildSVFModule(Module &mod) LLVMModuleSet* mset = getLLVMModuleSet(); double startSVFModuleTime = SVFStat::getClk(true); - SVFModule::getSVFModule()->setModuleIdentifier(mod.getModuleIdentifier()); + PAG::getPAG()->setModuleIdentifier(mod.getModuleIdentifier()); mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()` mset->loadExtAPIModules(); // Uses context from module through `this->getContext()` mset->build(); @@ -142,7 +145,7 @@ SVFModule* LLVMModuleSet::buildSVFModule(const std::vector &moduleN if (!moduleNameVec.empty()) { - SVFModule::getSVFModule()->setModuleIdentifier(moduleNameVec.front()); + PAG::getPAG()->setModuleIdentifier(moduleNameVec.front()); } mset->build(); @@ -159,7 +162,7 @@ SVFModule* LLVMModuleSet::buildSVFModule(const std::vector &moduleN void LLVMModuleSet::buildSymbolTable() const { double startSymInfoTime = SVFStat::getClk(true); - if (!SVFModule::pagReadFromTXT()) + if (!SVFIR::pagReadFromTXT()) { /// building symbol table DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n")); @@ -528,9 +531,9 @@ void LLVMModuleSet::loadModules(const std::vector &moduleNameVec) //assert(!moduleNameVec.empty() && "no LLVM bc file is found!"); } // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR - else - SVFModule::setPagFromTXT(Options::Graphtxt()); - + else { + SVFIR::setPagFromTXT(Options::Graphtxt()); + } // // LLVMContext objects separate global LLVM settings (from which e.g. types are // derived); multiple LLVMContext objects can coexist and each context can "own" diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 7748ce234..14da2ad0e 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -35,8 +35,8 @@ #include "SVF-LLVM/LLVMUtil.h" #include "SVF-LLVM/SymbolTableBuilder.h" #include "SVFIR/PAGBuilderFromFile.h" -#include "SVFIR/SVFModule.h" -#include "SVFIR/SVFValue.h" +#include "SVF-LLVM/SVFModule.h" +#include "SVF-LLVM/SVFValue.h" #include "Util/CallGraphBuilder.h" #include "Graphs/CallGraph.h" #include "Util/Options.h" @@ -57,13 +57,10 @@ SVFIR* SVFIRBuilder::build() DBOUT(DGENERAL, outs() << pasMsg("\t Building SVFIR ...\n")); - // Set SVFModule from SVFIRBuilder - pag->setModule(svfModule); - // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR - if (SVFModule::pagReadFromTXT()) + if (SVFIR::pagReadFromTXT()) { - PAGBuilderFromFile fileBuilder(SVFModule::pagFileName()); + PAGBuilderFromFile fileBuilder(SVFIR::pagFileName()); return fileBuilder.build(); } @@ -99,7 +96,7 @@ SVFIR* SVFIRBuilder::build() } pag->callGraph = callGraphBuilder.buildSVFIRCallGraph(funset); - CHGraph* chg = new CHGraph(pag->getModule()); + CHGraph* chg = new CHGraph(); CHGBuilder chgbuilder(chg); chgbuilder.buildCHG(); pag->setCHG(chg); @@ -1534,7 +1531,7 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const */ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) { - if (SVFModule::pagReadFromTXT()) + if (SVFIR::pagReadFromTXT()) return; assert(curVal && "current Val is nullptr?"); diff --git a/svf/lib/SVFIR/SVFModule.cpp b/svf-llvm/lib/SVFModule.cpp similarity index 96% rename from svf/lib/SVFIR/SVFModule.cpp rename to svf-llvm/lib/SVFModule.cpp index 3fcd0a573..776e9f6c5 100644 --- a/svf/lib/SVFIR/SVFModule.cpp +++ b/svf-llvm/lib/SVFModule.cpp @@ -21,7 +21,7 @@ //===----------------------------------------------------------------------===// -#include "SVFIR/SVFModule.h" +#include "SVF-LLVM/SVFModule.h" #include "SVFIR/ObjTypeInfo.h" #include "Util/SVFUtil.h" #include "Util/SVFStat.h" @@ -29,7 +29,6 @@ using namespace SVF; -std::string SVFModule::pagReadFromTxt = ""; SVFModule* SVFModule::svfModule = nullptr; SVFModule::~SVFModule() diff --git a/svf-llvm/lib/SVFValue.cpp b/svf-llvm/lib/SVFValue.cpp new file mode 100644 index 000000000..fbcd31757 --- /dev/null +++ b/svf-llvm/lib/SVFValue.cpp @@ -0,0 +1,71 @@ +#include "SVF-LLVM/SVFValue.h" +#include "Util/SVFUtil.h" +#include "Graphs/GenericGraph.h" + +using namespace SVF; +using namespace SVFUtil; + +SVFFunction::SVFFunction(const SVFType* ty, const SVFFunctionType* ft, + bool declare, bool intrinsic, bool adt, bool varg, + SVFLoopAndDomInfo* ld) + : SVFValue(ty, SVFValue::SVFFunc), isDecl(declare), intrinsic(intrinsic), + addrTaken(adt), isUncalled(false), isNotRet(false), varArg(varg), + funcType(ft), loopAndDom(ld), realDefFun(nullptr), exitBlock(nullptr) +{ +} + +SVFFunction::~SVFFunction() +{ + delete loopAndDom; + delete bbGraph; +} + +u32_t SVFFunction::arg_size() const +{ + return allArgs.size(); +} + +const ArgValVar* SVFFunction::getArg(u32_t idx) const +{ + assert (idx < allArgs.size() && "getArg() out of range!"); + return allArgs[idx]; +} + +bool SVFFunction::isVarArg() const +{ + return varArg; +} + +const SVFBasicBlock *SVFFunction::getExitBB() const +{ + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + assert(exitBlock && "must have an exitBlock"); + return exitBlock; +} + +void SVFFunction::setExitBlock(SVFBasicBlock *bb) +{ + assert(!exitBlock && "have already set exit Basicblock!"); + exitBlock = bb; +} + + +SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, + bool tm, bool isRet, SVFValKind k) + : SVFValue(ty, k), bb(b), terminator(tm), ret(isRet) +{ +} + +__attribute__((weak)) +std::string SVFValue::toString() const +{ + assert("SVFValue::toString should be implemented or supported by fronted" && false); + abort(); +} + +__attribute__((weak)) +const std::string SVFBaseNode::valueOnlyToString() const +{ + assert("SVFBaseNode::valueOnlyToString should be implemented or supported by fronted" && false); + abort(); +} \ No newline at end of file diff --git a/svf-llvm/lib/SymbolTableBuilder.cpp b/svf-llvm/lib/SymbolTableBuilder.cpp index 1f04798d8..3c1a0f63c 100644 --- a/svf-llvm/lib/SymbolTableBuilder.cpp +++ b/svf-llvm/lib/SymbolTableBuilder.cpp @@ -34,7 +34,7 @@ #include "SVF-LLVM/GEPTypeBridgeIterator.h" // include bridge_gep_iterator #include "SVF-LLVM/LLVMUtil.h" #include "SVF-LLVM/SymbolTableBuilder.h" -#include "SVFIR/SVFModule.h" +#include "SVF-LLVM/SVFModule.h" #include "Util/NodeIDAllocator.h" #include "Util/Options.h" #include "Util/SVFUtil.h" diff --git a/svf/include/DDA/DDAClient.h b/svf/include/DDA/DDAClient.h index bf44c36d8..fecfc5b47 100644 --- a/svf/include/DDA/DDAClient.h +++ b/svf/include/DDA/DDAClient.h @@ -48,11 +48,11 @@ namespace SVF class DDAClient { public: - DDAClient(SVFModule* mod) : pag(nullptr), module(mod), curPtr(0), solveAll(true) {} + DDAClient() : pag(nullptr), curPtr(0), solveAll(true) {} virtual ~DDAClient() {} - virtual inline void initialise(SVFModule*) {} + virtual inline void initialise() {} /// Collect candidate pointers for query. virtual inline OrderedNodeSet& collectCandidateQueries(SVFIR* p) @@ -91,16 +91,12 @@ class DDAClient userInput.insert(ptr); solveAll = false; } - /// Get LLVM module - inline SVFModule* getModule() const - { - return module; - } + virtual void answerQueries(PointerAnalysis* pta); virtual inline void performStat(PointerAnalysis*) {} - virtual inline void collectWPANum(SVFModule*) {} + virtual inline void collectWPANum() {} protected: void addCandidate(NodeID id) { @@ -109,7 +105,6 @@ class DDAClient } SVFIR* pag; ///< SVFIR graph used by current DDA analysis - SVFModule* module; ///< LLVM module NodeID curPtr; ///< current pointer being queried OrderedNodeSet candidateQueries; ///< store all candidate pointers to be queried @@ -128,7 +123,7 @@ class FunptrDDAClient : public DDAClient typedef OrderedMap VTablePtrToCallSiteMap; VTablePtrToCallSiteMap vtableToCallSiteMap; public: - FunptrDDAClient(SVFModule* module) : DDAClient(module) {} + FunptrDDAClient() : DDAClient() {} ~FunptrDDAClient() {} /// Only collect function pointers as query candidates. @@ -147,7 +142,7 @@ class AliasDDAClient : public DDAClient public: typedef OrderedSet PAGNodeSet; - AliasDDAClient(SVFModule* module) : DDAClient(module) {} + AliasDDAClient() : DDAClient() {} ~AliasDDAClient() {} /// Only collect function pointers as query candidates. diff --git a/svf/include/DDA/DDAPass.h b/svf/include/DDA/DDAPass.h index a97cb68dd..bd769fed4 100644 --- a/svf/include/DDA/DDAPass.h +++ b/svf/include/DDA/DDAPass.h @@ -69,7 +69,7 @@ class DDAPass virtual void runOnModule(SVFIR* module); /// Select a client - virtual void selectClient(SVFModule* module); + virtual void selectClient(); /// Pass name virtual inline std::string getPassName() const diff --git a/svf/include/Graphs/CHG.h b/svf/include/Graphs/CHG.h index 9d75501cd..ee9dce647 100644 --- a/svf/include/Graphs/CHG.h +++ b/svf/include/Graphs/CHG.h @@ -33,7 +33,7 @@ #ifndef CHA_H_ #define CHA_H_ -#include "SVFIR/SVFModule.h" +#include "Util/ThreadAPI.h" #include "Graphs/GenericGraph.h" #include "Util/WorkList.h" @@ -252,7 +252,7 @@ class CHGraph: public CommonCHGraph, public GenericCHGraphTy DESTRUCTOR = 0x2 // connect node based on destructor } RELATIONTYPE; - CHGraph(SVFModule* svfModule): svfMod(svfModule), classNum(0), vfID(0), buildingCHGTime(0) + CHGraph(): classNum(0), vfID(0), buildingCHGTime(0) { this->kind = Standard; } @@ -318,7 +318,6 @@ class CHGraph: public CommonCHGraph, public GenericCHGraphTy private: - SVFModule* svfMod; u32_t classNum; u32_t vfID; double buildingCHGTime; diff --git a/svf/include/Graphs/GenericGraph.h b/svf/include/Graphs/GenericGraph.h index 8639d6927..6c856bd5b 100644 --- a/svf/include/Graphs/GenericGraph.h +++ b/svf/include/Graphs/GenericGraph.h @@ -33,6 +33,7 @@ #include "SVFIR/SVFType.h" #include "Util/iterator.h" #include "Graphs/GraphTraits.h" +#include "SVFIR/SVFValue.h" namespace SVF { @@ -134,292 +135,6 @@ class GenericEdge }; -class SVFBaseNode -{ - -public: - - enum GNodeK - { - // ┌─────────────────────────────────────────────────────────────────────────┐ - // │ ICFGNode: Classes of inter-procedural and intra-procedural control flow │ - // │ graph nodes (Parent class: ICFGNode) │ - // └─────────────────────────────────────────────────────────────────────────┘ - IntraBlock, // ├── Represents a node within a single procedure - GlobalBlock, // ├── Represents a global-level block - // │ └─ Subclass: InterICFGNode - FunEntryBlock, // │ ├── Entry point of a function - FunExitBlock, // │ ├── Exit point of a function - FunCallBlock, // │ ├── Call site in the function - FunRetBlock, // │ └── Return site in the function - - // ┌─────────────────────────────────────────────────────────────────────────┐ - // │ SVFVar: Classes of variable nodes (Parent class: SVFVar) │ - // │ Includes two main subclasses: ValVar and ObjVar │ - // └─────────────────────────────────────────────────────────────────────────┘ - // └─ Subclass: ValVar (Top-level variable nodes) - ValNode, // ├── Represents a standard value variable - ArgValNode, // ├── Represents an argument value variable - FunValNode, // ├── Represents a function value variable - GepValNode, // ├── Represents a GEP value variable - RetValNode, // ├── Represents a return value node - VarargValNode, // ├── Represents a variadic argument node - GlobalValNode, // ├── Represents a global variable node - ConstAggValNode, // ├── Represents a constant aggregate value node - // │ └─ Subclass: ConstDataValVar - ConstDataValNode, // │ ├── Represents a constant data variable - BlackHoleValNode, // │ ├── Represents a black hole node - ConstFPValNode, // │ ├── Represents a constant floating-point value node - ConstIntValNode, // │ ├── Represents a constant integer value node - ConstNullptrValNode, // │ └── Represents a constant nullptr value node - // │ └─ Subclass: DummyValVar - DummyValNode, // │ └── Dummy node for uninitialized values - - // └─ Subclass: ObjVar (Object variable nodes) - ObjNode, // ├── Represents an object variable - // │ └─ Subclass: GepObjVar - GepObjNode, // │ ├── Represents a GEP object variable - // │ └─ Subclass: BaseObjVar - BaseObjNode, // │ ├── Represents a base object node - FunObjNode, // │ ├── Represents a function object - HeapObjNode, // │ ├── Represents a heap object - StackObjNode, // │ ├── Represents a stack object - GlobalObjNode, // │ ├── Represents a global object - ConstAggObjNode, // │ ├── Represents a constant aggregate object - // │ └─ Subclass: ConstDataObjVar - ConstDataObjNode, // │ ├── Represents a constant data object - ConstFPObjNode, // │ ├── Represents a constant floating-point object - ConstIntObjNode, // │ ├── Represents a constant integer object - ConstNullptrObjNode, // │ └── Represents a constant nullptr object - // │ └─ Subclass: DummyObjVar - DummyObjNode, // │ └── Dummy node for uninitialized objects - - // ┌─────────────────────────────────────────────────────────────────────────┐ - // │ VFGNode: Classes of Value Flow Graph (VFG) node kinds (Parent class: │ - // │ VFGNode) │ - // │ Includes operation nodes and specialized subclasses │ - // └─────────────────────────────────────────────────────────────────────────┘ - Cmp, // ├── Represents a comparison operation - BinaryOp, // ├── Represents a binary operation - UnaryOp, // ├── Represents a unary operation - Branch, // ├── Represents a branch operation - DummyVProp, // ├── Dummy node for value propagation - NPtr, // ├── Represents a null pointer operation - // │ └─ Subclass: ArgumentVFGNode - FRet, // │ ├── Represents a function return value - ARet, // │ ├── Represents an argument return value - AParm, // │ ├── Represents an argument parameter - FParm, // │ └── Represents a function parameter - // │ └─ Subclass: StmtVFGNode - Addr, // │ ├── Represents an address operation - Copy, // │ ├── Represents a copy operation - Gep, // │ ├── Represents a GEP operation - Store, // │ ├── Represents a store operation - Load, // │ └── Represents a load operation - // │ └─ Subclass: PHIVFGNode - TPhi, // │ ├── Represents a type-based PHI node - TIntraPhi, // │ ├── Represents an intra-procedural PHI node - TInterPhi, // │ └── Represents an inter-procedural PHI node - // │ └─ Subclass: MRSVFGNode - FPIN, // │ ├── Function parameter input - FPOUT, // │ ├── Function parameter output - APIN, // │ ├── Argument parameter input - APOUT, // │ └── Argument parameter output - // │ └─ Subclass: MSSAPHISVFGNode - MPhi, // │ ├── Memory PHI node - MIntraPhi, // │ ├── Intra-procedural memory PHI node - MInterPhi, // │ └── Inter-procedural memory PHI node - - // ┌─────────────────────────────────────────────────────────────────────────┐ - // │ Additional specific graph node types │ - // └─────────────────────────────────────────────────────────────────────────┘ - CallNodeKd, // Callgraph node - CDNodeKd, // Control dependence graph node - CFLNodeKd, // CFL graph node - CHNodeKd, // Class hierarchy graph node - ConstraintNodeKd, // Constraint graph node - TCTNodeKd, // Thread creation tree node - DCHNodeKd, // DCHG node - BasicBlockKd, // Basic block node - OtherKd // Other node kind - }; - - - SVFBaseNode(NodeID i, GNodeK k, const SVFType* ty = nullptr): id(i),nodeKind(k), type(ty) - { - - } - - /// Get ID - inline NodeID getId() const - { - return id; - } - - /// Get node kind - inline GNodeK getNodeKind() const - { - return nodeKind; - } - - virtual const SVFType* getType() const - { - return type; - } - - inline virtual void setName(const std::string& nameInfo) - { - name = nameInfo; - } - - inline virtual void setName(std::string&& nameInfo) - { - name = std::move(nameInfo); - } - - virtual const std::string& getName() const - { - return name; - } - - inline virtual void setSourceLoc(const std::string& sourceCodeInfo) - { - sourceLoc = sourceCodeInfo; - } - - virtual const std::string getSourceLoc() const - { - return sourceLoc; - } - - const std::string valueOnlyToString() const; - - -protected: - NodeID id; ///< Node ID - GNodeK nodeKind; ///< Node kind - const SVFType* type; ///< SVF type - - std::string name; - std::string sourceLoc; ///< Source code information of this value - - /// Helper functions to check node kinds - //{@ Check node kind - static inline bool isICFGNodeKinds(GNodeK n) - { - static_assert(FunRetBlock - IntraBlock == 5, - "the number of ICFGNodeKinds has changed, make sure " - "the range is correct"); - return n <= FunRetBlock && n >= IntraBlock; - } - - static inline bool isInterICFGNodeKind(GNodeK n) - { - static_assert(FunRetBlock - FunEntryBlock == 3, - "the number of InterICFGNodeKind has changed, make sure " - "the range is correct"); - return n <= FunRetBlock && n >= FunEntryBlock; - } - - static inline bool isSVFVarKind(GNodeK n) - { - static_assert(DummyObjNode - ValNode == 26, - "The number of SVFVarKinds has changed, make sure the " - "range is correct"); - - return n <= DummyObjNode && n >= ValNode; - } - - static inline bool isValVarKinds(GNodeK n) - { - static_assert(DummyValNode - ValNode == 13, - "The number of ValVarKinds has changed, make sure the " - "range is correct"); - return n <= DummyValNode && n >= ValNode; - } - - - static inline bool isConstantDataValVar(GNodeK n) - { - static_assert(ConstNullptrValNode - ConstDataValNode == 4, - "The number of ConstantDataValVarKinds has changed, make " - "sure the range is correct"); - return n <= ConstNullptrValNode && n >= ConstDataValNode; - } - - static inline bool isObjVarKinds(GNodeK n) - { - static_assert(DummyObjNode - ObjNode == 12, - "The number of ObjVarKinds has changed, make sure the " - "range is correct"); - return n <= DummyObjNode && n >= ObjNode; - } - - static inline bool isBaseObjVarKinds(GNodeK n) - { - static_assert(DummyObjNode - BaseObjNode == 10, - "The number of BaseObjVarKinds has changed, make sure the " - "range is correct"); - return n <= DummyObjNode && n >= BaseObjNode; - } - - static inline bool isConstantDataObjVarKinds(GNodeK n) - { - static_assert(ConstNullptrObjNode - ConstDataObjNode == 3, - "The number of ConstantDataObjVarKinds has changed, make " - "sure the range is correct"); - return n <= ConstNullptrObjNode && n >= ConstDataObjNode; - } - - static inline bool isVFGNodeKinds(GNodeK n) - { - static_assert(MInterPhi - Cmp == 24, - "The number of VFGNodeKinds has changed, make sure the " - "range is correct"); - return n <= MInterPhi && n >= Cmp; - } - - static inline bool isArgumentVFGNodeKinds(GNodeK n) - { - static_assert(FParm - FRet == 3, - "The number of ArgumentVFGNodeKinds has changed, make " - "sure the range is correct"); - return n <= FParm && n >= FRet; - } - - static inline bool isStmtVFGNodeKinds(GNodeK n) - { - static_assert(Load - Addr == 4, - "The number of StmtVFGNodeKinds has changed, make sure " - "the range is correct"); - return n <= Load && n >= Addr; - } - - static inline bool isPHIVFGNodeKinds(GNodeK n) - { - static_assert(TInterPhi - TPhi == 2, - "The number of PHIVFGNodeKinds has changed, make sure " - "the range is correct"); - return n <= TInterPhi && n >= TPhi; - } - - static inline bool isMRSVFGNodeKinds(GNodeK n) - { - static_assert(MInterPhi - FPIN == 6, - "The number of MRSVFGNodeKinds has changed, make sure " - "the range is correct"); - return n <= MInterPhi && n >= FPIN; - } - - static inline bool isMSSAPHISVFGNodeKinds(GNodeK n) - { - static_assert(MInterPhi - MPhi == 2, - "The number of MSSAPHISVFGNodeKinds has changed, make " - "sure the range is correct"); - return n <= MInterPhi && n >= MPhi; - } - //@} -}; /*! * Generic node on the graph as base class diff --git a/svf/include/MTA/MTA.h b/svf/include/MTA/MTA.h index 44242c907..19951db1f 100644 --- a/svf/include/MTA/MTA.h +++ b/svf/include/MTA/MTA.h @@ -67,11 +67,11 @@ class MTA /// We start the pass here virtual bool runOnModule(SVFIR* module); /// Compute MHP - virtual MHP* computeMHP(SVFModule* module); + virtual MHP* computeMHP(); /// Compute locksets virtual LockAnalysis* computeLocksets(TCT* tct); /// Perform detection - virtual void detect(SVFModule* module); + virtual void detect(); // Not implemented for now // void dump(Module &module, MHP *mhp, LockAnalysis *lsa); diff --git a/svf/include/MTA/TCT.h b/svf/include/MTA/TCT.h index bd01af93a..f42ddd501 100644 --- a/svf/include/MTA/TCT.h +++ b/svf/include/MTA/TCT.h @@ -186,12 +186,6 @@ class TCT: public GenericThreadCreateTreeTy destroy(); } - /// Get SVFFModule - SVFModule* getSVFModule() const - { - return pta->getModule(); - } - /// Get TCG inline ThreadCallGraph* getThreadCallGraph() const { diff --git a/svf/include/MemoryModel/PointerAnalysis.h b/svf/include/MemoryModel/PointerAnalysis.h index 4e587f73a..3243c5a75 100644 --- a/svf/include/MemoryModel/PointerAnalysis.h +++ b/svf/include/MemoryModel/PointerAnalysis.h @@ -139,8 +139,6 @@ class PointerAnalysis /// SVFIR static SVFIR* pag; - /// Module - SVFModule* svfMod; /// Pointer analysis Type PTATY ptaTy; /// PTA implementation type. @@ -206,11 +204,7 @@ class PointerAnalysis { return stat; } - /// Module - inline SVFModule* getModule() const - { - return svfMod; - } + /// Get all Valid Pointers for resolution inline OrderedNodeSet& getAllValidPtrs() { diff --git a/svf/include/SABER/DoubleFreeChecker.h b/svf/include/SABER/DoubleFreeChecker.h index 0f8de67dd..44d0bcc40 100644 --- a/svf/include/SABER/DoubleFreeChecker.h +++ b/svf/include/SABER/DoubleFreeChecker.h @@ -57,7 +57,7 @@ class DoubleFreeChecker : public LeakChecker virtual bool runOnModule(SVFIR* pag) override { /// start analysis - analyze(pag->getModule()); + analyze(); return false; } diff --git a/svf/include/SABER/FileChecker.h b/svf/include/SABER/FileChecker.h index 8b0ff642d..b4958e6dd 100644 --- a/svf/include/SABER/FileChecker.h +++ b/svf/include/SABER/FileChecker.h @@ -58,7 +58,7 @@ class FileChecker : public LeakChecker virtual bool runOnModule(SVFIR* pag) { /// start analysis - analyze(pag->getModule()); + analyze(); return false; } diff --git a/svf/include/SABER/LeakChecker.h b/svf/include/SABER/LeakChecker.h index 2d5957e3b..c40e125c2 100644 --- a/svf/include/SABER/LeakChecker.h +++ b/svf/include/SABER/LeakChecker.h @@ -68,7 +68,7 @@ class LeakChecker : public SrcSnkDDA virtual bool runOnModule(SVFIR* pag) { /// start analysis - analyze(pag->getModule()); + analyze(); return false; } diff --git a/svf/include/SABER/SaberCondAllocator.h b/svf/include/SABER/SaberCondAllocator.h index 5631f5ce7..94346ab1e 100644 --- a/svf/include/SABER/SaberCondAllocator.h +++ b/svf/include/SABER/SaberCondAllocator.h @@ -30,7 +30,6 @@ #ifndef PATHALLOCATOR_H_ #define PATHALLOCATOR_H_ -#include "SVFIR/SVFModule.h" #include "SVFIR/SVFValue.h" #include "Util/WorkList.h" #include "Graphs/SVFG.h" @@ -121,7 +120,7 @@ class SaberCondAllocator Condition newCond(const ICFGNode* inst); /// Perform path allocation - void allocate(const SVFModule* module); + void allocate(); /// Get/Set instruction based on Z3 expression id //{@ diff --git a/svf/include/SABER/SrcSnkDDA.h b/svf/include/SABER/SrcSnkDDA.h index 0ca00a1ad..f1f859808 100644 --- a/svf/include/SABER/SrcSnkDDA.h +++ b/svf/include/SABER/SrcSnkDDA.h @@ -105,10 +105,10 @@ class SrcSnkDDA : public CFLSrcSnkSolver } /// Start analysis here - virtual void analyze(SVFModule* module); + virtual void analyze(); /// Initialize analysis - virtual void initialize(SVFModule* module); + virtual void initialize(); /// Finalize analysis virtual void finalize() diff --git a/svf/include/SVFIR/ObjTypeInfo.h b/svf/include/SVFIR/ObjTypeInfo.h index af3958a7d..5e77c56cf 100644 --- a/svf/include/SVFIR/ObjTypeInfo.h +++ b/svf/include/SVFIR/ObjTypeInfo.h @@ -33,7 +33,6 @@ #include "Util/SVFUtil.h" #include "MemoryModel/AccessPath.h" -#include "SVFIR/SVFModule.h" namespace SVF { diff --git a/svf/include/SVFIR/SVFIR.h b/svf/include/SVFIR/SVFIR.h index a3f53e2b1..09ab52d2f 100644 --- a/svf/include/SVFIR/SVFIR.h +++ b/svf/include/SVFIR/SVFIR.h @@ -93,13 +93,15 @@ class SVFIR : public IRGraph /// Valid pointers for pointer analysis resolution connected by SVFIR edges (constraints) /// this set of candidate pointers can change during pointer resolution (e.g. adding new object nodes) OrderedNodeSet candidatePointers; - SVFModule* svfModule; /// SVF Module ICFG* icfg; // ICFG CommonCHGraph* chgraph; // class hierarchy graph CallSiteSet callSiteSet; /// all the callsites of a program CallGraph* callGraph; /// call graph static std::unique_ptr pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once. + static std::string pagReadFromTxt; + + std::string moduleIdentifier; /// Constructor SVFIR(bool buildFromFile); @@ -152,16 +154,7 @@ class SVFIR : public IRGraph /// Whether to handle blackhole edge static void handleBlackHole(bool b); //@} - /// Set/Get LLVM Module - inline void setModule(SVFModule* mod) - { - svfModule = mod; - } - inline SVFModule* getModule() - { - assert(svfModule && "empty SVFModule! Build SVF IR first!"); - return svfModule; - } + /// Set/Get ICFG inline void setICFG(ICFG* i) { @@ -196,6 +189,39 @@ class SVFIR : public IRGraph const FunObjVar* getFunObjVar(const std::string& name); + inline const std::string& getModuleIdentifier() const { + if (pagReadFromTxt.empty()) + { + assert(!moduleIdentifier.empty() && + "No module found! Reading from a file other than LLVM-IR?"); + return moduleIdentifier; + } + else + { + return pagReadFromTxt; + } + } + + static inline std::string pagFileName() + { + return pagReadFromTxt; + } + + static inline bool pagReadFromTXT() + { + return !pagReadFromTxt.empty(); + } + + static inline void setPagFromTXT(const std::string& txt) + { + pagReadFromTxt = txt; + } + + inline void setModuleIdentifier(const std::string& moduleIdentifier) + { + this->moduleIdentifier = moduleIdentifier; + } + /// Get/set methods to get SVFStmts based on their kinds and ICFGNodes //@{ /// Get edges set according to its kind diff --git a/svf/include/SVFIR/SVFStatements.h b/svf/include/SVFIR/SVFStatements.h index fc577e86d..98376978f 100644 --- a/svf/include/SVFIR/SVFStatements.h +++ b/svf/include/SVFIR/SVFStatements.h @@ -43,6 +43,7 @@ class IntraICFGNode; class CallICFGNode; class FunEntryICFGNode; class FunExitICFGNode; +class SVFBasicBlock; /* * SVFIR program statements (PAGEdges) diff --git a/svf/include/SVFIR/SVFValue.h b/svf/include/SVFIR/SVFValue.h index e287b6b9a..6e277c1b5 100644 --- a/svf/include/SVFIR/SVFValue.h +++ b/svf/include/SVFIR/SVFValue.h @@ -32,897 +32,299 @@ #include "SVFIR/SVFType.h" #include "Graphs/GraphPrinter.h" -#include "Util/Casting.h" -#include "Graphs/BasicBlockG.h" -namespace SVF -{ -/// LLVM Aliases and constants -typedef SVF::GraphPrinter GraphPrinter; +namespace SVF { -class CallGraphNode; -class SVFInstruction; -class SVFBasicBlock; -class SVFArgument; -class SVFFunction; -class SVFType; -class SVFLoopAndDomInfo +class SVFBaseNode { - friend class SVFIRWriter; - friend class SVFIRReader; -public: - typedef Set BBSet; - typedef std::vector BBList; - typedef BBList LoopBBs; - -private: - BBList reachableBBs; ///< reachable BasicBlocks from the function entry. - Map dtBBsMap; ///< map a BasicBlock to BasicBlocks it Dominates - Map pdtBBsMap; ///< map a BasicBlock to BasicBlocks it PostDominates - Map dfBBsMap; ///< map a BasicBlock to its Dominate Frontier BasicBlocks - Map bb2LoopMap; ///< map a BasicBlock (if it is in a loop) to all the BasicBlocks in this loop - Map bb2PdomLevel; ///< map a BasicBlock to its level in pdom tree, used in findNearestCommonPDominator - Map bb2PIdom; ///< map a BasicBlock to its immediate dominator in pdom tree, used in findNearestCommonPDominator public: - SVFLoopAndDomInfo() - { - } - - virtual ~SVFLoopAndDomInfo() {} - - inline const Map& getDomFrontierMap() const - { - return dfBBsMap; - } - - inline Map& getDomFrontierMap() - { - return dfBBsMap; - } - - inline bool hasLoopInfo(const SVFBasicBlock* bb) const - { - return bb2LoopMap.find(bb) != bb2LoopMap.end(); - } - - const LoopBBs& getLoopInfo(const SVFBasicBlock* bb) const; - - inline const SVFBasicBlock* getLoopHeader(const LoopBBs& lp) const - { - assert(!lp.empty() && "this is not a loop, empty basic block"); - return lp.front(); - } - - inline bool loopContainsBB(const LoopBBs& lp, const SVFBasicBlock* bb) const - { - return std::find(lp.begin(), lp.end(), bb) != lp.end(); - } - - inline void addToBB2LoopMap(const SVFBasicBlock* bb, const SVFBasicBlock* loopBB) - { - bb2LoopMap[bb].push_back(loopBB); - } - - inline const Map& getPostDomTreeMap() const - { - return pdtBBsMap; - } - - inline Map& getPostDomTreeMap() - { - return pdtBBsMap; - } - - inline const Map& getBBPDomLevel() const - { - return bb2PdomLevel; - } - - inline Map& getBBPDomLevel() - { - return bb2PdomLevel; - } - - inline const Map& getBB2PIdom() const - { - return bb2PIdom; - } - - inline Map& getBB2PIdom() - { - return bb2PIdom; - } + enum GNodeK + { + // ┌─────────────────────────────────────────────────────────────────────────┐ + // │ ICFGNode: Classes of inter-procedural and intra-procedural control flow │ + // │ graph nodes (Parent class: ICFGNode) │ + // └─────────────────────────────────────────────────────────────────────────┘ + IntraBlock, // ├── Represents a node within a single procedure + GlobalBlock, // ├── Represents a global-level block + // │ └─ Subclass: InterICFGNode + FunEntryBlock, // │ ├── Entry point of a function + FunExitBlock, // │ ├── Exit point of a function + FunCallBlock, // │ ├── Call site in the function + FunRetBlock, // │ └── Return site in the function + + // ┌─────────────────────────────────────────────────────────────────────────┐ + // │ SVFVar: Classes of variable nodes (Parent class: SVFVar) │ + // │ Includes two main subclasses: ValVar and ObjVar │ + // └─────────────────────────────────────────────────────────────────────────┘ + // └─ Subclass: ValVar (Top-level variable nodes) + ValNode, // ├── Represents a standard value variable + ArgValNode, // ├── Represents an argument value variable + FunValNode, // ├── Represents a function value variable + GepValNode, // ├── Represents a GEP value variable + RetValNode, // ├── Represents a return value node + VarargValNode, // ├── Represents a variadic argument node + GlobalValNode, // ├── Represents a global variable node + ConstAggValNode, // ├── Represents a constant aggregate value node + // │ └─ Subclass: ConstDataValVar + ConstDataValNode, // │ ├── Represents a constant data variable + BlackHoleValNode, // │ ├── Represents a black hole node + ConstFPValNode, // │ ├── Represents a constant floating-point value node + ConstIntValNode, // │ ├── Represents a constant integer value node + ConstNullptrValNode, // │ └── Represents a constant nullptr value node + // │ └─ Subclass: DummyValVar + DummyValNode, // │ └── Dummy node for uninitialized values + + // └─ Subclass: ObjVar (Object variable nodes) + ObjNode, // ├── Represents an object variable + // │ └─ Subclass: GepObjVar + GepObjNode, // │ ├── Represents a GEP object variable + // │ └─ Subclass: BaseObjVar + BaseObjNode, // │ ├── Represents a base object node + FunObjNode, // │ ├── Represents a function object + HeapObjNode, // │ ├── Represents a heap object + StackObjNode, // │ ├── Represents a stack object + GlobalObjNode, // │ ├── Represents a global object + ConstAggObjNode, // │ ├── Represents a constant aggregate object + // │ └─ Subclass: ConstDataObjVar + ConstDataObjNode, // │ ├── Represents a constant data object + ConstFPObjNode, // │ ├── Represents a constant floating-point object + ConstIntObjNode, // │ ├── Represents a constant integer object + ConstNullptrObjNode, // │ └── Represents a constant nullptr object + // │ └─ Subclass: DummyObjVar + DummyObjNode, // │ └── Dummy node for uninitialized objects + + // ┌─────────────────────────────────────────────────────────────────────────┐ + // │ VFGNode: Classes of Value Flow Graph (VFG) node kinds (Parent class: │ + // │ VFGNode) │ + // │ Includes operation nodes and specialized subclasses │ + // └─────────────────────────────────────────────────────────────────────────┘ + Cmp, // ├── Represents a comparison operation + BinaryOp, // ├── Represents a binary operation + UnaryOp, // ├── Represents a unary operation + Branch, // ├── Represents a branch operation + DummyVProp, // ├── Dummy node for value propagation + NPtr, // ├── Represents a null pointer operation + // │ └─ Subclass: ArgumentVFGNode + FRet, // │ ├── Represents a function return value + ARet, // │ ├── Represents an argument return value + AParm, // │ ├── Represents an argument parameter + FParm, // │ └── Represents a function parameter + // │ └─ Subclass: StmtVFGNode + Addr, // │ ├── Represents an address operation + Copy, // │ ├── Represents a copy operation + Gep, // │ ├── Represents a GEP operation + Store, // │ ├── Represents a store operation + Load, // │ └── Represents a load operation + // │ └─ Subclass: PHIVFGNode + TPhi, // │ ├── Represents a type-based PHI node + TIntraPhi, // │ ├── Represents an intra-procedural PHI node + TInterPhi, // │ └── Represents an inter-procedural PHI node + // │ └─ Subclass: MRSVFGNode + FPIN, // │ ├── Function parameter input + FPOUT, // │ ├── Function parameter output + APIN, // │ ├── Argument parameter input + APOUT, // │ └── Argument parameter output + // │ └─ Subclass: MSSAPHISVFGNode + MPhi, // │ ├── Memory PHI node + MIntraPhi, // │ ├── Intra-procedural memory PHI node + MInterPhi, // │ └── Inter-procedural memory PHI node + + // ┌─────────────────────────────────────────────────────────────────────────┐ + // │ Additional specific graph node types │ + // └─────────────────────────────────────────────────────────────────────────┘ + CallNodeKd, // Callgraph node + CDNodeKd, // Control dependence graph node + CFLNodeKd, // CFL graph node + CHNodeKd, // Class hierarchy graph node + ConstraintNodeKd, // Constraint graph node + TCTNodeKd, // Thread creation tree node + DCHNodeKd, // DCHG node + BasicBlockKd, // Basic block node + OtherKd // Other node kind + }; - inline Map& getDomTreeMap() - { - return dtBBsMap; - } - inline const Map& getDomTreeMap() const + SVFBaseNode(NodeID i, GNodeK k, const SVFType* ty = nullptr): id(i),nodeKind(k), type(ty) { - return dtBBsMap; - } - inline bool isUnreachable(const SVFBasicBlock* bb) const - { - return std::find(reachableBBs.begin(), reachableBBs.end(), bb) == - reachableBBs.end(); } - inline const BBList& getReachableBBs() const + /// Get ID + inline NodeID getId() const { - return reachableBBs; + return id; } - inline void setReachableBBs(BBList& bbs) + /// Get node kind + inline GNodeK getNodeKind() const { - reachableBBs = bbs; + return nodeKind; } - void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const; - - bool isLoopHeader(const SVFBasicBlock* bb) const; - - bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const; - - bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const; - - /// find nearest common post dominator of two basic blocks - const SVFBasicBlock *findNearestCommonPDominator(const SVFBasicBlock *A, const SVFBasicBlock *B) const; -}; - -class SVFValue -{ - friend class SVFIRWriter; - friend class SVFIRReader; - friend class LLVMModuleSet; - -public: - typedef s64_t GNodeK; - - enum SVFValKind - { - SVFVal, - SVFFunc, - SVFBB, - SVFInst, - SVFCall, - SVFVCall, - SVFGlob, - SVFArg, - SVFConst, - SVFConstData, - SVFConstInt, - SVFConstFP, - SVFNullPtr, - SVFBlackHole, - SVFMetaAsValue, - SVFOther - }; - -private: - GNodeK kind; ///< used for classof - bool ptrInUncalledFun; ///< true if this pointer is in an uncalled function - bool constDataOrAggData; ///< true if this value is a ConstantData (e.g., numbers, string, floats) or a constantAggregate - -protected: - const SVFType* type; ///< Type of this SVFValue - std::string name; ///< Short name of value for printing & debugging - std::string sourceLoc; ///< Source code information of this value - /// Constructor without name - SVFValue(const SVFType* ty, SVFValKind k) - : kind(k), ptrInUncalledFun(false), - constDataOrAggData(SVFConstData == k), type(ty), sourceLoc("NoLoc") + virtual const SVFType* getType() const { + return type; } - ///@{ attributes to be set only through Module builders e.g., - /// LLVMModule - inline void setConstDataOrAggData() + inline virtual void setName(const std::string& nameInfo) { - constDataOrAggData = true; + name = nameInfo; } - inline void setPtrInUncalledFunction() - { - ptrInUncalledFun = true; - } - ///@} -public: - SVFValue() = delete; - virtual ~SVFValue() = default; - /// Get the type of this SVFValue - inline GNodeK getKind() const + inline virtual void setName(std::string&& nameInfo) { - return kind; + name = std::move(nameInfo); } - inline const std::string &getName() const + virtual const std::string& getName() const { return name; } - inline void setName(std::string&& n) - { - name = std::move(n); - } - - inline virtual const SVFType* getType() const - { - return type; - } - inline bool isConstDataOrAggData() const - { - return constDataOrAggData; - } - inline bool ptrInUncalledFunction() const - { - return ptrInUncalledFun; - } - inline bool isblackHole() const - { - return getKind() == SVFBlackHole;; - } - inline bool isNullPtr() const - { - return getKind() == SVFNullPtr; - } inline virtual void setSourceLoc(const std::string& sourceCodeInfo) { sourceLoc = sourceCodeInfo; } - inline virtual const std::string getSourceLoc() const - { - return sourceLoc; - } - - /// Needs to be implemented by a SVF front end - std::string toString() const; - - /// Overloading operator << for dumping ICFG node ID - //@{ - friend OutStream& operator<<(OutStream &os, const SVFValue &value) - { - return os << value.toString(); - } - //@} -}; - -class ArgValVar; - -class SVFFunction : public SVFValue -{ - friend class LLVMModuleSet; - friend class SVFIRWriter; - friend class SVFIRReader; - friend class SVFIRBuilder; - -public: - typename BasicBlockGraph::IDToNodeMapTy::iterator iterator; - typedef BasicBlockGraph::IDToNodeMapTy::const_iterator const_iterator; - typedef SVFLoopAndDomInfo::BBSet BBSet; - typedef SVFLoopAndDomInfo::BBList BBList; - typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; - -private: - bool isDecl; /// return true if this function does not have a body - bool intrinsic; /// return true if this function is an intrinsic function (e.g., llvm.dbg), which does not reside in the application code - bool addrTaken; /// return true if this function is address-taken (for indirect call purposes) - bool isUncalled; /// return true if this function is never called - bool isNotRet; /// return true if this function never returns - bool varArg; /// return true if this function supports variable arguments - const SVFFunctionType* funcType; /// FunctionType, which is different from the type (PointerType) of this SVFFunction - SVFLoopAndDomInfo* loopAndDom; /// the loop and dominate information - const SVFFunction* realDefFun; /// the definition of a function across multiple modules - std::vector allArgs; /// all formal arguments of this function - SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function - BasicBlockGraph* bbGraph; /// the basic block graph of this function - -protected: - - inline void addArgument(const ArgValVar* arg) - { - allArgs.push_back(arg); - } - - inline void setIsUncalledFunction(bool uncalledFunction) - { - isUncalled = uncalledFunction; - } - - inline void setIsNotRet(bool notRet) - { - isNotRet = notRet; - } - - inline void setDefFunForMultipleModule(const SVFFunction* deffun) - { - realDefFun = deffun; - } - /// @} - -public: - SVFFunction(const SVFType* ty,const SVFFunctionType* ft, bool declare, bool intrinsic, bool addrTaken, bool varg, SVFLoopAndDomInfo* ld); - SVFFunction(void) = delete; - virtual ~SVFFunction(); - - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFFunc; - } - - inline SVFLoopAndDomInfo* getLoopAndDomInfo() - { - return loopAndDom; - } - inline bool isDeclaration() const - { - return isDecl; - } - - void setBasicBlockGraph(BasicBlockGraph* graph) - { - this->bbGraph = graph; - } - - BasicBlockGraph* getBasicBlockGraph() - { - return bbGraph; - } - - const BasicBlockGraph* getBasicBlockGraph() const - { - return bbGraph; - } - - inline bool isIntrinsic() const - { - return intrinsic; - } - - inline bool hasAddressTaken() const - { - return addrTaken; - } - - /// Returns the FunctionType - inline const SVFFunctionType* getFunctionType() const - { - return funcType; - } - - /// Returns the FunctionType - inline const SVFType* getReturnType() const - { - return funcType->getReturnType(); - } - - inline const SVFFunction* getDefFunForMultipleModule() const - { - if(realDefFun==nullptr) - return this; - return realDefFun; - } - - u32_t arg_size() const; - const ArgValVar* getArg(u32_t idx) const; - bool isVarArg() const; - - inline bool hasBasicBlock() const - { - return bbGraph && bbGraph->begin() != bbGraph->end(); - } - - inline const SVFBasicBlock* getEntryBlock() const - { - assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); - assert(bbGraph->begin()->second->getInEdges().size() == 0 && "the first basic block is not entry block"); - return bbGraph->begin()->second; - } - - /// Carefully! when you call getExitBB, you need ensure the function has return instruction - /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 - const SVFBasicBlock* getExitBB() const; - - void setExitBlock(SVFBasicBlock *bb); - - inline const SVFBasicBlock* front() const - { - return getEntryBlock(); - } - - inline const SVFBasicBlock* back() const - { - assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); - /// Carefully! 'back' is just the last basic block of function, - /// but not necessarily a exit basic block - /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 - return std::prev(bbGraph->end())->second; - } - - inline const_iterator begin() const - { - return bbGraph->begin(); - } - - inline const_iterator end() const - { - return bbGraph->end(); - } - - - inline const std::vector& getReachableBBs() const - { - return loopAndDom->getReachableBBs(); - } - - inline bool isUncalledFunction() const - { - return isUncalled; - } - - inline bool hasReturn() const - { - return !isNotRet; - } - - inline void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const - { - return loopAndDom->getExitBlocksOfLoop(bb,exitbbs); - } - - inline bool hasLoopInfo(const SVFBasicBlock* bb) const - { - return loopAndDom->hasLoopInfo(bb); - } - - const LoopBBs& getLoopInfo(const SVFBasicBlock* bb) const - { - return loopAndDom->getLoopInfo(bb); - } - - inline const SVFBasicBlock* getLoopHeader(const BBList& lp) const - { - return loopAndDom->getLoopHeader(lp); - } - - inline bool loopContainsBB(const BBList& lp, const SVFBasicBlock* bb) const - { - return loopAndDom->loopContainsBB(lp,bb); - } - - inline const Map& getDomTreeMap() const - { - return loopAndDom->getDomTreeMap(); - } - - inline const Map& getDomFrontierMap() const - { - return loopAndDom->getDomFrontierMap(); - } - - inline bool isLoopHeader(const SVFBasicBlock* bb) const - { - return loopAndDom->isLoopHeader(bb); - } - - inline bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const - { - return loopAndDom->dominate(bbKey,bbValue); - } - - inline bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const - { - return loopAndDom->postDominate(bbKey,bbValue); - } -}; - -class ICFGNode; -class FunObjVar; - -class SVFInstruction : public SVFValue -{ - friend class SVFIRWriter; - friend class SVFIRReader; - -private: - const SVFBasicBlock* bb; /// The BasicBlock where this Instruction resides - bool terminator; /// return true if this is a terminator instruction - bool ret; /// return true if this is an return instruction of a function - -public: - /// Constructor without name, set name with setName() - SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, bool tm, - bool isRet, SVFValKind k = SVFInst); - SVFInstruction(void) = delete; - - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFInst || - node->getKind() == SVFCall || - node->getKind() == SVFVCall; - } - - inline const SVFBasicBlock* getParent() const - { - return bb; - } - - inline const FunObjVar* getFunction() const - { - return bb->getParent(); - } - - inline bool isRetInst() const - { - return ret; - } -}; - -class SVFCallInst : public SVFInstruction -{ - friend class SVFIRWriter; - friend class SVFIRReader; - friend class LLVMModuleSet; - friend class SVFIRBuilder; - -private: - std::vector args; - bool varArg; - const SVFValue* calledVal; - -protected: - ///@{ attributes to be set only through Module builders e.g., LLVMModule - inline void addArgument(const SVFValue* a) - { - args.push_back(a); - } - inline void setCalledOperand(const SVFValue* v) - { - calledVal = v; - } - /// @} - -public: - SVFCallInst(const SVFType* ty, const SVFBasicBlock* b, bool va, bool tm, SVFValKind k = SVFCall) : - SVFInstruction(ty, b, tm, false, k), varArg(va), calledVal(nullptr) - { - } - SVFCallInst(void) = delete; - - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFCall || node->getKind() == SVFVCall; - } - static inline bool classof(const SVFInstruction *node) - { - return node->getKind() == SVFCall || node->getKind() == SVFVCall; - } - inline u32_t arg_size() const - { - return args.size(); - } - inline bool arg_empty() const - { - return args.empty(); - } - inline const SVFValue* getArgOperand(u32_t i) const - { - assert(i < arg_size() && "out of bound access of the argument"); - return args[i]; - } - inline u32_t getNumArgOperands() const - { - return arg_size(); - } - inline const SVFValue* getCalledOperand() const - { - return calledVal; - } - inline bool isVarArg() const - { - return varArg; - } - inline const SVFFunction* getCalledFunction() const - { - return SVFUtil::dyn_cast(calledVal); - } - inline const FunObjVar* getCaller() const - { - return getFunction(); - } -}; - -class SVFConstant : public SVFValue -{ - friend class SVFIRWriter; - friend class SVFIRReader; -public: - SVFConstant(const SVFType* ty, SVFValKind k = SVFConst): SVFValue(ty, k) - { - } - SVFConstant() = delete; - static inline bool classof(const SVFValue *node) + virtual const std::string getSourceLoc() const { - return node->getKind() == SVFConst || - node->getKind() == SVFGlob || - node->getKind() == SVFConstData || - node->getKind() == SVFConstInt || - node->getKind() == SVFConstFP || - node->getKind() == SVFNullPtr || - node->getKind() == SVFBlackHole; + return sourceLoc; } -}; + const std::string valueOnlyToString() const; -class SVFGlobalValue : public SVFConstant -{ - friend class SVFIRWriter; - friend class SVFIRReader; - friend class LLVMModuleSet; - -private: - const SVFValue* realDefGlobal; /// the definition of a function across multiple modules protected: - inline void setDefGlobalForMultipleModule(const SVFValue* defg) - { - realDefGlobal = defg; - } + NodeID id; ///< Node ID + GNodeK nodeKind; ///< Node kind + const SVFType* type; ///< SVF type -public: - SVFGlobalValue(const SVFType* ty): SVFConstant(ty, SVFValue::SVFGlob), realDefGlobal(nullptr) - { - } - SVFGlobalValue(std::string&& name, const SVFType* ty) : SVFGlobalValue(ty) - { - setName(std::move(name)); - } - SVFGlobalValue() = delete; - - inline const SVFValue* getDefGlobalForMultipleModule() const - { - if(realDefGlobal==nullptr) - return this; - return realDefGlobal; - } - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFGlob; - } - static inline bool classof(const SVFConstant *node) - { - return node->getKind() == SVFGlob; - } -}; - -class SVFArgument : public SVFValue -{ - friend class SVFIRWriter; - friend class SVFIRReader; -private: - const SVFFunction* fun; - u32_t argNo; - bool uncalled; -public: - SVFArgument(const SVFType* ty, const SVFFunction* fun, u32_t argNo, - bool uncalled) - : SVFValue(ty, SVFValue::SVFArg), fun(fun), argNo(argNo), - uncalled(uncalled) - { - } - SVFArgument() = delete; - - inline const SVFFunction* getParent() const - { - return fun; - } - - /// Return the index of this formal argument in its containing function. - /// For example in "void foo(int a, float b)" a is 0 and b is 1. - inline u32_t getArgNo() const - { - return argNo; - } + std::string name; + std::string sourceLoc; ///< Source code information of this value - inline bool isArgOfUncalledFunction() const + /// Helper functions to check node kinds + //{@ Check node kind + static inline bool isICFGNodeKinds(GNodeK n) { - return uncalled; + static_assert(FunRetBlock - IntraBlock == 5, + "the number of ICFGNodeKinds has changed, make sure " + "the range is correct"); + return n <= FunRetBlock && n >= IntraBlock; } - static inline bool classof(const SVFValue *node) + static inline bool isInterICFGNodeKind(GNodeK n) { - return node->getKind() == SVFArg; + static_assert(FunRetBlock - FunEntryBlock == 3, + "the number of InterICFGNodeKind has changed, make sure " + "the range is correct"); + return n <= FunRetBlock && n >= FunEntryBlock; } -}; -class SVFConstantData : public SVFConstant -{ - friend class SVFIRWriter; - friend class SVFIRReader; -public: - SVFConstantData(const SVFType* ty, SVFValKind k = SVFConstData) - : SVFConstant(ty, k) + static inline bool isSVFVarKind(GNodeK n) { - } - SVFConstantData() = delete; + static_assert(DummyObjNode - ValNode == 26, + "The number of SVFVarKinds has changed, make sure the " + "range is correct"); - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFConstData || - node->getKind() == SVFConstInt || - node->getKind() == SVFConstFP || - node->getKind() == SVFNullPtr || - node->getKind() == SVFBlackHole; - } - static inline bool classof(const SVFConstantData *node) - { - return node->getKind() == SVFConstData || - node->getKind() == SVFConstInt || - node->getKind() == SVFConstFP || - node->getKind() == SVFNullPtr || - node->getKind() == SVFBlackHole; + return n <= DummyObjNode && n >= ValNode; } -}; -class SVFConstantInt : public SVFConstantData -{ - friend class SVFIRWriter; - friend class SVFIRReader; -private: - u64_t zval; - s64_t sval; -public: - SVFConstantInt(const SVFType* ty, u64_t z, s64_t s) - : SVFConstantData(ty, SVFValue::SVFConstInt), zval(z), sval(s) + static inline bool isValVarKinds(GNodeK n) { + static_assert(DummyValNode - ValNode == 13, + "The number of ValVarKinds has changed, make sure the " + "range is correct"); + return n <= DummyValNode && n >= ValNode; } - SVFConstantInt() = delete; - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFConstInt; - } - static inline bool classof(const SVFConstantData *node) - { - return node->getKind() == SVFConstInt; - } - // Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate for the type of this constant. - inline u64_t getZExtValue () const - { - return zval; - } - // Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the type of this constant - inline s64_t getSExtValue () const - { - return sval; - } -}; -class SVFConstantFP : public SVFConstantData -{ - friend class SVFIRWriter; - friend class SVFIRReader; -private: - float dval; -public: - SVFConstantFP(const SVFType* ty, double d) - : SVFConstantData(ty, SVFValue::SVFConstFP), dval(d) + static inline bool isConstantDataValVar(GNodeK n) { + static_assert(ConstNullptrValNode - ConstDataValNode == 4, + "The number of ConstantDataValVarKinds has changed, make " + "sure the range is correct"); + return n <= ConstNullptrValNode && n >= ConstDataValNode; } - SVFConstantFP() = delete; - inline double getFPValue () const - { - return dval; - } - static inline bool classof(const SVFValue *node) + static inline bool isObjVarKinds(GNodeK n) { - return node->getKind() == SVFConstFP; + static_assert(DummyObjNode - ObjNode == 12, + "The number of ObjVarKinds has changed, make sure the " + "range is correct"); + return n <= DummyObjNode && n >= ObjNode; } - static inline bool classof(const SVFConstantData *node) - { - return node->getKind() == SVFConstFP; - } -}; - -class SVFConstantNullPtr : public SVFConstantData -{ - friend class SVFIRWriter; - friend class SVFIRReader; -public: - SVFConstantNullPtr(const SVFType* ty) - : SVFConstantData(ty, SVFValue::SVFNullPtr) + static inline bool isBaseObjVarKinds(GNodeK n) { + static_assert(DummyObjNode - BaseObjNode == 10, + "The number of BaseObjVarKinds has changed, make sure the " + "range is correct"); + return n <= DummyObjNode && n >= BaseObjNode; } - SVFConstantNullPtr() = delete; - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFNullPtr; - } - static inline bool classof(const SVFConstantData *node) + static inline bool isConstantDataObjVarKinds(GNodeK n) { - return node->getKind() == SVFNullPtr; + static_assert(ConstNullptrObjNode - ConstDataObjNode == 3, + "The number of ConstantDataObjVarKinds has changed, make " + "sure the range is correct"); + return n <= ConstNullptrObjNode && n >= ConstDataObjNode; } -}; - -class SVFBlackHoleValue : public SVFConstantData -{ - friend class SVFIRWriter; - friend class SVFIRReader; -public: - SVFBlackHoleValue(const SVFType* ty) - : SVFConstantData(ty, SVFValue::SVFBlackHole) + static inline bool isVFGNodeKinds(GNodeK n) { + static_assert(MInterPhi - Cmp == 24, + "The number of VFGNodeKinds has changed, make sure the " + "range is correct"); + return n <= MInterPhi && n >= Cmp; } - SVFBlackHoleValue() = delete; - static inline bool classof(const SVFValue *node) - { - return node->getKind() == SVFBlackHole; - } - static inline bool classof(const SVFConstantData *node) + static inline bool isArgumentVFGNodeKinds(GNodeK n) { - return node->getKind() == SVFBlackHole; + static_assert(FParm - FRet == 3, + "The number of ArgumentVFGNodeKinds has changed, make " + "sure the range is correct"); + return n <= FParm && n >= FRet; } -}; -class SVFOtherValue : public SVFValue -{ - friend class SVFIRWriter; - friend class SVFIRReader; -public: - SVFOtherValue(const SVFType* ty, SVFValKind k = SVFValue::SVFOther) - : SVFValue(ty, k) + static inline bool isStmtVFGNodeKinds(GNodeK n) { + static_assert(Load - Addr == 4, + "The number of StmtVFGNodeKinds has changed, make sure " + "the range is correct"); + return n <= Load && n >= Addr; } - SVFOtherValue() = delete; - static inline bool classof(const SVFValue *node) + static inline bool isPHIVFGNodeKinds(GNodeK n) { - return node->getKind() == SVFOther || node->getKind() == SVFMetaAsValue; + static_assert(TInterPhi - TPhi == 2, + "The number of PHIVFGNodeKinds has changed, make sure " + "the range is correct"); + return n <= TInterPhi && n >= TPhi; } -}; -/* - * This class is only for LLVM's MetadataAsValue -*/ -class SVFMetadataAsValue : public SVFOtherValue -{ - friend class SVFIRWriter; - friend class SVFIRReader; -public: - SVFMetadataAsValue(const SVFType* ty) - : SVFOtherValue(ty, SVFValue::SVFMetaAsValue) + static inline bool isMRSVFGNodeKinds(GNodeK n) { + static_assert(MInterPhi - FPIN == 6, + "The number of MRSVFGNodeKinds has changed, make sure " + "the range is correct"); + return n <= MInterPhi && n >= FPIN; } - SVFMetadataAsValue() = delete; - static inline bool classof(const SVFValue *node) + static inline bool isMSSAPHISVFGNodeKinds(GNodeK n) { - return node->getKind() == SVFMetaAsValue; - } - static inline bool classof(const SVFOtherValue *node) - { - return node->getKind() == SVFMetaAsValue; + static_assert(MInterPhi - MPhi == 2, + "The number of MSSAPHISVFGNodeKinds has changed, make " + "sure the range is correct"); + return n <= MInterPhi && n >= MPhi; } + //@} }; -/// [FOR DEBUG ONLY, DON'T USE IT UNSIDE `svf`!] -/// Converts an SVFValue to corresponding LLVM::Value, then get the string -/// representation of it. Use it only when you are debugging. Don't use -/// it in any SVF algorithm because it relies on information stored in LLVM bc. -std::string dumpLLVMValue(const SVFValue* svfValue); - template OutStream& operator<< (OutStream &o, const std::pair &var) { @@ -930,6 +332,6 @@ OutStream& operator<< (OutStream &o, const std::pair &var) return o; } -} // End namespace SVF +} #endif /* INCLUDE_SVFIR_SVFVALUE_H_ */ diff --git a/svf/include/Util/CDGBuilder.h b/svf/include/Util/CDGBuilder.h index f66ab6720..15f464143 100644 --- a/svf/include/Util/CDGBuilder.h +++ b/svf/include/Util/CDGBuilder.h @@ -55,7 +55,7 @@ class CDGBuilder void build(); /// build control dependence for each function - void buildControlDependence(const SVFModule *svfgModule); + void buildControlDependence(); /// build map at icfg node level void buildICFGNodeControlMap(); diff --git a/svf/include/Util/GeneralType.h b/svf/include/Util/GeneralType.h index 95dab6a4b..69df9a2a1 100644 --- a/svf/include/Util/GeneralType.h +++ b/svf/include/Util/GeneralType.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "Util/SparseBitVector.h" namespace SVF diff --git a/svf/include/Util/SVFLoopAndDomInfo.h b/svf/include/Util/SVFLoopAndDomInfo.h new file mode 100644 index 000000000..782ad5fb9 --- /dev/null +++ b/svf/include/Util/SVFLoopAndDomInfo.h @@ -0,0 +1,168 @@ +//===- SVFLoopAndDomInfo.h -- ------------------------------// +// +// SVF: Static Value-Flow Analysis +// +// Copyright (C) <2013-2017> +// + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//===----------------------------------------------------------------------===// + +/* +* SVFLoopAndDomInfo.h +* +* Created on: Feb 7, 2025 +* Author: Xiao Cheng +* +*/ + +#ifndef SVFLOOPANDDOMINFO_H +#define SVFLOOPANDDOMINFO_H + +#include "SVFIR/SVFType.h" +#include "Graphs/GraphPrinter.h" +#include "Util/Casting.h" +#include "Graphs/BasicBlockG.h" + +namespace SVF { +class SVFLoopAndDomInfo +{ + friend class SVFIRWriter; + friend class SVFIRReader; +public: + typedef Set BBSet; + typedef std::vector BBList; + typedef BBList LoopBBs; + +private: + BBList reachableBBs; ///< reachable BasicBlocks from the function entry. + Map dtBBsMap; ///< map a BasicBlock to BasicBlocks it Dominates + Map pdtBBsMap; ///< map a BasicBlock to BasicBlocks it PostDominates + Map dfBBsMap; ///< map a BasicBlock to its Dominate Frontier BasicBlocks + Map bb2LoopMap; ///< map a BasicBlock (if it is in a loop) to all the BasicBlocks in this loop + Map bb2PdomLevel; ///< map a BasicBlock to its level in pdom tree, used in findNearestCommonPDominator + Map bb2PIdom; ///< map a BasicBlock to its immediate dominator in pdom tree, used in findNearestCommonPDominator + +public: + SVFLoopAndDomInfo() + { + } + + virtual ~SVFLoopAndDomInfo() {} + + inline const Map& getDomFrontierMap() const + { + return dfBBsMap; + } + + inline Map& getDomFrontierMap() + { + return dfBBsMap; + } + + inline bool hasLoopInfo(const SVFBasicBlock* bb) const + { + return bb2LoopMap.find(bb) != bb2LoopMap.end(); + } + + const LoopBBs& getLoopInfo(const SVFBasicBlock* bb) const; + + inline const SVFBasicBlock* getLoopHeader(const LoopBBs& lp) const + { + assert(!lp.empty() && "this is not a loop, empty basic block"); + return lp.front(); + } + + inline bool loopContainsBB(const LoopBBs& lp, const SVFBasicBlock* bb) const + { + return std::find(lp.begin(), lp.end(), bb) != lp.end(); + } + + inline void addToBB2LoopMap(const SVFBasicBlock* bb, const SVFBasicBlock* loopBB) + { + bb2LoopMap[bb].push_back(loopBB); + } + + inline const Map& getPostDomTreeMap() const + { + return pdtBBsMap; + } + + inline Map& getPostDomTreeMap() + { + return pdtBBsMap; + } + + inline const Map& getBBPDomLevel() const + { + return bb2PdomLevel; + } + + inline Map& getBBPDomLevel() + { + return bb2PdomLevel; + } + + inline const Map& getBB2PIdom() const + { + return bb2PIdom; + } + + inline Map& getBB2PIdom() + { + return bb2PIdom; + } + + + inline Map& getDomTreeMap() + { + return dtBBsMap; + } + + inline const Map& getDomTreeMap() const + { + return dtBBsMap; + } + + inline bool isUnreachable(const SVFBasicBlock* bb) const + { + return std::find(reachableBBs.begin(), reachableBBs.end(), bb) == + reachableBBs.end(); + } + + inline const BBList& getReachableBBs() const + { + return reachableBBs; + } + + inline void setReachableBBs(BBList& bbs) + { + reachableBBs = bbs; + } + + void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const; + + bool isLoopHeader(const SVFBasicBlock* bb) const; + + bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const; + + bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const; + + /// find nearest common post dominator of two basic blocks + const SVFBasicBlock *findNearestCommonPDominator(const SVFBasicBlock *A, const SVFBasicBlock *B) const; +}; +} + +#endif //SVFLOOPANDDOMINFO_H diff --git a/svf/include/Util/SVFUtil.h b/svf/include/Util/SVFUtil.h index 743d62d96..30e8ebbd0 100644 --- a/svf/include/Util/SVFUtil.h +++ b/svf/include/Util/SVFUtil.h @@ -32,10 +32,12 @@ #include "FastCluster/fastcluster.h" #include "SVFIR/SVFValue.h" -#include "SVFIR/SVFModule.h" +#include "Util/SVFLoopAndDomInfo.h" #include "Util/ExtAPI.h" #include "MemoryModel/PointsTo.h" #include +#include "Util/NodeIDAllocator.h" +#include "Util/ThreadAPI.h" namespace SVF { diff --git a/svf/include/Util/ThreadAPI.h b/svf/include/Util/ThreadAPI.h index 8605edc89..754f4190b 100644 --- a/svf/include/Util/ThreadAPI.h +++ b/svf/include/Util/ThreadAPI.h @@ -41,6 +41,7 @@ class CallICFGNode; class SVFVar; class ValVar; class ObjVar; +class FunObjVar; /* * ThreadAPI class contains interfaces for pthread programs @@ -179,7 +180,7 @@ class ThreadAPI bool isTDBarWait(const CallICFGNode *inst) const; //@} - void performAPIStat(SVFModule* m); + void performAPIStat(); void statInit(Map& tdAPIStatMap); }; diff --git a/svf/include/WPA/FlowSensitive.h b/svf/include/WPA/FlowSensitive.h index 79c493170..146193e91 100644 --- a/svf/include/WPA/FlowSensitive.h +++ b/svf/include/WPA/FlowSensitive.h @@ -93,7 +93,7 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl } /// We start from here - virtual bool runOnModule(SVFModule*) + virtual bool runOnModule() { return false; } diff --git a/svf/lib/DDA/DDAPass.cpp b/svf/lib/DDA/DDAPass.cpp index 53930dd2d..acbd7a849 100644 --- a/svf/lib/DDA/DDAPass.cpp +++ b/svf/lib/DDA/DDAPass.cpp @@ -57,7 +57,7 @@ void DDAPass::runOnModule(SVFIR* pag) /// initialization for llvm alias analyzer //InitializeAliasAnalysis(this, getDataLayout(&module)); - selectClient(pag->getModule()); + selectClient(); for (u32_t i = PointerAnalysis::FlowS_DDA; i < PointerAnalysis::Default_PTA; i++) @@ -69,7 +69,7 @@ void DDAPass::runOnModule(SVFIR* pag) } /// select a client to initialize queries -void DDAPass::selectClient(SVFModule* module) +void DDAPass::selectClient() { if (!Options::UserInputQuery().empty()) @@ -77,16 +77,16 @@ void DDAPass::selectClient(SVFModule* module) /// solve function pointer if (Options::UserInputQuery() == "funptr") { - _client = new FunptrDDAClient(module); + _client = new FunptrDDAClient(); } else if (Options::UserInputQuery() == "alias") { - _client = new AliasDDAClient(module); + _client = new AliasDDAClient(); } /// allow user specify queries else { - _client = new DDAClient(module); + _client = new DDAClient(); if (Options::UserInputQuery() != "all") { u32_t buf; // Have a buffer @@ -101,7 +101,7 @@ void DDAPass::selectClient(SVFModule* module) assert(false && "Please specify query options!"); } - _client->initialise(module); + _client->initialise(); } /// Create pointer analysis according to specified kind and analyze the module. @@ -131,7 +131,7 @@ void DDAPass::runPointerAnalysis(SVFIR* pag, u32_t kind) if(Options::WPANum()) { - _client->collectWPANum(pag->getModule()); + _client->collectWPANum(); } else { diff --git a/svf/lib/Graphs/ConsG.cpp b/svf/lib/Graphs/ConsG.cpp index 34d8bc1e0..aeda91d7b 100644 --- a/svf/lib/Graphs/ConsG.cpp +++ b/svf/lib/Graphs/ConsG.cpp @@ -190,7 +190,7 @@ AddrCGEdge::AddrCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) // Retarget addr edges may lead s to be a dummy node PAGNode* node = SVFIR::getPAG()->getGNode(s->getId()); (void)node; // Suppress warning of unused variable under release build - if (!SVFModule::pagReadFromTXT()) + if (!SVFIR::pagReadFromTXT()) { assert(!SVFUtil::isa(node) && "a dummy node??"); } diff --git a/svf/lib/Graphs/ICFG.cpp b/svf/lib/Graphs/ICFG.cpp index aaf594854..f6a8f5bbe 100644 --- a/svf/lib/Graphs/ICFG.cpp +++ b/svf/lib/Graphs/ICFG.cpp @@ -30,7 +30,6 @@ #include "Graphs/ICFG.h" #include "Graphs/CallGraph.h" #include "SVFIR/SVFIR.h" -#include "SVFIR/SVFModule.h" #include using namespace SVF; diff --git a/svf/lib/Graphs/SVFG.cpp b/svf/lib/Graphs/SVFG.cpp index b07ef8a54..29f3b6acd 100644 --- a/svf/lib/Graphs/SVFG.cpp +++ b/svf/lib/Graphs/SVFG.cpp @@ -27,7 +27,7 @@ * Author: Yulei Sui */ -#include "SVFIR/SVFModule.h" + #include "Util/SVFUtil.h" #include "Graphs/SVFG.h" #include "Graphs/SVFGOPT.h" diff --git a/svf/lib/Graphs/SVFGReadWrite.cpp b/svf/lib/Graphs/SVFGReadWrite.cpp index a0cc3e477..c87d3f828 100644 --- a/svf/lib/Graphs/SVFGReadWrite.cpp +++ b/svf/lib/Graphs/SVFGReadWrite.cpp @@ -27,7 +27,6 @@ * Author: Jeffrey Ma */ -#include "SVFIR/SVFModule.h" #include "Util/SVFUtil.h" #include "Graphs/SVFG.h" #include "Graphs/SVFGStat.h" diff --git a/svf/lib/Graphs/ThreadCallGraph.cpp b/svf/lib/Graphs/ThreadCallGraph.cpp index ee6a35e24..90f3739bc 100644 --- a/svf/lib/Graphs/ThreadCallGraph.cpp +++ b/svf/lib/Graphs/ThreadCallGraph.cpp @@ -27,7 +27,6 @@ * Author: Yulei Sui, Peng Di, Ding Ye */ -#include "SVFIR/SVFModule.h" #include "Graphs/ThreadCallGraph.h" #include "Util/ThreadAPI.h" #include "SVFIR/SVFIR.h" diff --git a/svf/lib/Graphs/VFG.cpp b/svf/lib/Graphs/VFG.cpp index 850c93530..542885d8c 100644 --- a/svf/lib/Graphs/VFG.cpp +++ b/svf/lib/Graphs/VFG.cpp @@ -31,7 +31,6 @@ #include #include "Util/Options.h" #include "Graphs/VFG.h" -#include "SVFIR/SVFModule.h" #include "Util/SVFUtil.h" using namespace SVF; diff --git a/svf/lib/MSSA/MemRegion.cpp b/svf/lib/MSSA/MemRegion.cpp index 0dbeca6ea..e4fe9bc0f 100644 --- a/svf/lib/MSSA/MemRegion.cpp +++ b/svf/lib/MSSA/MemRegion.cpp @@ -28,7 +28,6 @@ */ #include "Util/Options.h" -#include "SVFIR/SVFModule.h" #include "MSSA/MemRegion.h" #include "MSSA/MSSAMuChi.h" #include "Graphs/CallGraph.h" diff --git a/svf/lib/MSSA/SVFGBuilder.cpp b/svf/lib/MSSA/SVFGBuilder.cpp index 4367e888b..ce5a23353 100644 --- a/svf/lib/MSSA/SVFGBuilder.cpp +++ b/svf/lib/MSSA/SVFGBuilder.cpp @@ -27,7 +27,6 @@ * Author: Yulei Sui */ #include "Util/Options.h" -#include "SVFIR/SVFModule.h" #include "Util/SVFUtil.h" #include "MSSA/MemSSA.h" #include "Graphs/SVFG.h" diff --git a/svf/lib/MTA/MTA.cpp b/svf/lib/MTA/MTA.cpp index aeb57c327..b57a11998 100644 --- a/svf/lib/MTA/MTA.cpp +++ b/svf/lib/MTA/MTA.cpp @@ -60,11 +60,11 @@ MTA::~MTA() */ bool MTA::runOnModule(SVFIR* pag) { - mhp = computeMHP(pag->getModule()); + mhp = computeMHP(); lsa = computeLocksets(mhp->getTCT()); if(Options::RaceCheck()) - detect(pag->getModule()); + detect(); return false; } @@ -79,7 +79,7 @@ LockAnalysis* MTA::computeLocksets(TCT* tct) return lsa; } -MHP* MTA::computeMHP(SVFModule* module) +MHP* MTA::computeMHP() { DBOUT(DGENERAL, outs() << pasMsg("MTA analysis\n")); @@ -125,7 +125,7 @@ MHP* MTA::computeMHP(SVFModule* module) // * when two memory access may-happen in parallel and are not protected by the same lock // * (excluding global constraints because they are initialized before running the main function) // */ -void MTA::detect(SVFModule* module) +void MTA::detect() { DBOUT(DGENERAL, outs() << pasMsg("Starting Race Detection\n")); diff --git a/svf/lib/MemoryModel/PointerAnalysis.cpp b/svf/lib/MemoryModel/PointerAnalysis.cpp index c55d51c1c..91b7c6059 100644 --- a/svf/lib/MemoryModel/PointerAnalysis.cpp +++ b/svf/lib/MemoryModel/PointerAnalysis.cpp @@ -28,7 +28,6 @@ */ #include "Util/Options.h" -#include "SVFIR/SVFModule.h" #include "Util/SVFUtil.h" #include "MemoryModel/PointerAnalysisImpl.h" @@ -66,8 +65,9 @@ const std::string PointerAnalysis::aliasTestFailNoAliasMangled = "_Z20EXPECTEDF /*! * Constructor */ -PointerAnalysis::PointerAnalysis(SVFIR* p, PTATY ty, bool alias_check) : - svfMod(nullptr),ptaTy(ty),stat(nullptr),callgraph(nullptr),callGraphSCC(nullptr),icfg(nullptr),chgraph(nullptr) +PointerAnalysis::PointerAnalysis(SVFIR *p, PTATY ty, bool alias_check) : ptaTy(ty), stat(nullptr), callgraph(nullptr), + callGraphSCC(nullptr), icfg(nullptr), + chgraph(nullptr) { pag = p; OnTheFlyIterBudgetForStat = Options::StatBudget(); @@ -106,7 +106,6 @@ void PointerAnalysis::initialize() { assert(pag && "SVFIR has not been built!"); - svfMod = pag->getModule(); chgraph = pag->getCHG(); /// initialise pta call graph for every pointer analysis instance @@ -260,7 +259,7 @@ void PointerAnalysis::dumpPts(NodeID ptr, const PointsTo& pts) { outs() << "## id:" << node->getId(); } - else if (!SVFUtil::isa(node) && !SVFModule::pagReadFromTXT()) + else if (!SVFUtil::isa(node) && !SVFIR::pagReadFromTXT()) { outs() << "##<" << node->getName() << "> "; outs() << "Source Loc: " << node->getSourceLoc(); @@ -296,7 +295,7 @@ void PointerAnalysis::dumpPts(NodeID ptr, const PointsTo& pts) outs() << "Dummy Obj id: " << node->getId() << "]\n"; else { - if (!SVFModule::pagReadFromTXT()) + if (!SVFIR::pagReadFromTXT()) { outs() << "<" << pagNode->getName() << "> "; outs() << "Source Loc: " diff --git a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp index 72a1fa2da..01dfb80d9 100644 --- a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +++ b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp @@ -97,7 +97,7 @@ void BVDataPTAImpl::finalize() if (Options::ptDataBacking() == PTBackingType::Persistent && print_stat) { - std::string moduleName(pag->getModule()->getModuleIdentifier()); + std::string moduleName(pag->getModuleIdentifier()); std::vector names = SVFUtil::split(moduleName,'/'); if (names.size() > 1) moduleName = names[names.size() - 1]; diff --git a/svf/lib/SABER/SaberCondAllocator.cpp b/svf/lib/SABER/SaberCondAllocator.cpp index 464868966..783e69b5e 100644 --- a/svf/lib/SABER/SaberCondAllocator.cpp +++ b/svf/lib/SABER/SaberCondAllocator.cpp @@ -56,7 +56,7 @@ SaberCondAllocator::SaberCondAllocator() /*! * Allocate path condition for each branch */ -void SaberCondAllocator::allocate(const SVFModule *M) +void SaberCondAllocator::allocate() { DBOUT(DGENERAL, outs() << pasMsg("path condition allocation starts\n")); diff --git a/svf/lib/SABER/SrcSnkDDA.cpp b/svf/lib/SABER/SrcSnkDDA.cpp index 707390abc..31256c3f0 100644 --- a/svf/lib/SABER/SrcSnkDDA.cpp +++ b/svf/lib/SABER/SrcSnkDDA.cpp @@ -38,7 +38,7 @@ using namespace SVF; using namespace SVFUtil; /// Initialize analysis -void SrcSnkDDA::initialize(SVFModule* module) +void SrcSnkDDA::initialize() { SVFIR* pag = PAG::getPAG(); @@ -52,16 +52,16 @@ void SrcSnkDDA::initialize(SVFModule* module) callgraph = ander->getCallGraph(); //AndersenWaveDiff::releaseAndersenWaveDiff(); /// allocate control-flow graph branch conditions - getSaberCondAllocator()->allocate(getPAG()->getModule()); + getSaberCondAllocator()->allocate(); initSrcs(); initSnks(); } -void SrcSnkDDA::analyze(SVFModule* module) +void SrcSnkDDA::analyze() { - initialize(module); + initialize(); ContextCond::setMaxCxtLen(Options::CxtLimit()); diff --git a/svf/lib/SVFIR/SVFIR.cpp b/svf/lib/SVFIR/SVFIR.cpp index f03db09ee..1c51ff313 100644 --- a/svf/lib/SVFIR/SVFIR.cpp +++ b/svf/lib/SVFIR/SVFIR.cpp @@ -37,7 +37,9 @@ using namespace SVFUtil; std::unique_ptr SVFIR::pag; -SVFIR::SVFIR(bool buildFromFile) : IRGraph(buildFromFile), svfModule(nullptr), icfg(nullptr), chgraph(nullptr) +std::string SVFIR::pagReadFromTxt = ""; + +SVFIR::SVFIR(bool buildFromFile) : IRGraph(buildFromFile), icfg(nullptr), chgraph(nullptr) { } @@ -545,8 +547,6 @@ void SVFIR::destroy() icfg = nullptr; delete chgraph; chgraph = nullptr; - SVFModule::releaseSVFModule(); - svfModule = nullptr; delete callGraph; callGraph = nullptr; } diff --git a/svf/lib/SVFIR/SVFValue.cpp b/svf/lib/SVFIR/SVFValue.cpp index 388ba3b25..b72b8b33b 100644 --- a/svf/lib/SVFIR/SVFValue.cpp +++ b/svf/lib/SVFIR/SVFValue.cpp @@ -1,6 +1,8 @@ #include "SVFIR/SVFValue.h" #include "Util/SVFUtil.h" #include "Graphs/GenericGraph.h" +#include "Util/SVFLoopAndDomInfo.h" + using namespace SVF; using namespace SVFUtil; @@ -149,64 +151,6 @@ bool SVFLoopAndDomInfo::isLoopHeader(const SVFBasicBlock* bb) const return false; } -SVFFunction::SVFFunction(const SVFType* ty, const SVFFunctionType* ft, - bool declare, bool intrinsic, bool adt, bool varg, - SVFLoopAndDomInfo* ld) - : SVFValue(ty, SVFValue::SVFFunc), isDecl(declare), intrinsic(intrinsic), - addrTaken(adt), isUncalled(false), isNotRet(false), varArg(varg), - funcType(ft), loopAndDom(ld), realDefFun(nullptr), exitBlock(nullptr) -{ -} - -SVFFunction::~SVFFunction() -{ - delete loopAndDom; - delete bbGraph; -} - -u32_t SVFFunction::arg_size() const -{ - return allArgs.size(); -} - -const ArgValVar* SVFFunction::getArg(u32_t idx) const -{ - assert (idx < allArgs.size() && "getArg() out of range!"); - return allArgs[idx]; -} - -bool SVFFunction::isVarArg() const -{ - return varArg; -} - -const SVFBasicBlock *SVFFunction::getExitBB() const -{ - assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); - assert(exitBlock && "must have an exitBlock"); - return exitBlock; -} - -void SVFFunction::setExitBlock(SVFBasicBlock *bb) -{ - assert(!exitBlock && "have already set exit Basicblock!"); - exitBlock = bb; -} - - -SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, - bool tm, bool isRet, SVFValKind k) - : SVFValue(ty, k), bb(b), terminator(tm), ret(isRet) -{ -} - -__attribute__((weak)) -std::string SVFValue::toString() const -{ - assert("SVFValue::toString should be implemented or supported by fronted" && false); - abort(); -} - __attribute__((weak)) const std::string SVFBaseNode::valueOnlyToString() const { diff --git a/svf/lib/Util/CDGBuilder.cpp b/svf/lib/Util/CDGBuilder.cpp index 4b9f6ec71..19de6c0da 100644 --- a/svf/lib/Util/CDGBuilder.cpp +++ b/svf/lib/Util/CDGBuilder.cpp @@ -78,8 +78,7 @@ void CDGBuilder::build() { if (_controlDG->getTotalNodeNum() > 0) return; - PAG *pag = PAG::getPAG(); - buildControlDependence(pag->getModule()); + buildControlDependence(); buildICFGNodeControlMap(); } @@ -121,7 +120,7 @@ s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasic * including LCA if LCA is pred, excluding LCA if LCA is not pred * @param svfgModule */ -void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) +void CDGBuilder::buildControlDependence() { CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) diff --git a/svf/lib/Util/SVFStat.cpp b/svf/lib/Util/SVFStat.cpp index 96c4a9ea0..6c06bdea7 100644 --- a/svf/lib/Util/SVFStat.cpp +++ b/svf/lib/Util/SVFStat.cpp @@ -67,7 +67,7 @@ double SVFStat::getClk(bool mark) void SVFStat::printStat(string statname) { - std::string moduleName(SVFIR::getPAG()->getModule()->getModuleIdentifier()); + std::string moduleName(SVFIR::getPAG()->getModuleIdentifier()); std::vector names = SVFUtil::split(moduleName,'/'); if (names.size() > 1) { diff --git a/svf/lib/Util/ThreadAPI.cpp b/svf/lib/Util/ThreadAPI.cpp index ed67bb8ba..e37a10e07 100644 --- a/svf/lib/Util/ThreadAPI.cpp +++ b/svf/lib/Util/ThreadAPI.cpp @@ -275,7 +275,7 @@ void ThreadAPI::statInit(Map& tdAPIStatMap) tdAPIStatMap["hare_parallel_for"] = 0; } -void ThreadAPI::performAPIStat(SVFModule* module) +void ThreadAPI::performAPIStat() { Map tdAPIStatMap; @@ -397,7 +397,7 @@ void ThreadAPI::performAPIStat(SVFModule* module) } - std::string name(module->getModuleIdentifier()); + std::string name(PAG::getPAG()->getModuleIdentifier()); std::vector fullNames = SVFUtil::split(name,'/'); if (fullNames.size() > 1) { diff --git a/svf/lib/WPA/FlowSensitive.cpp b/svf/lib/WPA/FlowSensitive.cpp index e62e60c45..992c9904c 100644 --- a/svf/lib/WPA/FlowSensitive.cpp +++ b/svf/lib/WPA/FlowSensitive.cpp @@ -28,7 +28,6 @@ */ #include "Util/Options.h" -#include "SVFIR/SVFModule.h" #include "WPA/WPAStat.h" #include "WPA/FlowSensitive.h" #include "WPA/Andersen.h" diff --git a/svf/lib/WPA/WPAPass.cpp b/svf/lib/WPA/WPAPass.cpp index bcee38ed4..71aac3237 100644 --- a/svf/lib/WPA/WPAPass.cpp +++ b/svf/lib/WPA/WPAPass.cpp @@ -34,7 +34,6 @@ #include "Util/Options.h" -#include "SVFIR/SVFModule.h" #include "MemoryModel/PointerAnalysisImpl.h" #include "WPA/WPAPass.h" #include "WPA/Andersen.h"