111 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// \file10//11// Give any globals used for OpenCL block enqueue runtime handles external12// linkage so the runtime may access them. These should behave like internal13// functions for purposes of linking, but need to have an external symbol in the14// final object for the runtime to access them.15//16// TODO: This could be replaced with a new linkage type or global object17// metadata that produces an external symbol in the final object, but allows18// rename on IR linking. Alternatively if we can rely on19// GlobalValue::getGlobalIdentifier we can just make these external symbols to20// 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 31using namespace llvm;32 33namespace {34 35/// Lower enqueued blocks.36class AMDGPUExportKernelRuntimeHandlesLegacy : public ModulePass {37public:38 static char ID;39 40 explicit AMDGPUExportKernelRuntimeHandlesLegacy() : ModulePass(ID) {}41 42private:43 bool runOnModule(Module &M) override;44};45 46} // end anonymous namespace47 48char AMDGPUExportKernelRuntimeHandlesLegacy::ID = 0;49 50char &llvm::AMDGPUExportKernelRuntimeHandlesLegacyID =51 AMDGPUExportKernelRuntimeHandlesLegacy::ID;52 53INITIALIZE_PASS(AMDGPUExportKernelRuntimeHandlesLegacy, DEBUG_TYPE,54 "Externalize enqueued block runtime handles", false, false)55 56ModulePass *llvm::createAMDGPUExportKernelRuntimeHandlesLegacyPass() {57 return new AMDGPUExportKernelRuntimeHandlesLegacy();58}59 60static 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 can77 // 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 97bool AMDGPUExportKernelRuntimeHandlesLegacy::runOnModule(Module &M) {98 return exportKernelRuntimeHandles(M);99}100 101PreservedAnalyses102AMDGPUExportKernelRuntimeHandlesPass::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