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;
AMDGPUAnnotateUniformValues()36 AMDGPUAnnotateUniformValues() :
37 FunctionPass(ID) { }
38 bool doInitialization(Module &M) override;
39 bool runOnFunction(Function &F) override;
getPassName() const40 const char *getPassName() const override { return "AMDGPU Annotate Uniform Values"; }
getAnalysisUsage(AnalysisUsage & AU) const41 void getAnalysisUsage(AnalysisUsage &AU) const override {
42 AU.addRequired<DivergenceAnalysis>();
43 AU.setPreservesAll();
44 }
45
46 void visitBranchInst(BranchInst &I);
47 void visitLoadInst(LoadInst &I);
48
49 };
50
51 } // End anonymous namespace
52
53 INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
54 "Add AMDGPU uniform metadata", false, false)
55 INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
56 INITIALIZE_PASS_END(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
57 "Add AMDGPU uniform metadata", false, false)
58
59 char AMDGPUAnnotateUniformValues::ID = 0;
60
setUniformMetadata(Instruction * I)61 static void setUniformMetadata(Instruction *I) {
62 I->setMetadata("amdgpu.uniform", MDNode::get(I->getContext(), {}));
63 }
64
visitBranchInst(BranchInst & I)65 void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) {
66 if (I.isUnconditional())
67 return;
68
69 Value *Cond = I.getCondition();
70 if (!DA->isUniform(Cond))
71 return;
72
73 setUniformMetadata(I.getParent()->getTerminator());
74 }
75
visitLoadInst(LoadInst & I)76 void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) {
77 Value *Ptr = I.getPointerOperand();
78 if (!DA->isUniform(Ptr))
79 return;
80
81 if (Instruction *PtrI = dyn_cast<Instruction>(Ptr))
82 setUniformMetadata(PtrI);
83
84 }
85
doInitialization(Module & M)86 bool AMDGPUAnnotateUniformValues::doInitialization(Module &M) {
87 return false;
88 }
89
runOnFunction(Function & F)90 bool AMDGPUAnnotateUniformValues::runOnFunction(Function &F) {
91 if (skipFunction(F))
92 return false;
93
94 DA = &getAnalysis<DivergenceAnalysis>();
95 visit(F);
96
97 return true;
98 }
99
100 FunctionPass *
createAMDGPUAnnotateUniformValues()101 llvm::createAMDGPUAnnotateUniformValues() {
102 return new AMDGPUAnnotateUniformValues();
103 }
104