#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstVisitor.h"
#define DEBUG_TYPE "cfl-aa"
-// -- Setting up/registering CFLAA pass -- //
-char CFLAliasAnalysis::ID = 0;
-
-INITIALIZE_AG_PASS(CFLAliasAnalysis, AliasAnalysis, "cfl-aa",
- "CFL-Based AA implementation", false, true, false)
-
-ImmutablePass *llvm::createCFLAliasAnalysisPass() {
- return new CFLAliasAnalysis();
-}
+CFLAAResult::CFLAAResult(const TargetLibraryInfo &TLI) : AAResultBase(TLI) {}
+CFLAAResult::CFLAAResult(CFLAAResult &&Arg) : AAResultBase(std::move(Arg)) {}
// \brief Information we have about a function and would like to keep around
-struct CFLAliasAnalysis::FunctionInfo {
+struct CFLAAResult::FunctionInfo {
StratifiedSets<Value *> Sets;
// Lots of functions have < 4 returns. Adjust as necessary.
SmallVector<Value *, 4> ReturnedValues;
: Sets(std::move(S)), ReturnedValues(std::move(RV)) {}
};
-CFLAliasAnalysis::CFLAliasAnalysis() : ImmutablePass(ID) {
- initializeCFLAliasAnalysisPass(*PassRegistry::getPassRegistry());
-}
-
-CFLAliasAnalysis::~CFLAliasAnalysis() {}
-
-void CFLAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AliasAnalysis::getAnalysisUsage(AU);
-}
-
-void *CFLAliasAnalysis::getAdjustedAnalysisPointer(const void *ID) {
- if (ID == &AliasAnalysis::ID)
- return (AliasAnalysis *)this;
- return this;
-}
-
// Try to go from a Value* to a Function*. Never returns nullptr.
static Optional<Function *> parentFunctionOfValue(Value *);
// \brief Gets the edges our graph should have, based on an Instruction*
class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
- CFLAliasAnalysis &AA;
+ CFLAAResult &AA;
SmallVectorImpl<Edge> &Output;
public:
- GetEdgesVisitor(CFLAliasAnalysis &AA, SmallVectorImpl<Edge> &Output)
+ GetEdgesVisitor(CFLAAResult &AA, SmallVectorImpl<Edge> &Output)
: AA(AA), Output(Output) {}
void visitInstruction(Instruction &) {
}
template <typename InstT> void visitCallLikeInst(InstT &Inst) {
+ // TODO: Add support for noalias args/all the other fun function attributes
+ // that we can tack on.
SmallVector<Function *, 4> Targets;
if (getPossibleTargets(&Inst, Targets)) {
if (tryInterproceduralAnalysis(Targets, &Inst, Inst.arg_operands()))
Output.clear();
}
+ // Because the function is opaque, we need to note that anything
+ // could have happened to the arguments, and that the result could alias
+ // just about anything, too.
+ // The goal of the loop is in part to unify many Values into one set, so we
+ // don't care if the function is void there.
for (Value *V : Inst.arg_operands())
Output.push_back(Edge(&Inst, V, EdgeType::Assign, AttrAll));
+ if (Inst.getNumArgOperands() == 0 &&
+ Inst.getType() != Type::getVoidTy(Inst.getContext()))
+ Output.push_back(Edge(&Inst, &Inst, EdgeType::Assign, AttrAll));
}
void visitCallInst(CallInst &Inst) { visitCallLikeInst(Inst); }
static EdgeType flipWeight(EdgeType);
// Gets edges of the given Instruction*, writing them to the SmallVector*.
-static void argsToEdges(CFLAliasAnalysis &, Instruction *,
- SmallVectorImpl<Edge> &);
+static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl<Edge> &);
// Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
-static void argsToEdges(CFLAliasAnalysis &, ConstantExpr *,
- SmallVectorImpl<Edge> &);
+static void argsToEdges(CFLAAResult &, ConstantExpr *, SmallVectorImpl<Edge> &);
// Gets the "Level" that one should travel in StratifiedSets
// given an EdgeType.
// Builds the graph needed for constructing the StratifiedSets for the
// given function
-static void buildGraphFrom(CFLAliasAnalysis &, Function *,
+static void buildGraphFrom(CFLAAResult &, Function *,
SmallVectorImpl<Value *> &, NodeMapT &, GraphT &);
// Gets the edges of a ConstantExpr as if it was an Instruction. This
// function also acts on any nested ConstantExprs, adding the edges
// of those to the given SmallVector as well.
-static void constexprToEdges(CFLAliasAnalysis &, ConstantExpr &,
+static void constexprToEdges(CFLAAResult &, ConstantExpr &,
SmallVectorImpl<Edge> &);
// Given an Instruction, this will add it to the graph, along with any
// %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
// addInstructionToGraph would add both the `load` and `getelementptr`
// instructions to the graph appropriately.
-static void addInstructionToGraph(CFLAliasAnalysis &, Instruction &,
+static void addInstructionToGraph(CFLAAResult &, Instruction &,
SmallVectorImpl<Value *> &, NodeMapT &,
GraphT &);
llvm_unreachable("Incomplete coverage of EdgeType enum");
}
-static void argsToEdges(CFLAliasAnalysis &Analysis, Instruction *Inst,
+static void argsToEdges(CFLAAResult &Analysis, Instruction *Inst,
SmallVectorImpl<Edge> &Output) {
assert(hasUsefulEdges(Inst) &&
"Expected instructions to have 'useful' edges");
v.visit(Inst);
}
-static void argsToEdges(CFLAliasAnalysis &Analysis, ConstantExpr *CE,
+static void argsToEdges(CFLAAResult &Analysis, ConstantExpr *CE,
SmallVectorImpl<Edge> &Output) {
assert(hasUsefulEdges(CE) && "Expected constant expr to have 'useful' edges");
GetEdgesVisitor v(Analysis, Output);
llvm_unreachable("Incomplete switch coverage");
}
-static void constexprToEdges(CFLAliasAnalysis &Analysis,
+static void constexprToEdges(CFLAAResult &Analysis,
ConstantExpr &CExprToCollapse,
SmallVectorImpl<Edge> &Results) {
SmallVector<ConstantExpr *, 4> Worklist;
}
}
-static void addInstructionToGraph(CFLAliasAnalysis &Analysis, Instruction &Inst,
+static void addInstructionToGraph(CFLAAResult &Analysis, Instruction &Inst,
SmallVectorImpl<Value *> &ReturnedValues,
NodeMapT &Map, GraphT &Graph) {
const auto findOrInsertNode = [&Map, &Graph](Value *Val) {
// buy us much that we don't already have. I'd like to add interprocedural
// analysis prior to this however, in case that somehow requires the graph
// produced by this for efficient execution
-static void buildGraphFrom(CFLAliasAnalysis &Analysis, Function *Fn,
+static void buildGraphFrom(CFLAAResult &Analysis, Function *Fn,
SmallVectorImpl<Value *> &ReturnedValues,
NodeMapT &Map, GraphT &Graph) {
for (auto &Bb : Fn->getBasicBlockList())
}
// Builds the graph + StratifiedSets for a function.
-CFLAliasAnalysis::FunctionInfo CFLAliasAnalysis::buildSetsFrom(Function *Fn) {
+CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
NodeMapT Map;
GraphT Graph;
SmallVector<Value *, 4> ReturnedValues;
return FunctionInfo(Builder.build(), std::move(ReturnedValues));
}
-void CFLAliasAnalysis::scan(Function *Fn) {
+void CFLAAResult::scan(Function *Fn) {
auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
(void)InsertPair;
assert(InsertPair.second &&
Handles.push_front(FunctionHandle(Fn, this));
}
-void CFLAliasAnalysis::evict(Function *Fn) { Cache.erase(Fn); }
+void CFLAAResult::evict(Function *Fn) { Cache.erase(Fn); }
/// \brief Ensures that the given function is available in the cache.
/// Returns the appropriate entry from the cache.
-const Optional<CFLAliasAnalysis::FunctionInfo> &
-CFLAliasAnalysis::ensureCached(Function *Fn) {
+const Optional<CFLAAResult::FunctionInfo> &
+CFLAAResult::ensureCached(Function *Fn) {
auto Iter = Cache.find(Fn);
if (Iter == Cache.end()) {
scan(Fn);
return Iter->second;
}
-AliasResult CFLAliasAnalysis::query(const MemoryLocation &LocA,
- const MemoryLocation &LocB) {
+AliasResult CFLAAResult::query(const MemoryLocation &LocA,
+ const MemoryLocation &LocB) {
auto *ValA = const_cast<Value *>(LocA.Ptr);
auto *ValB = const_cast<Value *>(LocB.Ptr);
return NoAlias;
}
-bool CFLAliasAnalysis::doInitialization(Module &M) {
- InitializeAliasAnalysis(this, &M.getDataLayout());
- return true;
+CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> *AM) {
+ return CFLAAResult(AM->getResult<TargetLibraryAnalysis>(F));
+}
+
+char CFLAA::PassID;
+
+char CFLAAWrapperPass::ID = 0;
+INITIALIZE_PASS_BEGIN(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis",
+ false, true)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_END(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis",
+ false, true)
+
+ImmutablePass *llvm::createCFLAAWrapperPass() { return new CFLAAWrapperPass(); }
+
+CFLAAWrapperPass::CFLAAWrapperPass() : ImmutablePass(ID) {
+ initializeCFLAAWrapperPassPass(*PassRegistry::getPassRegistry());
+}
+
+bool CFLAAWrapperPass::doInitialization(Module &M) {
+ Result.reset(
+ new CFLAAResult(getAnalysis<TargetLibraryInfoWrapperPass>().getTLI()));
+ return false;
+}
+
+bool CFLAAWrapperPass::doFinalization(Module &M) {
+ Result.reset();
+ return false;
+}
+
+void CFLAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
}