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