13931948bSMatt Arsenault //===-- AMDGPUAnnotateKernelFeaturesPass.cpp ------------------------------===// 23931948bSMatt Arsenault // 33931948bSMatt Arsenault // The LLVM Compiler Infrastructure 43931948bSMatt Arsenault // 53931948bSMatt Arsenault // This file is distributed under the University of Illinois Open Source 63931948bSMatt Arsenault // License. See LICENSE.TXT for details. 73931948bSMatt Arsenault // 83931948bSMatt Arsenault //===----------------------------------------------------------------------===// 93931948bSMatt Arsenault // 103931948bSMatt Arsenault /// \file This pass adds target attributes to functions which use intrinsics 113931948bSMatt Arsenault /// which will impact calling convention lowering. 123931948bSMatt Arsenault // 133931948bSMatt Arsenault //===----------------------------------------------------------------------===// 143931948bSMatt Arsenault 153931948bSMatt Arsenault #include "AMDGPU.h" 163931948bSMatt Arsenault #include "llvm/IR/Instructions.h" 173931948bSMatt Arsenault #include "llvm/IR/Module.h" 183931948bSMatt Arsenault 193931948bSMatt Arsenault #define DEBUG_TYPE "amdgpu-annotate-kernel-features" 203931948bSMatt Arsenault 213931948bSMatt Arsenault using namespace llvm; 223931948bSMatt Arsenault 233931948bSMatt Arsenault namespace { 243931948bSMatt Arsenault 253931948bSMatt Arsenault class AMDGPUAnnotateKernelFeatures : public ModulePass { 263931948bSMatt Arsenault private: 273931948bSMatt Arsenault void addAttrToCallers(Function *Intrin, StringRef AttrName); 283931948bSMatt Arsenault bool addAttrsForIntrinsics(Module &M, ArrayRef<StringRef[2]>); 293931948bSMatt Arsenault 303931948bSMatt Arsenault public: 313931948bSMatt Arsenault static char ID; 323931948bSMatt Arsenault 333931948bSMatt Arsenault AMDGPUAnnotateKernelFeatures() : ModulePass(ID) { } 343931948bSMatt Arsenault bool runOnModule(Module &M) override; 353931948bSMatt Arsenault const char *getPassName() const override { 363931948bSMatt Arsenault return "AMDGPU Annotate Kernel Features"; 373931948bSMatt Arsenault } 383931948bSMatt Arsenault 393931948bSMatt Arsenault void getAnalysisUsage(AnalysisUsage &AU) const override { 403931948bSMatt Arsenault AU.setPreservesAll(); 413931948bSMatt Arsenault ModulePass::getAnalysisUsage(AU); 423931948bSMatt Arsenault } 433931948bSMatt Arsenault }; 443931948bSMatt Arsenault 453931948bSMatt Arsenault } 463931948bSMatt Arsenault 473931948bSMatt Arsenault char AMDGPUAnnotateKernelFeatures::ID = 0; 483931948bSMatt Arsenault 493931948bSMatt Arsenault char &llvm::AMDGPUAnnotateKernelFeaturesID = AMDGPUAnnotateKernelFeatures::ID; 503931948bSMatt Arsenault 513931948bSMatt Arsenault 523931948bSMatt Arsenault INITIALIZE_PASS_BEGIN(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE, 533931948bSMatt Arsenault "Add AMDGPU function attributes", false, false) 543931948bSMatt Arsenault INITIALIZE_PASS_END(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE, 553931948bSMatt Arsenault "Add AMDGPU function attributes", false, false) 563931948bSMatt Arsenault 573931948bSMatt Arsenault 583931948bSMatt Arsenault void AMDGPUAnnotateKernelFeatures::addAttrToCallers(Function *Intrin, 593931948bSMatt Arsenault StringRef AttrName) { 603931948bSMatt Arsenault SmallPtrSet<Function *, 4> SeenFuncs; 613931948bSMatt Arsenault 623931948bSMatt Arsenault for (User *U : Intrin->users()) { 633931948bSMatt Arsenault // CallInst is the only valid user for an intrinsic. 643931948bSMatt Arsenault CallInst *CI = cast<CallInst>(U); 653931948bSMatt Arsenault 663931948bSMatt Arsenault Function *CallingFunction = CI->getParent()->getParent(); 673931948bSMatt Arsenault if (SeenFuncs.insert(CallingFunction).second) 683931948bSMatt Arsenault CallingFunction->addFnAttr(AttrName); 693931948bSMatt Arsenault } 703931948bSMatt Arsenault } 713931948bSMatt Arsenault 723931948bSMatt Arsenault bool AMDGPUAnnotateKernelFeatures::addAttrsForIntrinsics( 733931948bSMatt Arsenault Module &M, 743931948bSMatt Arsenault ArrayRef<StringRef[2]> IntrinsicToAttr) { 753931948bSMatt Arsenault bool Changed = false; 763931948bSMatt Arsenault 773931948bSMatt Arsenault for (const StringRef *Arr : IntrinsicToAttr) { 783931948bSMatt Arsenault if (Function *Fn = M.getFunction(Arr[0])) { 793931948bSMatt Arsenault addAttrToCallers(Fn, Arr[1]); 803931948bSMatt Arsenault Changed = true; 813931948bSMatt Arsenault } 823931948bSMatt Arsenault } 833931948bSMatt Arsenault 843931948bSMatt Arsenault return Changed; 853931948bSMatt Arsenault } 863931948bSMatt Arsenault 873931948bSMatt Arsenault bool AMDGPUAnnotateKernelFeatures::runOnModule(Module &M) { 883931948bSMatt Arsenault Triple TT(M.getTargetTriple()); 893931948bSMatt Arsenault 903931948bSMatt Arsenault static const StringRef IntrinsicToAttr[][2] = { 913931948bSMatt Arsenault // .x omitted 9243976df0SMatt Arsenault { "llvm.amdgcn.workitem.id.y", "amdgpu-work-item-id-y" }, 9343976df0SMatt Arsenault { "llvm.amdgcn.workitem.id.z", "amdgpu-work-item-id-z" }, 9443976df0SMatt Arsenault 9543976df0SMatt Arsenault { "llvm.amdgcn.workgroup.id.y", "amdgpu-work-group-id-y" }, 9643976df0SMatt Arsenault { "llvm.amdgcn.workgroup.id.z", "amdgpu-work-group-id-z" }, 9743976df0SMatt Arsenault 983931948bSMatt Arsenault { "llvm.r600.read.tgid.y", "amdgpu-work-group-id-y" }, 993931948bSMatt Arsenault { "llvm.r600.read.tgid.z", "amdgpu-work-group-id-z" }, 1003931948bSMatt Arsenault 1013931948bSMatt Arsenault // .x omitted 1023931948bSMatt Arsenault { "llvm.r600.read.tidig.y", "amdgpu-work-item-id-y" }, 1033931948bSMatt Arsenault { "llvm.r600.read.tidig.z", "amdgpu-work-item-id-z" } 1043931948bSMatt Arsenault }; 1053931948bSMatt Arsenault 1063931948bSMatt Arsenault static const StringRef HSAIntrinsicToAttr[][2] = { 10748f29f21STom Stellard { "llvm.amdgcn.dispatch.ptr", "amdgpu-dispatch-ptr" } 1083931948bSMatt Arsenault }; 1093931948bSMatt Arsenault 110*d0799df7SMatt Arsenault // TODO: We should not add the attributes if the known compile time workgroup 111*d0799df7SMatt Arsenault // size is 1 for y/z. 112*d0799df7SMatt Arsenault 1133931948bSMatt Arsenault // TODO: Intrinsics that require queue ptr. 1143931948bSMatt Arsenault 1153931948bSMatt Arsenault // We do not need to note the x workitem or workgroup id because they are 1163931948bSMatt Arsenault // always initialized. 1173931948bSMatt Arsenault 1183931948bSMatt Arsenault bool Changed = addAttrsForIntrinsics(M, IntrinsicToAttr); 1193931948bSMatt Arsenault if (TT.getOS() == Triple::AMDHSA) 1203931948bSMatt Arsenault Changed |= addAttrsForIntrinsics(M, HSAIntrinsicToAttr); 1213931948bSMatt Arsenault 1223931948bSMatt Arsenault return Changed; 1233931948bSMatt Arsenault } 1243931948bSMatt Arsenault 1253931948bSMatt Arsenault ModulePass *llvm::createAMDGPUAnnotateKernelFeaturesPass() { 1263931948bSMatt Arsenault return new AMDGPUAnnotateKernelFeatures(); 1273931948bSMatt Arsenault } 128