diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp @@ -186,6 +186,7 @@ #include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" @@ -199,6 +200,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/OptimizedStructLayout.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -331,10 +333,28 @@ } public: + TargetMachine *TM = nullptr; static char ID; - AMDGPULowerModuleLDS() : ModulePass(ID) { + AMDGPULowerModuleLDS() + : ModulePass(ID) + + { + fprintf(stderr, "Called LowerModuleLDS constructor\n"); initializeAMDGPULowerModuleLDSPass(*PassRegistry::getPassRegistry()); + + // Asserts + // assert(PI && "getAnalysis for unregistered pass!"); + // Can change to getAnalysisIfAvailable, which asserts + // assert(Resolver && "Pass not resident in a PassManager object!"); + // Thus... how do I get at the TargetMachine from a ModulePass? + +#if 0 + fprintf(stderr, "Constructor\n"); + // This crashes in old and new pass manager at present + auto *TPC = getAnalysisIfAvailable(); + fprintf(stderr, "Constructor done\n"); +#endif } using FunctionVariableMap = DenseMap>; @@ -1101,7 +1121,33 @@ return KernelToCreatedDynamicLDS; } + bool doInitialization(Module &) override { + // When called as -amdgpu-lower-module-lds, this function runs and sets up + // TM When called as -passes=amdgpu-lower-module-lds, this function does not + // run + auto *TPC = getAnalysisIfAvailable(); + if (!TPC) + report_fatal_error("TargetMachine is required"); + + TM = &TPC->getTM(); + + fprintf(stderr, "doInitialization ran\n"); + return false; + } + bool runOnModule(Module &M) override { + + fprintf(stderr, "calling runOnModule\n"); + + auto *TPC = getAnalysisIfAvailable(); + if (!TPC) + report_fatal_error( + "TargetMachine get if available failed in runonmodule"); + + if (!TM) { + report_fatal_error("TargetMachine is required by runOnModule"); + } + CallGraph CG = CallGraph(M); bool Changed = superAlignLDSGlobals(M); @@ -1268,6 +1314,11 @@ return Changed; } + void getAnalysisUsage(AnalysisUsage &AU) const override { + fprintf(stderr, "Called getAnalysisUsage\n"); + AU.addRequired(); + } + private: // Increase the alignment of LDS globals if necessary to maximise the chance // that we can use aligned LDS instructions to access them. @@ -1533,16 +1584,24 @@ char &llvm::AMDGPULowerModuleLDSID = AMDGPULowerModuleLDS::ID; -INITIALIZE_PASS(AMDGPULowerModuleLDS, DEBUG_TYPE, - "Lower uses of LDS variables from non-kernel functions", false, - false) +INITIALIZE_PASS_BEGIN(AMDGPULowerModuleLDS, DEBUG_TYPE, + "Lower uses of LDS variables from non-kernel functions", + false, false) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) +INITIALIZE_PASS_END(AMDGPULowerModuleLDS, DEBUG_TYPE, + "Lower uses of LDS variables from non-kernel functions", + false, false) ModulePass *llvm::createAMDGPULowerModuleLDSPass() { return new AMDGPULowerModuleLDS(); } PreservedAnalyses AMDGPULowerModuleLDSPass::run(Module &M, - ModuleAnalysisManager &) { + ModuleAnalysisManager &AM) { + fprintf(stderr, "LDSPass::run\n"); + // Docs suggest this, but it doesn't compile + // No type named result + auto wot = AM.getResult(M); return AMDGPULowerModuleLDS().runOnModule(M) ? PreservedAnalyses::none() : PreservedAnalyses::all(); }