1a6f24c65STom Stellard //===-- AMDGPUAnnotateUniformValues.cpp - ---------------------------------===//
2a6f24c65STom Stellard //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a6f24c65STom Stellard //
7a6f24c65STom Stellard //===----------------------------------------------------------------------===//
8a6f24c65STom Stellard //
9a6f24c65STom Stellard /// \file
10a6f24c65STom Stellard /// This pass adds amdgpu.uniform metadata to IR values so this information
11a6f24c65STom Stellard /// can be used during instruction selection.
12a6f24c65STom Stellard //
13a6f24c65STom Stellard //===----------------------------------------------------------------------===//
14a6f24c65STom Stellard 
15a6f24c65STom Stellard #include "AMDGPU.h"
1685117e28SMatt Arsenault #include "Utils/AMDGPUBaseInfo.h"
17290e5722SStanislav Mekhanoshin #include "Utils/AMDGPUMemoryUtils.h"
1879606ee8SStanislav Mekhanoshin #include "llvm/Analysis/AliasAnalysis.h"
1935617ed4SNicolai Haehnle #include "llvm/Analysis/LegacyDivergenceAnalysis.h"
20ab90ae6fSStanislav Mekhanoshin #include "llvm/Analysis/MemorySSA.h"
216bda14b3SChandler Carruth #include "llvm/IR/InstVisitor.h"
2205da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
23a6f24c65STom Stellard 
24a6f24c65STom Stellard #define DEBUG_TYPE "amdgpu-annotate-uniform"
25a6f24c65STom Stellard 
26a6f24c65STom Stellard using namespace llvm;
27a6f24c65STom Stellard 
28a6f24c65STom Stellard namespace {
29a6f24c65STom Stellard 
30a6f24c65STom Stellard class AMDGPUAnnotateUniformValues : public FunctionPass,
31a6f24c65STom Stellard                        public InstVisitor<AMDGPUAnnotateUniformValues> {
3235617ed4SNicolai Haehnle   LegacyDivergenceAnalysis *DA;
33ab90ae6fSStanislav Mekhanoshin   MemorySSA *MSSA;
3479606ee8SStanislav Mekhanoshin   AliasAnalysis *AA;
3585117e28SMatt Arsenault   bool isEntryFunc;
36*77e793d0SJay Foad   bool Changed;
37*77e793d0SJay Foad 
setUniformMetadata(Instruction * I)38*77e793d0SJay Foad   void setUniformMetadata(Instruction *I) {
39*77e793d0SJay Foad     I->setMetadata("amdgpu.uniform", MDNode::get(I->getContext(), {}));
40*77e793d0SJay Foad     Changed = true;
41*77e793d0SJay Foad   }
42*77e793d0SJay Foad 
setNoClobberMetadata(Instruction * I)43*77e793d0SJay Foad   void setNoClobberMetadata(Instruction *I) {
44*77e793d0SJay Foad     I->setMetadata("amdgpu.noclobber", MDNode::get(I->getContext(), {}));
45*77e793d0SJay Foad     Changed = true;
46*77e793d0SJay Foad   }
47a6f24c65STom Stellard 
48a6f24c65STom Stellard public:
49a6f24c65STom Stellard   static char ID;
AMDGPUAnnotateUniformValues()50a6f24c65STom Stellard   AMDGPUAnnotateUniformValues() :
51a6f24c65STom Stellard     FunctionPass(ID) { }
52a6f24c65STom Stellard   bool doInitialization(Module &M) override;
53a6f24c65STom Stellard   bool runOnFunction(Function &F) override;
getPassName() const54117296c0SMehdi Amini   StringRef getPassName() const override {
55117296c0SMehdi Amini     return "AMDGPU Annotate Uniform Values";
56117296c0SMehdi Amini   }
getAnalysisUsage(AnalysisUsage & AU) const57a6f24c65STom Stellard   void getAnalysisUsage(AnalysisUsage &AU) const override {
5835617ed4SNicolai Haehnle     AU.addRequired<LegacyDivergenceAnalysis>();
59ab90ae6fSStanislav Mekhanoshin     AU.addRequired<MemorySSAWrapperPass>();
6079606ee8SStanislav Mekhanoshin     AU.addRequired<AAResultsWrapperPass>();
61a6f24c65STom Stellard     AU.setPreservesAll();
62a6f24c65STom Stellard  }
63a6f24c65STom Stellard 
64bc4497b1STom Stellard   void visitBranchInst(BranchInst &I);
65a6f24c65STom Stellard   void visitLoadInst(LoadInst &I);
66a6f24c65STom Stellard };
67a6f24c65STom Stellard 
68a6f24c65STom Stellard } // End anonymous namespace
69a6f24c65STom Stellard 
70a6f24c65STom Stellard INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
71a6f24c65STom Stellard                       "Add AMDGPU uniform metadata", false, false)
7235617ed4SNicolai Haehnle INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis)
73ab90ae6fSStanislav Mekhanoshin INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
7479606ee8SStanislav Mekhanoshin INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
75a6f24c65STom Stellard INITIALIZE_PASS_END(AMDGPUAnnotateUniformValues, DEBUG_TYPE,
76a6f24c65STom Stellard                     "Add AMDGPU uniform metadata", false, false)
77a6f24c65STom Stellard 
78a6f24c65STom Stellard char AMDGPUAnnotateUniformValues::ID = 0;
79a6f24c65STom Stellard 
visitBranchInst(BranchInst & I)80bc4497b1STom Stellard void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) {
81f77e2e84SRhys Perry   if (DA->isUniform(&I))
82fd142e6cSJay Foad     setUniformMetadata(&I);
83bc4497b1STom Stellard }
84bc4497b1STom Stellard 
visitLoadInst(LoadInst & I)85a6f24c65STom Stellard void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) {
86a6f24c65STom Stellard   Value *Ptr = I.getPointerOperand();
87a6f24c65STom Stellard   if (!DA->isUniform(Ptr))
88a6f24c65STom Stellard     return;
89b9cf52bcSJay Foad   Instruction *PtrI = dyn_cast<Instruction>(Ptr);
90b9cf52bcSJay Foad   if (PtrI)
91b9cf52bcSJay Foad     setUniformMetadata(PtrI);
92b9cf52bcSJay Foad 
9385117e28SMatt Arsenault   // We're tracking up to the Function boundaries, and cannot go beyond because
9485117e28SMatt Arsenault   // of FunctionPass restrictions. We can ensure that is memory not clobbered
9585117e28SMatt Arsenault   // for memory operations that are live in to entry points only.
96b9cf52bcSJay Foad   if (!isEntryFunc)
97243376cdSChangpeng Fang     return;
980dcc8b86SJay Foad   bool GlobalLoad = I.getPointerAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
99290e5722SStanislav Mekhanoshin   if (GlobalLoad && !AMDGPU::isClobberedInFunction(&I, MSSA, AA))
100ddd3807eSJay Foad     setNoClobberMetadata(&I);
101a6f24c65STom Stellard }
102a6f24c65STom Stellard 
doInitialization(Module & M)103a6f24c65STom Stellard bool AMDGPUAnnotateUniformValues::doInitialization(Module &M) {
104a6f24c65STom Stellard   return false;
105a6f24c65STom Stellard }
106a6f24c65STom Stellard 
runOnFunction(Function & F)107a6f24c65STom Stellard bool AMDGPUAnnotateUniformValues::runOnFunction(Function &F) {
1087de74af9SAndrew Kaylor   if (skipFunction(F))
1097de74af9SAndrew Kaylor     return false;
1107de74af9SAndrew Kaylor 
11135617ed4SNicolai Haehnle   DA = &getAnalysis<LegacyDivergenceAnalysis>();
112ab90ae6fSStanislav Mekhanoshin   MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
11379606ee8SStanislav Mekhanoshin   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
11485117e28SMatt Arsenault   isEntryFunc = AMDGPU::isEntryFunctionCC(F.getCallingConv());
115a6f24c65STom Stellard 
116*77e793d0SJay Foad   Changed = false;
11718009560SAlexander Timofeev   visit(F);
118*77e793d0SJay Foad   return Changed;
119a6f24c65STom Stellard }
120a6f24c65STom Stellard 
121a6f24c65STom Stellard FunctionPass *
createAMDGPUAnnotateUniformValues()122a6f24c65STom Stellard llvm::createAMDGPUAnnotateUniformValues() {
123a6f24c65STom Stellard   return new AMDGPUAnnotateUniformValues();
124a6f24c65STom Stellard }
125