From 3bb5cbc20b57116693ac667e803110fa06173cff Mon Sep 17 00:00:00 2001 From: Hideto Ueno Date: Tue, 17 Sep 2019 05:45:18 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/Transforms/IPO/Attributor.h | 42 +++++++++++++------ llvm/lib/Transforms/IPO/Attributor.cpp | 26 ++++-------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 266eb02a3185..95cc07d31b34 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -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::Result *getAnalysis(const Function &F) { + if (!FAM) + return nullptr; + return &FAM->getResult(const_cast(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>; @@ -553,7 +569,12 @@ struct InformationCache { /// Return TargetLibraryInfo for function \p F. TargetLibraryInfo *getTargetLibraryInfoForFunction(const Function &F) { - return FuncTLIMap[&F]; + return AG.getAnalysis(F); + } + + /// Return AliasAnalysis Result for function \p F. + AAResults *getAAResultsForFunction(const Function &F) { + return AG.getAnalysis(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; - /// A map type from functions to their TLI. - using FuncTLIMapTy = DenseMap; - /// 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 &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 TLIGetter = - [&](Function &F) -> TargetLibraryInfo * { return nullptr; }; - - identifyDefaultAbstractAttributes(const_cast(F), TLIGetter); + identifyDefaultAbstractAttributes(const_cast(F)); } /// Record that \p I is deleted after information was manifested. diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 9d0e978432e0..90b0772a869d 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -3845,14 +3845,10 @@ ChangeStatus Attributor::run(Module &M) { return ManifestChange; } -void Attributor::identifyDefaultAbstractAttributes( - Function &F, std::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 &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(M).getManager(); - std::function TLIGetter = - [&](Function &F) -> TargetLibraryInfo * { - return &FAM.getResult(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 TLIGetter = - [&](Function &F) -> TargetLibraryInfo * { return nullptr; }; - return runAttributorOnModule(M, TLIGetter); + AnalysisGetter AG; + return runAttributorOnModule(M, AG); } void getAnalysisUsage(AnalysisUsage &AU) const override {