xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUExportKernelRuntimeHandles.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- AMDGPUExportKernelRuntimeHandles.cpp - Lower enqueued block --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // \file
10 //
11 // Give any globals used for OpenCL block enqueue runtime handles external
12 // linkage so the runtime may access them. These should behave like internal
13 // functions for purposes of linking, but need to have an external symbol in the
14 // final object for the runtime to access them.
15 //
16 // TODO: This could be replaced with a new linkage type or global object
17 // metadata that produces an external symbol in the final object, but allows
18 // rename on IR linking. Alternatively if we can rely on
19 // GlobalValue::getGlobalIdentifier we can just make these external symbols to
20 // begin with.
21 //
22 //===----------------------------------------------------------------------===//
23 
24 #include "AMDGPUExportKernelRuntimeHandles.h"
25 #include "AMDGPU.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/Pass.h"
28 
29 #define DEBUG_TYPE "amdgpu-export-kernel-runtime-handles"
30 
31 using namespace llvm;
32 
33 namespace {
34 
35 /// Lower enqueued blocks.
36 class AMDGPUExportKernelRuntimeHandlesLegacy : public ModulePass {
37 public:
38   static char ID;
39 
AMDGPUExportKernelRuntimeHandlesLegacy()40   explicit AMDGPUExportKernelRuntimeHandlesLegacy() : ModulePass(ID) {}
41 
42 private:
43   bool runOnModule(Module &M) override;
44 };
45 
46 } // end anonymous namespace
47 
48 char AMDGPUExportKernelRuntimeHandlesLegacy::ID = 0;
49 
50 char &llvm::AMDGPUExportKernelRuntimeHandlesLegacyID =
51     AMDGPUExportKernelRuntimeHandlesLegacy::ID;
52 
53 INITIALIZE_PASS(AMDGPUExportKernelRuntimeHandlesLegacy, DEBUG_TYPE,
54                 "Externalize enqueued block runtime handles", false, false)
55 
createAMDGPUExportKernelRuntimeHandlesLegacyPass()56 ModulePass *llvm::createAMDGPUExportKernelRuntimeHandlesLegacyPass() {
57   return new AMDGPUExportKernelRuntimeHandlesLegacy();
58 }
59 
exportKernelRuntimeHandles(Module & M)60 static bool exportKernelRuntimeHandles(Module &M) {
61   bool Changed = false;
62 
63   const StringLiteral HandleSectionName(".amdgpu.kernel.runtime.handle");
64 
65   for (GlobalVariable &GV : M.globals()) {
66     if (GV.getSection() == HandleSectionName) {
67       GV.setLinkage(GlobalValue::ExternalLinkage);
68       GV.setDSOLocal(false);
69       Changed = true;
70     }
71   }
72 
73   if (!Changed)
74     return false;
75 
76   // FIXME: We shouldn't really need to export the kernel address. We can
77   // initialize the runtime handle with the kernel descriptor.
78   for (Function &F : M) {
79     if (F.getCallingConv() != CallingConv::AMDGPU_KERNEL)
80       continue;
81 
82     const MDNode *Associated = F.getMetadata(LLVMContext::MD_associated);
83     if (!Associated)
84       continue;
85 
86     auto *VM = cast<ValueAsMetadata>(Associated->getOperand(0));
87     auto *Handle = dyn_cast<GlobalObject>(VM->getValue());
88     if (Handle && Handle->getSection() == HandleSectionName) {
89       F.setLinkage(GlobalValue::ExternalLinkage);
90       F.setVisibility(GlobalValue::ProtectedVisibility);
91     }
92   }
93 
94   return Changed;
95 }
96 
runOnModule(Module & M)97 bool AMDGPUExportKernelRuntimeHandlesLegacy::runOnModule(Module &M) {
98   return exportKernelRuntimeHandles(M);
99 }
100 
101 PreservedAnalyses
run(Module & M,ModuleAnalysisManager & MAM)102 AMDGPUExportKernelRuntimeHandlesPass::run(Module &M,
103                                           ModuleAnalysisManager &MAM) {
104   if (!exportKernelRuntimeHandles(M))
105     return PreservedAnalyses::all();
106 
107   PreservedAnalyses PA;
108   PA.preserveSet<AllAnalysesOn<Function>>();
109   return PA;
110 }
111