[Attributor] Create helper struct for handling analysis getters

Summary: This patch introduces a helper struct `AnalysisGetter` to put together analysis getters. In this patch, a getter for `AAResult` is also added for  `noalias`.

Reviewers: jdoerfert, sstefan1

Reviewed By: jdoerfert

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67603

llvm-svn: 372072
This commit is contained in:
Hideto Ueno 2019-09-17 05:45:18 +00:00
parent 73f2dbb7d2
commit 3bb5cbc20b
2 changed files with 37 additions and 31 deletions

View File

@ -97,6 +97,7 @@
#define LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/IR/CallSite.h"
@ -519,6 +520,21 @@ public:
iterator end() { return IRPositions.end(); }
};
/// Wrapper for FunctoinAnalysisManager.
struct AnalysisGetter {
template <typename Analysis>
typename Analysis::Result *getAnalysis(const Function &F) {
if (!FAM)
return nullptr;
return &FAM->getResult<Analysis>(const_cast<Function &>(F));
}
AnalysisGetter(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
AnalysisGetter() {}
private:
FunctionAnalysisManager *FAM = nullptr;
};
/// Data structure to hold cached (LLVM-IR) information.
///
/// All attributes are given an InformationCache object at creation time to
@ -532,7 +548,7 @@ public:
/// reusable, it is advised to inherit from the InformationCache and cast the
/// instance down in the abstract attributes.
struct InformationCache {
InformationCache(const DataLayout &DL) : DL(DL) {}
InformationCache(const DataLayout &DL, AnalysisGetter &AG) : DL(DL), AG(AG) {}
/// A map type from opcodes to instructions with this opcode.
using OpcodeInstMapTy = DenseMap<unsigned, SmallVector<Instruction *, 32>>;
@ -553,7 +569,12 @@ struct InformationCache {
/// Return TargetLibraryInfo for function \p F.
TargetLibraryInfo *getTargetLibraryInfoForFunction(const Function &F) {
return FuncTLIMap[&F];
return AG.getAnalysis<TargetLibraryAnalysis>(F);
}
/// Return AliasAnalysis Result for function \p F.
AAResults *getAAResultsForFunction(const Function &F) {
return AG.getAnalysis<AAManager>(F);
}
/// Return datalayout used in the module.
@ -566,9 +587,6 @@ private:
/// A map type from functions to their read or write instructions.
using FuncRWInstsMapTy = DenseMap<const Function *, InstructionVectorTy>;
/// A map type from functions to their TLI.
using FuncTLIMapTy = DenseMap<const Function *, TargetLibraryInfo *>;
/// A nested map that remembers all instructions in a function with a certain
/// instruction opcode (Instruction::getOpcode()).
FuncInstOpcodeMapTy FuncInstOpcodeMap;
@ -577,11 +595,13 @@ private:
FuncRWInstsMapTy FuncRWInstsMap;
/// A map from functions to their TLI.
FuncTLIMapTy FuncTLIMap;
/// The datalayout used in the module.
const DataLayout &DL;
/// Getters for analysis.
AnalysisGetter &AG;
/// Give the Attributor access to the members so
/// Attributor::identifyDefaultAbstractAttributes(...) can initialize them.
friend struct Attributor;
@ -711,8 +731,7 @@ struct Attributor {
/// reason for this is the single interface, the one of the abstract attribute
/// instance, which can be queried without the need to look at the IR in
/// various places.
void identifyDefaultAbstractAttributes(
Function &F, std::function<TargetLibraryInfo *(Function &)> &TLIGetter);
void identifyDefaultAbstractAttributes(Function &F);
/// Mark the internal function \p F as live.
///
@ -720,12 +739,9 @@ struct Attributor {
/// \p F.
void markLiveInternalFunction(const Function &F) {
assert(F.hasInternalLinkage() &&
"Only internal linkage is assumed dead initially.");
"Only internal linkage is assumed dead initially.");
std::function<TargetLibraryInfo *(Function &)> TLIGetter =
[&](Function &F) -> TargetLibraryInfo * { return nullptr; };
identifyDefaultAbstractAttributes(const_cast<Function &>(F), TLIGetter);
identifyDefaultAbstractAttributes(const_cast<Function &>(F));
}
/// Record that \p I is deleted after information was manifested.

View File

@ -3845,14 +3845,10 @@ ChangeStatus Attributor::run(Module &M) {
return ManifestChange;
}
void Attributor::identifyDefaultAbstractAttributes(
Function &F, std::function<TargetLibraryInfo *(Function &)> &TLIGetter) {
void Attributor::identifyDefaultAbstractAttributes(Function &F) {
if (!VisitedFunctions.insert(&F).second)
return;
if (EnableHeapToStack)
InfoCache.FuncTLIMap[&F] = TLIGetter(F);
IRPosition FPos = IRPosition::function(F);
// Check for dead BasicBlocks in every function.
@ -4063,8 +4059,7 @@ void AbstractAttribute::print(raw_ostream &OS) const {
/// Pass (Manager) Boilerplate
/// ----------------------------------------------------------------------------
static bool runAttributorOnModule(
Module &M, std::function<TargetLibraryInfo *(Function &)> &TLIGetter) {
static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
if (DisableAttributor)
return false;
@ -4073,7 +4068,7 @@ static bool runAttributorOnModule(
// Create an Attributor and initially empty information cache that is filled
// while we identify default attribute opportunities.
InformationCache InfoCache(M.getDataLayout());
InformationCache InfoCache(M.getDataLayout(), AG);
Attributor A(InfoCache, DepRecInterval);
for (Function &F : M) {
@ -4099,7 +4094,7 @@ static bool runAttributorOnModule(
// Populate the Attributor with abstract attribute opportunities in the
// function and the information cache with IR information.
A.identifyDefaultAbstractAttributes(F, TLIGetter);
A.identifyDefaultAbstractAttributes(F);
}
return A.run(M) == ChangeStatus::CHANGED;
@ -4108,12 +4103,8 @@ static bool runAttributorOnModule(
PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
std::function<TargetLibraryInfo *(Function &)> TLIGetter =
[&](Function &F) -> TargetLibraryInfo * {
return &FAM.getResult<TargetLibraryAnalysis>(F);
};
if (runAttributorOnModule(M, TLIGetter)) {
AnalysisGetter AG(FAM);
if (runAttributorOnModule(M, AG)) {
// FIXME: Think about passes we will preserve and add them here.
return PreservedAnalyses::none();
}
@ -4132,10 +4123,9 @@ struct AttributorLegacyPass : public ModulePass {
bool runOnModule(Module &M) override {
if (skipModule(M))
return false;
std::function<TargetLibraryInfo *(Function &)> TLIGetter =
[&](Function &F) -> TargetLibraryInfo * { return nullptr; };
return runAttributorOnModule(M, TLIGetter);
AnalysisGetter AG;
return runAttributorOnModule(M, AG);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {