1 //===-- AMDGPUAnnotateKernelFeaturesPass.cpp ------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// \file This pass adds target attributes to functions which use intrinsics
11 /// which will impact calling convention lowering.
13 //===----------------------------------------------------------------------===//
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/Module.h"
19 #define DEBUG_TYPE "amdgpu-annotate-kernel-features"
25 class AMDGPUAnnotateKernelFeatures : public ModulePass {
27 void addAttrToCallers(Function *Intrin, StringRef AttrName);
28 bool addAttrsForIntrinsics(Module &M, ArrayRef<StringRef[2]>);
33 AMDGPUAnnotateKernelFeatures() : ModulePass(ID) { }
34 bool runOnModule(Module &M) override;
35 const char *getPassName() const override {
36 return "AMDGPU Annotate Kernel Features";
39 void getAnalysisUsage(AnalysisUsage &AU) const override {
41 ModulePass::getAnalysisUsage(AU);
47 char AMDGPUAnnotateKernelFeatures::ID = 0;
49 char &llvm::AMDGPUAnnotateKernelFeaturesID = AMDGPUAnnotateKernelFeatures::ID;
52 INITIALIZE_PASS_BEGIN(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE,
53 "Add AMDGPU function attributes", false, false)
54 INITIALIZE_PASS_END(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE,
55 "Add AMDGPU function attributes", false, false)
58 void AMDGPUAnnotateKernelFeatures::addAttrToCallers(Function *Intrin,
60 SmallPtrSet<Function *, 4> SeenFuncs;
62 for (User *U : Intrin->users()) {
63 // CallInst is the only valid user for an intrinsic.
64 CallInst *CI = cast<CallInst>(U);
66 Function *CallingFunction = CI->getParent()->getParent();
67 if (SeenFuncs.insert(CallingFunction).second)
68 CallingFunction->addFnAttr(AttrName);
72 bool AMDGPUAnnotateKernelFeatures::addAttrsForIntrinsics(
74 ArrayRef<StringRef[2]> IntrinsicToAttr) {
77 for (const StringRef *Arr : IntrinsicToAttr) {
78 if (Function *Fn = M.getFunction(Arr[0])) {
79 addAttrToCallers(Fn, Arr[1]);
87 bool AMDGPUAnnotateKernelFeatures::runOnModule(Module &M) {
88 Triple TT(M.getTargetTriple());
90 static const StringRef IntrinsicToAttr[][2] = {
92 { "llvm.r600.read.tgid.y", "amdgpu-work-group-id-y" },
93 { "llvm.r600.read.tgid.z", "amdgpu-work-group-id-z" },
96 { "llvm.r600.read.tidig.y", "amdgpu-work-item-id-y" },
97 { "llvm.r600.read.tidig.z", "amdgpu-work-item-id-z" }
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" },
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" }
112 // TODO: Intrinsics that require queue ptr.
114 // We do not need to note the x workitem or workgroup id because they are
115 // always initialized.
117 bool Changed = addAttrsForIntrinsics(M, IntrinsicToAttr);
118 if (TT.getOS() == Triple::AMDHSA)
119 Changed |= addAttrsForIntrinsics(M, HSAIntrinsicToAttr);
124 ModulePass *llvm::createAMDGPUAnnotateKernelFeaturesPass() {
125 return new AMDGPUAnnotateKernelFeatures();