Skip to content

Commit

Permalink
Small refactoring of LLVMBasedAliasAnalysis + allow disabling the CFL…
Browse files Browse the repository at this point in the history
…-based alias analyses (#626)
  • Loading branch information
fabianbs96 authored Jun 15, 2023
1 parent 2b4ec1c commit 263ef58
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 47 deletions.
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

0 comments on commit 263ef58

Please sign in to comment.