Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -356,22 +356,27 @@ if(PHASAR_IN_TREE)
set (PHASAR_USE_Z3 OFF)
else()
if(PHASAR_USE_Z3)
# This z3-version is the same version LLVM requires; however, we cannot just use Z3 via the LLVM interface
# as it lacks some functionality (such as z3::expr::simplify()) that we require

# FindZ3.cmake by llvm tries to compile a snippet with Z3 which crashes on arm with sanitizers enabled
set(SAFE_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "")
find_package(Z3 4.7.1 REQUIRED)
set(CMAKE_CXX_FLAGS "${SAFE_CMAKE_CXX_FLAGS}")

if(Z3_FOUND)
if (NOT TARGET z3)
add_library(z3 IMPORTED SHARED)
set_property(TARGET z3 PROPERTY
IMPORTED_LOCATION ${Z3_LIBRARIES})
set_property(TARGET z3 PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR})
if (TARGET z3::libz3)
# When including SVF, it also tries to find z3, but in addition to LLVM's search it already creates a target: z3::libz3.
# Reuse it here:
if(NOT TARGET z3)
add_library(z3 ALIAS z3::libz3)
endif()
else()
# FindZ3.cmake by llvm tries to compile a snippet with Z3 which crashes on arm with sanitizers enabled
set(SAFE_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "")
find_package(Z3 REQUIRED)
set(CMAKE_CXX_FLAGS "${SAFE_CMAKE_CXX_FLAGS}")

if(Z3_FOUND)
if (NOT TARGET z3)
add_library(z3 IMPORTED SHARED)
set_target_properties(z3 PROPERTIES
IMPORTED_LOCATION ${Z3_LIBRARIES}
INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR}
)
endif()
endif()
endif()
endif()
Expand Down
2 changes: 2 additions & 0 deletions lib/PhasarLLVM/Pointer/SVF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ add_phasar_library(phasar_llvm_pointer_svf

target_include_directories(phasar_llvm_pointer_svf SYSTEM PRIVATE ${SVF_INSTALL_INCLUDE_DIR})
target_link_directories(phasar_llvm_pointer_svf PUBLIC ${SVF_INSTALL_LIB_DIR})
# Such that SVF finds its extapi.bc without system-wide installation:
target_compile_options(phasar_llvm_pointer_svf PRIVATE -DPHASAR_SVF_INSTALL_LIBDIR="${SVF_INSTALL_LIBDIR}")
12 changes: 4 additions & 8 deletions lib/PhasarLLVM/Pointer/SVF/InitSVF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ static psr::EmptyType initializeSVFImpl() {
char EmptyStr[] = "";
char NoAliasCheck[] = "-alias-check=false";
char NoStat[] = "-stat=false";
char Extapi[] = "-extapi=" PHASAR_SVF_INSTALL_LIBDIR "/extapi.bc";
char *MockArgv[] = {
EmptyStr,
NoAliasCheck,
NoStat,
Extapi,
};
OptionBase::parseOptions(std::size(MockArgv), MockArgv, "", "");

Expand All @@ -33,14 +35,8 @@ void psr::initializeSVF() {
(void)SVFInitialized;
}

SVF::SVFModule *psr::initSVFModule(psr::LLVMProjectIRDB &IRDB) {
void psr::initSVFModule(psr::LLVMProjectIRDB &IRDB) {
psr::initializeSVF();

auto *Mod = SVF::LLVMModuleSet::buildSVFModule(*IRDB.getModule());
if (!Mod) {
throw std::runtime_error(
"SVF failed to create an SVFModule from an llvm::Module!");
}

return Mod;
SVF::LLVMModuleSet::buildSVFModule(*IRDB.getModule());
}
7 changes: 1 addition & 6 deletions lib/PhasarLLVM/Pointer/SVF/InitSVF.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@

#include "llvm/Support/Compiler.h"

namespace SVF {
class SVFModule;
} // namespace SVF

namespace psr {
class LLVMProjectIRDB;

LLVM_LIBRARY_VISIBILITY void initializeSVF();
LLVM_LIBRARY_VISIBILITY SVF::SVFModule *
initSVFModule(psr::LLVMProjectIRDB &IRDB);
LLVM_LIBRARY_VISIBILITY void initSVFModule(psr::LLVMProjectIRDB &IRDB);
} // namespace psr
37 changes: 16 additions & 21 deletions lib/PhasarLLVM/Pointer/SVF/PhasarSVFUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,39 @@
#include "Util/GeneralType.h"

namespace psr {

[[nodiscard]] inline const llvm::Value *
svfVarToLLVMOrNull(const SVF::SVFVar *Var, SVF::LLVMModuleSet &ModSet) {
if (ModSet.hasLLVMValue(Var)) {
return ModSet.getLLVMValue(Var);
}

return nullptr;
}

[[nodiscard]] inline const llvm::Value *
pointerNodeToLLVMOrNull(SVF::NodeID Nod, SVF::LLVMModuleSet &ModSet,
SVF::SVFIR &PAG) {

if (const SVF::SVFVar *Var = PAG.getGNode(Nod)) {
if (const auto *Val = Var->getValue()) {
if (const auto *LLVMVal = ModSet.getLLVMValue(Val)) {
return LLVMVal;
}
}
return svfVarToLLVMOrNull(Var, ModSet);
}
return nullptr;
}

[[nodiscard]] inline const llvm::Value *
objectNodeToLLVMOrNull(SVF::NodeID Nod, SVF::LLVMModuleSet &ModSet,
SVF::SVFIR &PAG) {
if (const SVF::MemObj *Mem = PAG.getObject(Nod)) {
if (const auto *Val = Mem->getValue()) {
if (const auto *LLVMVal = ModSet.getLLVMValue(Val)) {
return LLVMVal;
}
}
}
return nullptr;
return pointerNodeToLLVMOrNull(Nod, ModSet, PAG);
}

[[nodiscard]] inline SVF::NodeID getNodeId(const llvm::Value *Pointer,
SVF::LLVMModuleSet &ModSet,
SVF::SVFIR &PAG) {
auto *Nod = ModSet.getSVFValue(Pointer);
return PAG.getValueNode(Nod);
SVF::LLVMModuleSet &ModSet) {
return ModSet.getValueNode(Pointer);
}
[[nodiscard]] inline SVF::NodeID getObjNodeId(const llvm::Value *Obj,
SVF::LLVMModuleSet &ModSet,
SVF::SVFIR &PAG) {
auto *Nod = ModSet.getSVFValue(Obj);
return PAG.getObjectNode(Nod);
SVF::LLVMModuleSet &ModSet) {
return ModSet.getObjectNode(Obj);
}

} // namespace psr
Expand Down
88 changes: 40 additions & 48 deletions lib/PhasarLLVM/Pointer/SVF/SVFBasedAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "SVF-LLVM/LLVMModule.h"
#include "SVF-LLVM/SVFIRBuilder.h"
#include "SVFIR/SVFIR.h"
#include "SVFIR/SVFModule.h"
#include "SVFIR/SVFType.h"
#include "Util/GeneralType.h"
#include "WPA/Andersen.h"
Expand All @@ -36,7 +35,10 @@
#include <memory>
#include <optional>

namespace psr {
using namespace psr;

namespace {

static constexpr psr::AliasResult
translateSVFAliasResult(SVF::AliasResult AR) noexcept {
switch (AR) {
Expand All @@ -55,13 +57,14 @@ static psr::AliasResult doAliasImpl(SVF::PointerAnalysis *AA,
const llvm::Value *V,
const llvm::Value *Rep) {
auto *ModSet = SVF::LLVMModuleSet::getLLVMModuleSet();
auto *Nod1 = ModSet->getSVFValue(V);
auto *Nod2 = ModSet->getSVFValue(Rep);

if (!Nod1 || !Nod2) {
if (!ModSet->hasValueNode(V) || !ModSet->hasValueNode(Rep)) {
return AliasResult::MayAlias;
}

auto Nod1 = getNodeId(V, *ModSet);
auto Nod2 = getNodeId(Rep, *ModSet);

return translateSVFAliasResult(AA->alias(Nod1, Nod2));
}

Expand All @@ -74,13 +77,12 @@ static psr::AliasResult aliasImpl(SVF::PointerAnalysis *AA,
// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
class SVFAliasAnalysisBase : public AliasAnalysisView {
public:
SVFAliasAnalysisBase(SVF::SVFModule *Mod, AliasAnalysisType PATy)
: AliasAnalysisView(PATy), IRBuilder(Mod), PAG(IRBuilder.build()) {}
SVFAliasAnalysisBase(AliasAnalysisType PATy)
: AliasAnalysisView(PATy), PAG(IRBuilder.build()) {}

~SVFAliasAnalysisBase() override {
SVF::SVFIR::releaseSVFIR();
SVF::AndersenWaveDiff::releaseAndersenWaveDiff();
SVF::SymbolTableInfo::releaseSymbolInfo();
SVF::LLVMModuleSet::releaseLLVMModuleSet();
}

Expand All @@ -95,8 +97,8 @@ class SVFAliasAnalysisBase : public AliasAnalysisView {

class SVFVFSAnalysis : public SVFAliasAnalysisBase {
public:
SVFVFSAnalysis(SVF::SVFModule *Mod)
: SVFAliasAnalysisBase(Mod, AliasAnalysisType::SVFVFS),
SVFVFSAnalysis()
: SVFAliasAnalysisBase(AliasAnalysisType::SVFVFS),
// Note: We must use the static createVFSWPA() function, otherwise SVF
// will leak memory
VFS(SVF::VersionedFlowSensitive::createVFSWPA(PAG)) {}
Expand All @@ -121,9 +123,8 @@ class SVFVFSAnalysis : public SVFAliasAnalysisBase {

class SVFDDAAnalysis : public SVFAliasAnalysisBase {
public:
SVFDDAAnalysis(SVF::SVFModule *Mod)
: SVFAliasAnalysisBase(Mod, AliasAnalysisType::SVFVFS), Client(Mod) {
Client.initialise(Mod);
SVFDDAAnalysis() : SVFAliasAnalysisBase(AliasAnalysisType::SVFVFS) {
Client.initialise();
DDA.emplace(PAG, &Client);
DDA->initialize();
Client.answerQueries(&*DDA);
Expand All @@ -149,28 +150,6 @@ class SVFDDAAnalysis : public SVFAliasAnalysisBase {
mutable std::optional<SVF::ContextDDA> DDA;
};

} // namespace psr

auto psr::createSVFVFSAnalysis(LLVMProjectIRDB &IRDB)
-> std::unique_ptr<AliasAnalysisView> {

return std::make_unique<SVFVFSAnalysis>(psr::initSVFModule(IRDB));
}

auto psr::createSVFDDAAnalysis(LLVMProjectIRDB &IRDB)
-> std::unique_ptr<AliasAnalysisView> {

return std::make_unique<SVFDDAAnalysis>(psr::initSVFModule(IRDB));
}

namespace psr {

class SVFAliasInfoImpl;

template <>
struct AliasInfoTraits<SVFAliasInfoImpl>
: DefaultAATraits<const llvm::Value *, const llvm::Instruction *> {};

class SVFAliasInfoImpl
: public SVFDDAAnalysis,
public AnalysisPropertiesMixin<SVFAliasInfoImpl>,
Expand Down Expand Up @@ -217,9 +196,7 @@ class SVFAliasInfoImpl
Ret = Set;

auto *ModSet = SVF::LLVMModuleSet::getLLVMModuleSet();
auto *Nod = ModSet->getSVFValue(Ptr);

auto PointerNod = PAG->getValueNode(Nod);
auto PointerNod = getNodeId(Ptr, *ModSet);

createAliasSet(PointerNod, *Set, *ModSet);

Expand All @@ -235,7 +212,7 @@ class SVFAliasInfoImpl
}

auto &ModSet = *SVF::LLVMModuleSet::getLLVMModuleSet();
auto Nod = getNodeId(Ptr, ModSet, *PAG);
auto Nod = getNodeId(Ptr, ModSet);
const auto &Pts = getPTA().getPts(Nod);

const auto *VFun = AliasInfoBaseUtils::retrieveFunction(Ptr);
Expand Down Expand Up @@ -267,14 +244,14 @@ class SVFAliasInfoImpl
}

auto &ModSet = *SVF::LLVMModuleSet::getLLVMModuleSet();
auto Nod = getNodeId(Ptr, ModSet, *PAG);
auto Nod = getNodeId(Ptr, ModSet);

if (IntraProcOnly && llvm::isa<llvm::Argument>(AllocSite)) {
auto AllocSiteNod = getNodeId(AllocSite, ModSet, *PAG);
auto AllocSiteNod = getNodeId(AllocSite, ModSet);
return getPTA().alias(Nod, AllocSiteNod) != SVF::NoAlias;
}

auto AllocSiteNod = getObjNodeId(AllocSite, ModSet, *PAG);
auto AllocSiteNod = getObjNodeId(AllocSite, ModSet);
const auto &Pts = getPTA().getPts(Nod);

return Pts.test(AllocSiteNod);
Expand All @@ -285,11 +262,7 @@ class SVFAliasInfoImpl

auto &ModSet = *SVF::LLVMModuleSet::getLLVMModuleSet();
for (const auto &[Nod, Var] : *PAG) {
if (!Var->hasValue()) {
continue;
}

const auto *PointerVal = ModSet.getLLVMValue(Var->getValue());
const auto *PointerVal = svfVarToLLVMOrNull(Var, ModSet);
if (!PointerVal) {
continue;
}
Expand Down Expand Up @@ -352,8 +325,27 @@ class SVFAliasInfoImpl
AliasSetOwner<AliasSetTy>::memory_resource_type MRes;
AliasSetOwner<AliasSetTy> Owner{&MRes};
};
} // namespace

namespace psr {
template <>
struct AliasInfoTraits<SVFAliasInfoImpl>
: DefaultAATraits<const llvm::Value *, const llvm::Instruction *> {};
} // namespace psr

auto psr::createSVFVFSAnalysis(LLVMProjectIRDB &IRDB)
-> std::unique_ptr<AliasAnalysisView> {
psr::initSVFModule(IRDB);
return std::make_unique<SVFVFSAnalysis>();
}

auto psr::createSVFDDAAnalysis(LLVMProjectIRDB &IRDB)
-> std::unique_ptr<AliasAnalysisView> {
psr::initSVFModule(IRDB);
return std::make_unique<SVFDDAAnalysis>();
}

auto psr::createLLVMSVFDDAAliasInfo(LLVMProjectIRDB &IRDB) -> LLVMAliasInfo {
return std::make_unique<SVFAliasInfoImpl>(psr::initSVFModule(IRDB));
psr::initSVFModule(IRDB);
return std::make_unique<SVFAliasInfoImpl>();
}
Loading
Loading