AMDGPUAnnotateKernelFeatures.cpp revision 292915
1//===-- AMDGPUAnnotateKernelFeaturesPass.cpp ------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10/// \file This pass adds target attributes to functions which use intrinsics 11/// which will impact calling convention lowering. 12// 13//===----------------------------------------------------------------------===// 14 15#include "AMDGPU.h" 16#include "llvm/IR/Instructions.h" 17#include "llvm/IR/Module.h" 18 19#define DEBUG_TYPE "amdgpu-annotate-kernel-features" 20 21using namespace llvm; 22 23namespace { 24 25class AMDGPUAnnotateKernelFeatures : public ModulePass { 26private: 27 void addAttrToCallers(Function *Intrin, StringRef AttrName); 28 bool addAttrsForIntrinsics(Module &M, ArrayRef<StringRef[2]>); 29 30public: 31 static char ID; 32 33 AMDGPUAnnotateKernelFeatures() : ModulePass(ID) { } 34 bool runOnModule(Module &M) override; 35 const char *getPassName() const override { 36 return "AMDGPU Annotate Kernel Features"; 37 } 38 39 void getAnalysisUsage(AnalysisUsage &AU) const override { 40 AU.setPreservesAll(); 41 ModulePass::getAnalysisUsage(AU); 42 } 43}; 44 45} 46 47char AMDGPUAnnotateKernelFeatures::ID = 0; 48 49char &llvm::AMDGPUAnnotateKernelFeaturesID = AMDGPUAnnotateKernelFeatures::ID; 50 51 52INITIALIZE_PASS_BEGIN(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE, 53 "Add AMDGPU function attributes", false, false) 54INITIALIZE_PASS_END(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE, 55 "Add AMDGPU function attributes", false, false) 56 57 58void AMDGPUAnnotateKernelFeatures::addAttrToCallers(Function *Intrin, 59 StringRef AttrName) { 60 SmallPtrSet<Function *, 4> SeenFuncs; 61 62 for (User *U : Intrin->users()) { 63 // CallInst is the only valid user for an intrinsic. 64 CallInst *CI = cast<CallInst>(U); 65 66 Function *CallingFunction = CI->getParent()->getParent(); 67 if (SeenFuncs.insert(CallingFunction).second) 68 CallingFunction->addFnAttr(AttrName); 69 } 70} 71 72bool AMDGPUAnnotateKernelFeatures::addAttrsForIntrinsics( 73 Module &M, 74 ArrayRef<StringRef[2]> IntrinsicToAttr) { 75 bool Changed = false; 76 77 for (const StringRef *Arr : IntrinsicToAttr) { 78 if (Function *Fn = M.getFunction(Arr[0])) { 79 addAttrToCallers(Fn, Arr[1]); 80 Changed = true; 81 } 82 } 83 84 return Changed; 85} 86 87bool AMDGPUAnnotateKernelFeatures::runOnModule(Module &M) { 88 Triple TT(M.getTargetTriple()); 89 90 static const StringRef IntrinsicToAttr[][2] = { 91 // .x omitted 92 { "llvm.r600.read.tgid.y", "amdgpu-work-group-id-y" }, 93 { "llvm.r600.read.tgid.z", "amdgpu-work-group-id-z" }, 94 95 // .x omitted 96 { "llvm.r600.read.tidig.y", "amdgpu-work-item-id-y" }, 97 { "llvm.r600.read.tidig.z", "amdgpu-work-item-id-z" } 98 99 }; 100 101 static const StringRef HSAIntrinsicToAttr[][2] = { 102 { "llvm.r600.read.local.size.x", "amdgpu-dispatch-ptr" }, 103 { "llvm.r600.read.local.size.y", "amdgpu-dispatch-ptr" }, 104 { "llvm.r600.read.local.size.z", "amdgpu-dispatch-ptr" }, 105 106 { "llvm.r600.read.global.size.x", "amdgpu-dispatch-ptr" }, 107 { "llvm.r600.read.global.size.y", "amdgpu-dispatch-ptr" }, 108 { "llvm.r600.read.global.size.z", "amdgpu-dispatch-ptr" }, 109 { "llvm.amdgcn.dispatch.ptr", "amdgpu-dispatch-ptr" } 110 }; 111 112 // TODO: Intrinsics that require queue ptr. 113 114 // We do not need to note the x workitem or workgroup id because they are 115 // always initialized. 116 117 bool Changed = addAttrsForIntrinsics(M, IntrinsicToAttr); 118 if (TT.getOS() == Triple::AMDHSA) 119 Changed |= addAttrsForIntrinsics(M, HSAIntrinsicToAttr); 120 121 return Changed; 122} 123 124ModulePass *llvm::createAMDGPUAnnotateKernelFeaturesPass() { 125 return new AMDGPUAnnotateKernelFeatures(); 126} 127