1//===-- AMDGPUAnnotateUniformValues.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
10/// This pass adds amdgpu.uniform metadata to IR values so this information
11/// can be used during instruction selection.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AMDGPU.h"
16#include "AMDGPUMemoryUtils.h"
17#include "Utils/AMDGPUBaseInfo.h"
18#include "llvm/Analysis/AliasAnalysis.h"
19#include "llvm/Analysis/MemorySSA.h"
20#include "llvm/Analysis/UniformityAnalysis.h"
21#include "llvm/IR/InstVisitor.h"
22#include "llvm/InitializePasses.h"
23
24#define DEBUG_TYPE "amdgpu-annotate-uniform"
25
26using namespace llvm;
27
28namespace {
29
30class AMDGPUAnnotateUniformValues
31 : public InstVisitor<AMDGPUAnnotateUniformValues> {
32 UniformityInfo *UA;
33 MemorySSA *MSSA;
34 AliasAnalysis *AA;
35 bool isEntryFunc;
36 bool Changed = false;
37
38 void setUniformMetadata(Instruction *I) {
39 I->setMetadata(Kind: "amdgpu.uniform", Node: MDNode::get(Context&: I->getContext(), MDs: {}));
40 Changed = true;
41 }
42
43 void setNoClobberMetadata(Instruction *I) {
44 I->setMetadata(Kind: "amdgpu.noclobber", Node: MDNode::get(Context&: I->getContext(), MDs: {}));
45 Changed = true;
46 }
47
48public:
49 AMDGPUAnnotateUniformValues(UniformityInfo &UA, MemorySSA &MSSA,
50 AliasAnalysis &AA, const Function &F)
51 : UA(&UA), MSSA(&MSSA), AA(&AA),
52 isEntryFunc(AMDGPU::isEntryFunctionCC(CC: F.getCallingConv())) {}
53
54 void visitBranchInst(BranchInst &I);
55 void visitLoadInst(LoadInst &I);
56
57 bool changed() const { return Changed; }
58};
59
60} // End anonymous namespace
61
62void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) {
63 if (UA->isUniform(I: &I))
64 setUniformMetadata(&I);
65}
66
67void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) {
68 Value *Ptr = I.getPointerOperand();
69 if (!UA->isUniform(V: Ptr))
70 return;
71 Instruction *PtrI = dyn_cast<Instruction>(Val: Ptr);
72 if (PtrI)
73 setUniformMetadata(PtrI);
74
75 // We're tracking up to the Function boundaries, and cannot go beyond because
76 // of FunctionPass restrictions. We can ensure that is memory not clobbered
77 // for memory operations that are live in to entry points only.
78 if (!isEntryFunc)
79 return;
80 bool GlobalLoad = I.getPointerAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
81 if (GlobalLoad && !AMDGPU::isClobberedInFunction(Load: &I, MSSA, AA))
82 setNoClobberMetadata(&I);
83}
84
85PreservedAnalyses
86AMDGPUAnnotateUniformValuesPass::run(Function &F,
87 FunctionAnalysisManager &FAM) {
88 UniformityInfo &UI = FAM.getResult<UniformityInfoAnalysis>(IR&: F);
89 MemorySSA &MSSA = FAM.getResult<MemorySSAAnalysis>(IR&: F).getMSSA();
90 AAResults &AA = FAM.getResult<AAManager>(IR&: F);
91
92 AMDGPUAnnotateUniformValues Impl(UI, MSSA, AA, F);
93 Impl.visit(F);
94
95 if (!Impl.changed())
96 return PreservedAnalyses::all();
97
98 PreservedAnalyses PA = PreservedAnalyses::none();
99 // TODO: Should preserve nearly everything
100 PA.preserveSet<CFGAnalyses>();
101 return PA;
102}
103
104class AMDGPUAnnotateUniformValuesLegacy : public FunctionPass {
105public:
106 static char ID;
107
108 AMDGPUAnnotateUniformValuesLegacy() : FunctionPass(ID) {}
109
110 bool doInitialization(Module &M) override { return false; }
111
112 bool runOnFunction(Function &F) override;
113 StringRef getPassName() const override {
114 return "AMDGPU Annotate Uniform Values";
115 }
116
117 void getAnalysisUsage(AnalysisUsage &AU) const override {
118 AU.addRequired<UniformityInfoWrapperPass>();
119 AU.addRequired<MemorySSAWrapperPass>();
120 AU.addRequired<AAResultsWrapperPass>();
121 AU.setPreservesAll();
122 }
123};
124
125bool AMDGPUAnnotateUniformValuesLegacy::runOnFunction(Function &F) {
126 if (skipFunction(F))
127 return false;
128
129 UniformityInfo &UI =
130 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
131 MemorySSA &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
132 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
133
134 AMDGPUAnnotateUniformValues Impl(UI, MSSA, AA, F);
135 Impl.visit(F);
136 return Impl.changed();
137}
138
139INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValuesLegacy, DEBUG_TYPE,
140 "Add AMDGPU uniform metadata", false, false)
141INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
142INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
143INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
144INITIALIZE_PASS_END(AMDGPUAnnotateUniformValuesLegacy, DEBUG_TYPE,
145 "Add AMDGPU uniform metadata", false, false)
146
147char AMDGPUAnnotateUniformValuesLegacy::ID = 0;
148
149FunctionPass *llvm::createAMDGPUAnnotateUniformValuesLegacy() {
150 return new AMDGPUAnnotateUniformValuesLegacy();
151}
152