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 "AMDGPUMemoryUtils.h" 17 #include "Utils/AMDGPUBaseInfo.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 31 : public InstVisitor<AMDGPUAnnotateUniformValues> { 32 UniformityInfo *UA; 33 MemorySSA *MSSA; 34 AliasAnalysis *AA; 35 bool isEntryFunc; 36 bool Changed = false; 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 AMDGPUAnnotateUniformValues(UniformityInfo &UA, MemorySSA &MSSA, 50 AliasAnalysis &AA, const Function &F) 51 : UA(&UA), MSSA(&MSSA), AA(&AA), 52 isEntryFunc(AMDGPU::isEntryFunctionCC(F.getCallingConv())) {} 53 54 void visitBranchInst(BranchInst &I); 55 void visitLoadInst(LoadInst &I); 56 57 bool changed() const { return Changed; } 58 }; 59 60 } // End anonymous namespace 61 62 void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) { 63 if (UA->isUniform(&I)) 64 setUniformMetadata(&I); 65 } 66 67 void AMDGPUAnnotateUniformValues::visitLoadInst(LoadInst &I) { 68 Value *Ptr = I.getPointerOperand(); 69 if (!UA->isUniform(Ptr)) 70 return; 71 Instruction *PtrI = dyn_cast<Instruction>(Ptr); 72 if (PtrI) 73 setUniformMetadata(PtrI); 74 75 // We're tracking up to the Function boundaries, and cannot go beyond because 76 // of FunctionPass restrictions. We can ensure that is memory not clobbered 77 // for memory operations that are live in to entry points only. 78 if (!isEntryFunc) 79 return; 80 bool GlobalLoad = I.getPointerAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 81 if (GlobalLoad && !AMDGPU::isClobberedInFunction(&I, MSSA, AA)) 82 setNoClobberMetadata(&I); 83 } 84 85 PreservedAnalyses 86 AMDGPUAnnotateUniformValuesPass::run(Function &F, 87 FunctionAnalysisManager &FAM) { 88 UniformityInfo &UI = FAM.getResult<UniformityInfoAnalysis>(F); 89 MemorySSA &MSSA = FAM.getResult<MemorySSAAnalysis>(F).getMSSA(); 90 AAResults &AA = FAM.getResult<AAManager>(F); 91 92 AMDGPUAnnotateUniformValues Impl(UI, MSSA, AA, F); 93 Impl.visit(F); 94 95 if (!Impl.changed()) 96 return PreservedAnalyses::all(); 97 98 PreservedAnalyses PA = PreservedAnalyses::none(); 99 // TODO: Should preserve nearly everything 100 PA.preserveSet<CFGAnalyses>(); 101 return PA; 102 } 103 104 class AMDGPUAnnotateUniformValuesLegacy : public FunctionPass { 105 public: 106 static char ID; 107 108 AMDGPUAnnotateUniformValuesLegacy() : FunctionPass(ID) {} 109 110 bool doInitialization(Module &M) override { return false; } 111 112 bool runOnFunction(Function &F) override; 113 StringRef getPassName() const override { 114 return "AMDGPU Annotate Uniform Values"; 115 } 116 117 void getAnalysisUsage(AnalysisUsage &AU) const override { 118 AU.addRequired<UniformityInfoWrapperPass>(); 119 AU.addRequired<MemorySSAWrapperPass>(); 120 AU.addRequired<AAResultsWrapperPass>(); 121 AU.setPreservesAll(); 122 } 123 }; 124 125 bool AMDGPUAnnotateUniformValuesLegacy::runOnFunction(Function &F) { 126 if (skipFunction(F)) 127 return false; 128 129 UniformityInfo &UI = 130 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo(); 131 MemorySSA &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA(); 132 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults(); 133 134 AMDGPUAnnotateUniformValues Impl(UI, MSSA, AA, F); 135 Impl.visit(F); 136 return Impl.changed(); 137 } 138 139 INITIALIZE_PASS_BEGIN(AMDGPUAnnotateUniformValuesLegacy, DEBUG_TYPE, 140 "Add AMDGPU uniform metadata", false, false) 141 INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass) 142 INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) 143 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 144 INITIALIZE_PASS_END(AMDGPUAnnotateUniformValuesLegacy, DEBUG_TYPE, 145 "Add AMDGPU uniform metadata", false, false) 146 147 char AMDGPUAnnotateUniformValuesLegacy::ID = 0; 148 149 FunctionPass *llvm::createAMDGPUAnnotateUniformValuesLegacy() { 150 return new AMDGPUAnnotateUniformValuesLegacy(); 151 } 152