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 "Utils/AMDGPUBaseInfo.h"
17 #include "Utils/AMDGPUMemoryUtils.h"
18 #include "llvm/Analysis/AliasAnalysis.h"
19 #include "llvm/Analysis/LegacyDivergenceAnalysis.h"
20 #include "llvm/Analysis/MemorySSA.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 : public FunctionPass,
31                        public InstVisitor<AMDGPUAnnotateUniformValues> {
32   LegacyDivergenceAnalysis *DA;
33   MemorySSA *MSSA;
34   AliasAnalysis *AA;
35   bool isEntryFunc;
36 
37 public:
38   static char ID;
39   AMDGPUAnnotateUniformValues() :
40     FunctionPass(ID) { }
41   bool doInitialization(Module &M) override;
42   bool runOnFunction(Function &F) override;
43   StringRef getPassName() const override {
44     return "AMDGPU Annotate Uniform Values";
45   }
46   void getAnalysisUsage(AnalysisUsage &AU) const override {
47     AU.addRequired<LegacyDivergenceAnalysis>();
48     AU.addRequired<MemorySSAWrapperPass>();
49     AU.addRequired<AAResultsWrapperPass>();
50     AU.setPreservesAll();
51  }
52 
53   void visitBranchInst(BranchInst &I);
54   void visitLoadInst(LoadInst &I);
55 };
56 
57 } // End anonymous namespace
58 
59 INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
60                       "Add AMDGPU uniform metadata", false, false)
61 INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis)
62 INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
63 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
64 INITIALIZE_PASS_END(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
65                     "Add AMDGPU uniform metadata", false, false)
66 
67 char AMDGPUAnnotateUniformValues::ID = 0;
68 
69 static void setUniformMetadata(Instruction *I) {
70   I->setMetadata("amdgpu.uniform", MDNode::get(I->getContext(), {}));
71 }
72 static void setNoClobberMetadata(Instruction *I) {
73   I->setMetadata("amdgpu.noclobber", MDNode::get(I->getContext(), {}));
74 }
75 
76 void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) {
77   if (DA->isUniform(&I))
78     setUniformMetadata(&I);
79 }
80 
81 void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) {
82   Value *Ptr = I.getPointerOperand();
83   if (!DA->isUniform(Ptr))
84     return;
85   Instruction *PtrI = dyn_cast<Instruction>(Ptr);
86   if (PtrI)
87     setUniformMetadata(PtrI);
88 
89   // We're tracking up to the Function boundaries, and cannot go beyond because
90   // of FunctionPass restrictions. We can ensure that is memory not clobbered
91   // for memory operations that are live in to entry points only.
92   if (!isEntryFunc)
93     return;
94   bool GlobalLoad = I.getPointerAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
95   if (GlobalLoad && !AMDGPU::isClobberedInFunction(&I, MSSA, AA))
96     setNoClobberMetadata(&I);
97 }
98 
99 bool AMDGPUAnnotateUniformValues::doInitialization(Module &M) {
100   return false;
101 }
102 
103 bool AMDGPUAnnotateUniformValues::runOnFunction(Function &F) {
104   if (skipFunction(F))
105     return false;
106 
107   DA = &getAnalysis<LegacyDivergenceAnalysis>();
108   MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
109   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
110   isEntryFunc = AMDGPU::isEntryFunctionCC(F.getCallingConv());
111 
112   visit(F);
113   return true;
114 }
115 
116 FunctionPass *
117 llvm::createAMDGPUAnnotateUniformValues() {
118   return new AMDGPUAnnotateUniformValues();
119 }
120