1 //===-- AMDGPUAnnotateUniformValues.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
11 /// This pass adds amdgpu.uniform metadata to IR values so this information
12 /// can be used during instruction selection.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "AMDGPU.h"
17 #include "AMDGPUIntrinsicInfo.h"
18 #include "llvm/Analysis/DivergenceAnalysis.h"
19 #include "llvm/IR/InstVisitor.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.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   DivergenceAnalysis *DA;
33 
34 public:
35   static char ID;
36   AMDGPUAnnotateUniformValues() :
37     FunctionPass(ID) { }
38   bool doInitialization(Module &M) override;
39   bool runOnFunction(Function &F) override;
40   StringRef getPassName() const override {
41     return "AMDGPU Annotate Uniform Values";
42   }
43   void getAnalysisUsage(AnalysisUsage &AU) const override {
44     AU.addRequired<DivergenceAnalysis>();
45     AU.setPreservesAll();
46  }
47 
48   void visitBranchInst(BranchInst &I);
49   void visitLoadInst(LoadInst &I);
50 
51 };
52 
53 } // End anonymous namespace
54 
55 INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
56                       "Add AMDGPU uniform metadata", false, false)
57 INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
58 INITIALIZE_PASS_END(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
59                     "Add AMDGPU uniform metadata", false, false)
60 
61 char AMDGPUAnnotateUniformValues::ID = 0;
62 
63 static void setUniformMetadata(Instruction *I) {
64   I->setMetadata("amdgpu.uniform", MDNode::get(I->getContext(), {}));
65 }
66 
67 void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) {
68   if (I.isUnconditional())
69     return;
70 
71   Value *Cond = I.getCondition();
72   if (!DA->isUniform(Cond))
73     return;
74 
75   setUniformMetadata(I.getParent()->getTerminator());
76 }
77 
78 void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) {
79   Value *Ptr = I.getPointerOperand();
80   if (!DA->isUniform(Ptr))
81     return;
82 
83   if (Instruction *PtrI = dyn_cast<Instruction>(Ptr))
84     setUniformMetadata(PtrI);
85 
86 }
87 
88 bool AMDGPUAnnotateUniformValues::doInitialization(Module &M) {
89   return false;
90 }
91 
92 bool AMDGPUAnnotateUniformValues::runOnFunction(Function &F) {
93   if (skipFunction(F))
94     return false;
95 
96   DA = &getAnalysis<DivergenceAnalysis>();
97   visit(F);
98 
99   return true;
100 }
101 
102 FunctionPass *
103 llvm::createAMDGPUAnnotateUniformValues() {
104   return new AMDGPUAnnotateUniformValues();
105 }
106