Skip to content

Weak Update LLVMBasedAliasAnalysis #626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 15, 2023
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
2 changes: 1 addition & 1 deletion include/phasar/ControlFlow/CallGraphAnalysisType.def
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ CALL_GRAPH_ANALYSIS_TYPE(CHA, "cha", "Class hierarchy analysis")
CALL_GRAPH_ANALYSIS_TYPE(RTA, "rta", "Rapid type analysis")
CALL_GRAPH_ANALYSIS_TYPE(DTA, "dta", "Declared type analysis")
CALL_GRAPH_ANALYSIS_TYPE(VTA, "vta", "Variable type analysis")
CALL_GRAPH_ANALYSIS_TYPE(OTF, "otf", "On-the-fly analysis based on points-to info")
CALL_GRAPH_ANALYSIS_TYPE(OTF, "otf", "On-the-fly analysis based on points-to info (default)")

#undef CALL_GRAPH_ANALYSIS_TYPE
45 changes: 26 additions & 19 deletions include/phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
#include "phasar/Pointer/AliasAnalysisType.h"

#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"

namespace llvm {
class Value;
Expand All @@ -27,23 +25,19 @@ namespace psr {
class LLVMProjectIRDB;

class LLVMBasedAliasAnalysis {
private:
llvm::PassBuilder PB;
llvm::AAManager AA;
llvm::FunctionAnalysisManager FAM;
llvm::FunctionPassManager FPM;
llvm::DenseMap<const llvm::Function *, llvm::AAResults *> AAInfos;
AliasAnalysisType PATy;

[[nodiscard]] bool hasAliasInfo(const llvm::Function &Fun) const;

void computeAliasInfo(llvm::Function &Fun);

public:
LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation = true,
AliasAnalysisType PATy = AliasAnalysisType::CFLAnders);
explicit LLVMBasedAliasAnalysis(
LLVMProjectIRDB &IRDB, bool UseLazyEvaluation,
AliasAnalysisType PATy = AliasAnalysisType::Basic);

~LLVMBasedAliasAnalysis() = default;
LLVMBasedAliasAnalysis(LLVMBasedAliasAnalysis &&) noexcept = default;
LLVMBasedAliasAnalysis &
operator=(LLVMBasedAliasAnalysis &&) noexcept = default;

LLVMBasedAliasAnalysis(const LLVMBasedAliasAnalysis &) = delete;
LLVMBasedAliasAnalysis &operator=(const LLVMBasedAliasAnalysis &) = delete;
~LLVMBasedAliasAnalysis();

void print(llvm::raw_ostream &OS = llvm::outs()) const;

Expand All @@ -54,13 +48,26 @@ class LLVMBasedAliasAnalysis {
return AAInfos.lookup(F);
};

void erase(llvm::Function *F);
void erase(llvm::Function *F) noexcept;

void clear();
void clear() noexcept;

[[nodiscard]] inline AliasAnalysisType getPointerAnalysisType() const {
[[nodiscard]] inline AliasAnalysisType
getPointerAnalysisType() const noexcept {
return PATy;
};

private:
[[nodiscard]] bool hasAliasInfo(const llvm::Function &Fun) const;

void computeAliasInfo(llvm::Function &Fun);

// -- data members

struct Impl;
std::unique_ptr<Impl> PImpl;
AliasAnalysisType PATy;
llvm::DenseMap<const llvm::Function *, llvm::AAResults *> AAInfos;
};

} // namespace psr
Expand Down
1 change: 1 addition & 0 deletions include/phasar/PhasarLLVM/Utils/BasicBlockOrdering.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/IR/Dominators.h"

#include <memory>
#include <type_traits>
Expand Down
3 changes: 2 additions & 1 deletion include/phasar/Pointer/AliasAnalysisType.def
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, DESC)
#endif

ALIAS_ANALYSIS_TYPE(Basic, "basic", "Basic LLVM alias resolving based on simple, local properties")
ALIAS_ANALYSIS_TYPE(CFLSteens, "cflsteens", "Steensgaard-style alias analysis (equality-based)")
ALIAS_ANALYSIS_TYPE(CFLAnders, "cflanders", "Andersen-style alias analysis (subset-based)")
ALIAS_ANALYSIS_TYPE(CFLAnders, "cflanders", "Andersen-style alias analysis (subset-based) (default)")
ALIAS_ANALYSIS_TYPE(PointsTo, "points-to", "Alias-information based on (external) points-to information")

#undef ALIAS_ANALYSIS_TYPE
3 changes: 2 additions & 1 deletion lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h"
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
#include "phasar/Pointer/AliasAnalysisType.h"
#include "phasar/Utils/BoxedPointer.h"
#include "phasar/Utils/Logger.h"
#include "phasar/Utils/NlohmannLogging.h"
Expand Down Expand Up @@ -96,7 +97,7 @@ LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, bool UseLazyEvaluation,

LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedPTS)
: PTA(*IRDB) {
: PTA(*IRDB, true) {
assert(IRDB != nullptr);
// Assume, we already have validated the json schema

Expand Down
69 changes: 45 additions & 24 deletions lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h"
#include "phasar/Pointer/AliasAnalysisType.h"

#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
Expand All @@ -19,6 +20,7 @@
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
Expand All @@ -28,11 +30,18 @@
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Passes/PassBuilder.h"

using namespace psr;

namespace psr {

struct LLVMBasedAliasAnalysis::Impl {
llvm::PassBuilder PB{};
llvm::FunctionAnalysisManager FAM{};
llvm::FunctionPassManager FPM{};
};

static void printResults(llvm::AliasResult AR, bool P, const llvm::Value *V1,
const llvm::Value *V2, const llvm::Module *M) {
if (P) {
Expand Down Expand Up @@ -88,44 +97,54 @@ bool LLVMBasedAliasAnalysis::hasAliasInfo(const llvm::Function &Fun) const {
}

void LLVMBasedAliasAnalysis::computeAliasInfo(llvm::Function &Fun) {
llvm::PreservedAnalyses PA = FPM.run(Fun, FAM);
llvm::AAResults &AAR = FAM.getResult<llvm::AAManager>(Fun);
assert(PImpl != nullptr);
llvm::PreservedAnalyses PA = PImpl->FPM.run(Fun, PImpl->FAM);
llvm::AAResults &AAR = PImpl->FAM.getResult<llvm::AAManager>(Fun);
AAInfos.insert(std::make_pair(&Fun, &AAR));
}

void LLVMBasedAliasAnalysis::erase(llvm::Function *F) {
void LLVMBasedAliasAnalysis::erase(llvm::Function *F) noexcept {
// after we clear all stuff, we need to set it up for the next function-wise
// analysis
AAInfos.erase(F);
FAM.clear(*F, F->getName());
PImpl->FAM.clear(*F, F->getName());
}

void LLVMBasedAliasAnalysis::clear() {
void LLVMBasedAliasAnalysis::clear() noexcept {
AAInfos.clear();
FAM.clear();
PImpl->FAM.clear();
}

LLVMBasedAliasAnalysis::LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB,
bool UseLazyEvaluation,
AliasAnalysisType PATy)
: PATy(PATy) {
AA.registerFunctionAnalysis<llvm::BasicAA>();
switch (PATy) {
case AliasAnalysisType::CFLAnders:
AA.registerFunctionAnalysis<llvm::CFLAndersAA>();
break;
case AliasAnalysisType::CFLSteens:
AA.registerFunctionAnalysis<llvm::CFLSteensAA>();
break;
default:
break;
}
AA.registerFunctionAnalysis<llvm::TypeBasedAA>();
FAM.registerPass([&] { return std::move(AA); });
PB.registerFunctionAnalyses(FAM);
llvm::FunctionPassManager FPM;
// Always verify the input.
FPM.addPass(llvm::VerifierPass());
: PImpl(new Impl{}), PATy(PATy) {

PImpl->FAM.registerPass([&] {
llvm::AAManager AA;
switch (PATy) {
case AliasAnalysisType::CFLAnders:
AA.registerFunctionAnalysis<llvm::CFLAndersAA>();
break;
case AliasAnalysisType::CFLSteens:
AA.registerFunctionAnalysis<llvm::CFLSteensAA>();
break;
case AliasAnalysisType::Basic:
[[fallthrough]];
default:
break;
}
// Note: The order of the alias analyses is important. See LLVM's source
// code for reference (e.g. registerAAAnalyses() in
// llvm/CodeGen/CodeGenPassBuilder.h)
//
AA.registerFunctionAnalysis<llvm::TypeBasedAA>();
AA.registerFunctionAnalysis<llvm::ScopedNoAliasAA>();
AA.registerFunctionAnalysis<llvm::BasicAA>();
return AA;
});
PImpl->PB.registerFunctionAnalyses(PImpl->FAM);

if (!UseLazyEvaluation) {
for (auto &F : *IRDB.getModule()) {
if (!F.isDeclaration()) {
Expand All @@ -135,6 +154,8 @@ LLVMBasedAliasAnalysis::LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB,
}
}

LLVMBasedAliasAnalysis::~LLVMBasedAliasAnalysis() = default;

void LLVMBasedAliasAnalysis::print(llvm::raw_ostream &OS) const {
OS << "Points-to Info:\n";
for (const auto &[Fn, AA] : AAInfos) {
Expand Down
1 change: 0 additions & 1 deletion lib/PhasarLLVM/Utils/BasicBlockOrdering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"

Expand Down