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
26using namespace llvm;
27
28namespace {
29
30class AMDGPUAnnotateUniformValues : public FunctionPass,
31                       public InstVisitor<AMDGPUAnnotateUniformValues> {
32  DivergenceAnalysis *DA;
33
34public:
35  static char ID;
36  AMDGPUAnnotateUniformValues() :
37    FunctionPass(ID) { }
38  bool doInitialization(Module &M) override;
39  bool runOnFunction(Function &F) override;
40  const char *getPassName() const override { return "AMDGPU Annotate Uniform Values"; }
41  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
53INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
54                      "Add AMDGPU uniform metadata", false, false)
55INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
56INITIALIZE_PASS_END(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
57                    "Add AMDGPU uniform metadata", false, false)
58
59char AMDGPUAnnotateUniformValues::ID = 0;
60
61static void setUniformMetadata(Instruction *I) {
62  I->setMetadata("amdgpu.uniform", MDNode::get(I->getContext(), {}));
63}
64
65void 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
76void 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
86bool AMDGPUAnnotateUniformValues::doInitialization(Module &M) {
87  return false;
88}
89
90bool 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
100FunctionPass *
101llvm::createAMDGPUAnnotateUniformValues() {
102  return new AMDGPUAnnotateUniformValues();
103}
104