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