Index: llvm/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/include/llvm/Transforms/IPO/Attributor.h +++ 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,33 @@ iterator end() { return IRPositions.end(); } }; +/// Helper class for handling analysis getters. +struct AnalysisGetter { + + /// A map type from functions to their TLI. + using FuncTLIMapTy = std::function; + FuncTLIMapTy FuncTLIMap; + + /// A map type from functions to their Alias Analysis. + using FuncAARMapTy = std::function; + FuncAARMapTy FuncAARMap; + + AnalysisGetter(FuncTLIMapTy &FuncTLIMap, FuncAARMapTy &FuncAARMap) + : FuncTLIMap(FuncTLIMap), FuncAARMap(FuncAARMap) {} + + AnalysisGetter() + : FuncTLIMap(getDummyGetter()), + FuncAARMap(getDummyGetter()) {} + + // Helper function for creating a function which returns nullptr. + template static std::function getDummyGetter() { + std::function Dummy = [](const Function *) -> T * { + return nullptr; + }; + return Dummy; + } +}; + /// Data structure to hold cached (LLVM-IR) information. /// /// All attributes are given an InformationCache object at creation time to @@ -532,7 +560,8 @@ /// 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, const AnalysisGetter &AG) + : DL(DL), AG(AG) {} /// A map type from opcodes to instructions with this opcode. using OpcodeInstMapTy = DenseMap>; @@ -553,7 +582,12 @@ /// Return TargetLibraryInfo for function \p F. TargetLibraryInfo *getTargetLibraryInfoForFunction(const Function &F) { - return FuncTLIMap[&F]; + return AG.FuncTLIMap(&F); + } + + /// Return AliasAnalysis Result for function \p F. + AAResults *getAAResultsForFunction(const Function &F) { + return AG.FuncAARMap(&F); } /// Return datalayout used in the module. @@ -566,9 +600,6 @@ /// 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 +608,13 @@ FuncRWInstsMapTy FuncRWInstsMap; /// A map from functions to their TLI. - FuncTLIMapTy FuncTLIMap; /// The datalayout used in the module. const DataLayout &DL; + /// Getters for analysis. + const AnalysisGetter &AG; + /// Give the Attributor access to the members so /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them. friend struct Attributor; @@ -711,8 +744,7 @@ /// 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 +752,9 @@ /// \p F. void markLiveInternalFunction(const Function &F) { assert(F.hasInternalLinkage() && - "Only internal linkage is assumed dead initially."); - - std::function TLIGetter = - [&](Function &F) -> TargetLibraryInfo * { return nullptr; }; + "Only internal linkage is assumed dead initially."); - identifyDefaultAbstractAttributes(const_cast(F), TLIGetter); + identifyDefaultAbstractAttributes(const_cast(F)); } /// Record that \p I is deleted after information was manifested. Index: llvm/lib/Transforms/IPO/Attributor.cpp =================================================================== --- llvm/lib/Transforms/IPO/Attributor.cpp +++ llvm/lib/Transforms/IPO/Attributor.cpp @@ -3845,14 +3845,10 @@ 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 @@ /// 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 @@ // 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 @@ // 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,17 @@ PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) { auto &FAM = AM.getResult(M).getManager(); - std::function TLIGetter = - [&](Function &F) -> TargetLibraryInfo * { - return &FAM.getResult(F); + AnalysisGetter::FuncTLIMapTy TLIGetter = + [&](const Function *F) -> TargetLibraryInfo * { + return &FAM.getResult(const_cast(*F)); + }; + AnalysisGetter::FuncAARMapTy AARGetter = + [&](const Function *F) -> AAResults * { + return &FAM.getResult(const_cast(*F)); }; - if (runAttributorOnModule(M, TLIGetter)) { + AnalysisGetter AG(TLIGetter, AARGetter); + if (runAttributorOnModule(M, AG)) { // FIXME: Think about passes we will preserve and add them here. return PreservedAnalyses::none(); } @@ -4132,10 +4132,9 @@ 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 {