mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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:
parent
a2114177f9
commit
e89a3c1190
@ -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.
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user