LLVM 19.0.0git
AMDGPUAnnotateKernelFeatures.cpp
Go to the documentation of this file.
1//===- AMDGPUAnnotateKernelFeaturesPass.cpp -------------------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file This pass propagates the uniform-work-group-size attribute from
10/// kernels to leaf functions when possible. It also adds additional attributes
11/// to hint ABI lowering optimizations later.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AMDGPU.h"
16#include "GCNSubtarget.h"
20#include "llvm/IR/IntrinsicsAMDGPU.h"
21#include "llvm/IR/IntrinsicsR600.h"
23
24#define DEBUG_TYPE "amdgpu-annotate-kernel-features"
25
26using namespace llvm;
27
28namespace {
29class AMDGPUAnnotateKernelFeatures : public CallGraphSCCPass {
30private:
31 const TargetMachine *TM = nullptr;
32
33 bool addFeatureAttributes(Function &F);
34
35public:
36 static char ID;
37
38 AMDGPUAnnotateKernelFeatures() : CallGraphSCCPass(ID) {}
39
40 bool doInitialization(CallGraph &CG) override;
41 bool runOnSCC(CallGraphSCC &SCC) override;
42
43 StringRef getPassName() const override {
44 return "AMDGPU Annotate Kernel Features";
45 }
46
47 void getAnalysisUsage(AnalysisUsage &AU) const override {
48 AU.setPreservesAll();
50 }
51};
52
53} // end anonymous namespace
54
55char AMDGPUAnnotateKernelFeatures::ID = 0;
56
57char &llvm::AMDGPUAnnotateKernelFeaturesID = AMDGPUAnnotateKernelFeatures::ID;
58
59INITIALIZE_PASS(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE,
60 "Add AMDGPU function attributes", false, false)
61
62bool AMDGPUAnnotateKernelFeatures::addFeatureAttributes(Function &F) {
63 bool HaveStackObjects = false;
64 bool Changed = false;
65 bool HaveCall = false;
66 bool IsFunc = !AMDGPU::isEntryFunctionCC(F.getCallingConv());
67
68 for (BasicBlock &BB : F) {
69 for (Instruction &I : BB) {
70 if (isa<AllocaInst>(I)) {
71 HaveStackObjects = true;
72 continue;
73 }
74
75 if (auto *CB = dyn_cast<CallBase>(&I)) {
76 const Function *Callee =
77 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
78
79 // Note the occurrence of indirect call.
80 if (!Callee) {
81 if (!CB->isInlineAsm())
82 HaveCall = true;
83
84 continue;
85 }
86
87 Intrinsic::ID IID = Callee->getIntrinsicID();
88 if (IID == Intrinsic::not_intrinsic) {
89 HaveCall = true;
90 Changed = true;
91 }
92 }
93 }
94 }
95
96 // TODO: We could refine this to captured pointers that could possibly be
97 // accessed by flat instructions. For now this is mostly a poor way of
98 // estimating whether there are calls before argument lowering.
99 if (!IsFunc && HaveCall) {
100 F.addFnAttr("amdgpu-calls");
101 Changed = true;
102 }
103
104 if (HaveStackObjects) {
105 F.addFnAttr("amdgpu-stack-objects");
106 Changed = true;
107 }
108
109 return Changed;
110}
111
112bool AMDGPUAnnotateKernelFeatures::runOnSCC(CallGraphSCC &SCC) {
113 bool Changed = false;
114
115 for (CallGraphNode *I : SCC) {
116 Function *F = I->getFunction();
117 // Ignore functions with graphics calling conventions, these are currently
118 // not allowed to have kernel arguments.
119 if (!F || F->isDeclaration() || AMDGPU::isGraphics(F->getCallingConv()))
120 continue;
121 // Add feature attributes
122 Changed |= addFeatureAttributes(*F);
123 }
124
125 return Changed;
126}
127
128bool AMDGPUAnnotateKernelFeatures::doInitialization(CallGraph &CG) {
129 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
130 if (!TPC)
131 report_fatal_error("TargetMachine is required");
132
133 TM = &TPC->getTM<TargetMachine>();
134 return false;
135}
136
138 return new AMDGPUAnnotateKernelFeatures();
139}
#define DEBUG_TYPE
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
AMD GCN specific subclass of TargetSubtarget.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
A node in the call graph for a module.
Definition: CallGraph.h:166
virtual bool runOnSCC(CallGraphSCC &SCC)=0
runOnSCC - This method should be implemented by the subclass to perform whatever action is necessary ...
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph.
virtual bool doInitialization(CallGraph &CG)
doInitialization - This method is called before the SCC's of the program has been processed,...
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
The basic data container for the call graph of a Module of IR.
Definition: CallGraph.h:72
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
bool isEntryFunctionCC(CallingConv::ID CC)
bool isGraphics(CallingConv::ID cc)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
char & AMDGPUAnnotateKernelFeaturesID
Pass * createAMDGPUAnnotateKernelFeaturesPass()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156