#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"
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
/// 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>>;
/// 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.
/// 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;
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;
/// 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.
///
/// \p F.
void markLiveInternalFunction(const Function &F) {
assert(F.hasInternalLinkage() &&
- "Only internal linkage is assumed dead initially.");
-
- std::function<TargetLibraryInfo *(Function &)> TLIGetter =
- [&](Function &F) -> TargetLibraryInfo * { return nullptr; };
+ "Only internal linkage is assumed dead initially.");
- identifyDefaultAbstractAttributes(const_cast<Function &>(F), TLIGetter);
+ identifyDefaultAbstractAttributes(const_cast<Function &>(F));
}
/// Record that \p I is deleted after information was manifested.
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.
/// Pass (Manager) Boilerplate
/// ----------------------------------------------------------------------------
-static bool runAttributorOnModule(
- Module &M, std::function<TargetLibraryInfo *(Function &)> &TLIGetter) {
+static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
if (DisableAttributor)
return false;
// 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) {
// 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;
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();
}
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 {