xref: /llvm-project/llvm/lib/Target/AMDGPU/AMDGPUAnnotateUniformValues.cpp (revision 3923e0451a4b02c4fe7c394e0f0ec90708ebca7a)
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 
26 using namespace llvm;
27 
28 namespace {
29 
30 class 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("amdgpu.uniform", MDNode::get(I->getContext(), {}));
40     Changed = true;
41   }
42 
43   void setNoClobberMetadata(Instruction *I) {
44     I->setMetadata("amdgpu.noclobber", MDNode::get(I->getContext(), {}));
45     Changed = true;
46   }
47 
48 public:
49   AMDGPUAnnotateUniformValues(UniformityInfo &UA, MemorySSA &MSSA,
50                               AliasAnalysis &AA, const Function &F)
51       : UA(&UA), MSSA(&MSSA), AA(&AA),
52         isEntryFunc(AMDGPU::isEntryFunctionCC(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 
62 void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) {
63   if (UA->isUniform(&I))
64     setUniformMetadata(&I);
65 }
66 
67 void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) {
68   Value *Ptr = I.getPointerOperand();
69   if (!UA->isUniform(Ptr))
70     return;
71   Instruction *PtrI = dyn_cast<Instruction>(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(&I, MSSA, AA))
82     setNoClobberMetadata(&I);
83 }
84 
85 PreservedAnalyses
86 AMDGPUAnnotateUniformValuesPass::run(Function &F,
87                                      FunctionAnalysisManager &FAM) {
88   UniformityInfo &UI = FAM.getResult<UniformityInfoAnalysis>(F);
89   MemorySSA &MSSA = FAM.getResult<MemorySSAAnalysis>(F).getMSSA();
90   AAResults &AA = FAM.getResult<AAManager>(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 
104 class AMDGPUAnnotateUniformValuesLegacy : public FunctionPass {
105 public:
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 
125 bool 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 
139 INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValuesLegacy, DEBUG_TYPE,
140                       "Add AMDGPU uniform metadata", false, false)
141 INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
142 INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
143 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
144 INITIALIZE_PASS_END(AMDGPUAnnotateUniformValuesLegacy, DEBUG_TYPE,
145                     "Add AMDGPU uniform metadata", false, false)
146 
147 char AMDGPUAnnotateUniformValuesLegacy::ID = 0;
148 
149 FunctionPass *llvm::createAMDGPUAnnotateUniformValuesLegacy() {
150   return new AMDGPUAnnotateUniformValuesLegacy();
151 }
152