1475ce4c2SSameer Sahasrabuddhe //===- MachineUniformityAnalysis.cpp --------------------------------------===// 2475ce4c2SSameer Sahasrabuddhe // 3475ce4c2SSameer Sahasrabuddhe // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4475ce4c2SSameer Sahasrabuddhe // See https://llvm.org/LICENSE.txt for license information. 5475ce4c2SSameer Sahasrabuddhe // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6475ce4c2SSameer Sahasrabuddhe // 7475ce4c2SSameer Sahasrabuddhe //===----------------------------------------------------------------------===// 8475ce4c2SSameer Sahasrabuddhe 9475ce4c2SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineUniformityAnalysis.h" 10475ce4c2SSameer Sahasrabuddhe #include "llvm/ADT/GenericUniformityImpl.h" 11475ce4c2SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineCycleAnalysis.h" 12475ce4c2SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineDominators.h" 13475ce4c2SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineRegisterInfo.h" 14475ce4c2SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineSSAContext.h" 15475ce4c2SSameer Sahasrabuddhe #include "llvm/CodeGen/TargetInstrInfo.h" 16475ce4c2SSameer Sahasrabuddhe #include "llvm/InitializePasses.h" 17475ce4c2SSameer Sahasrabuddhe 18475ce4c2SSameer Sahasrabuddhe using namespace llvm; 19475ce4c2SSameer Sahasrabuddhe 20475ce4c2SSameer Sahasrabuddhe template <> 21475ce4c2SSameer Sahasrabuddhe bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::hasDivergentDefs( 22475ce4c2SSameer Sahasrabuddhe const MachineInstr &I) const { 235022fc2aSJay Foad for (auto &op : I.all_defs()) { 24475ce4c2SSameer Sahasrabuddhe if (isDivergent(op.getReg())) 25475ce4c2SSameer Sahasrabuddhe return true; 26475ce4c2SSameer Sahasrabuddhe } 27475ce4c2SSameer Sahasrabuddhe return false; 28475ce4c2SSameer Sahasrabuddhe } 29475ce4c2SSameer Sahasrabuddhe 30475ce4c2SSameer Sahasrabuddhe template <> 31475ce4c2SSameer Sahasrabuddhe bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::markDefsDivergent( 32fbe1c061SSameer Sahasrabuddhe const MachineInstr &Instr) { 33475ce4c2SSameer Sahasrabuddhe bool insertedDivergent = false; 34475ce4c2SSameer Sahasrabuddhe const auto &MRI = F.getRegInfo(); 35fbe1c061SSameer Sahasrabuddhe const auto &RBI = *F.getSubtarget().getRegBankInfo(); 36475ce4c2SSameer Sahasrabuddhe const auto &TRI = *MRI.getTargetRegisterInfo(); 375022fc2aSJay Foad for (auto &op : Instr.all_defs()) { 38475ce4c2SSameer Sahasrabuddhe if (!op.getReg().isVirtual()) 39475ce4c2SSameer Sahasrabuddhe continue; 40475ce4c2SSameer Sahasrabuddhe assert(!op.getSubReg()); 41fbe1c061SSameer Sahasrabuddhe if (TRI.isUniformReg(MRI, RBI, op.getReg())) 42475ce4c2SSameer Sahasrabuddhe continue; 43475ce4c2SSameer Sahasrabuddhe insertedDivergent |= markDivergent(op.getReg()); 44475ce4c2SSameer Sahasrabuddhe } 45475ce4c2SSameer Sahasrabuddhe return insertedDivergent; 46475ce4c2SSameer Sahasrabuddhe } 47475ce4c2SSameer Sahasrabuddhe 48475ce4c2SSameer Sahasrabuddhe template <> 49475ce4c2SSameer Sahasrabuddhe void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() { 50475ce4c2SSameer Sahasrabuddhe const auto &InstrInfo = *F.getSubtarget().getInstrInfo(); 51475ce4c2SSameer Sahasrabuddhe 52475ce4c2SSameer Sahasrabuddhe for (const MachineBasicBlock &block : F) { 53475ce4c2SSameer Sahasrabuddhe for (const MachineInstr &instr : block) { 54475ce4c2SSameer Sahasrabuddhe auto uniformity = InstrInfo.getInstructionUniformity(instr); 55475ce4c2SSameer Sahasrabuddhe if (uniformity == InstructionUniformity::AlwaysUniform) { 56475ce4c2SSameer Sahasrabuddhe addUniformOverride(instr); 57475ce4c2SSameer Sahasrabuddhe continue; 58475ce4c2SSameer Sahasrabuddhe } 59475ce4c2SSameer Sahasrabuddhe 60475ce4c2SSameer Sahasrabuddhe if (uniformity == InstructionUniformity::NeverUniform) { 610a170eb7SSameer Sahasrabuddhe markDivergent(instr); 62475ce4c2SSameer Sahasrabuddhe } 63475ce4c2SSameer Sahasrabuddhe } 64475ce4c2SSameer Sahasrabuddhe } 65475ce4c2SSameer Sahasrabuddhe } 66475ce4c2SSameer Sahasrabuddhe 67475ce4c2SSameer Sahasrabuddhe template <> 68475ce4c2SSameer Sahasrabuddhe void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers( 69475ce4c2SSameer Sahasrabuddhe Register Reg) { 700a170eb7SSameer Sahasrabuddhe assert(isDivergent(Reg)); 71475ce4c2SSameer Sahasrabuddhe const auto &RegInfo = F.getRegInfo(); 72475ce4c2SSameer Sahasrabuddhe for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) { 730a170eb7SSameer Sahasrabuddhe markDivergent(UserInstr); 74475ce4c2SSameer Sahasrabuddhe } 75475ce4c2SSameer Sahasrabuddhe } 76475ce4c2SSameer Sahasrabuddhe 77475ce4c2SSameer Sahasrabuddhe template <> 78475ce4c2SSameer Sahasrabuddhe void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers( 79475ce4c2SSameer Sahasrabuddhe const MachineInstr &Instr) { 80475ce4c2SSameer Sahasrabuddhe assert(!isAlwaysUniform(Instr)); 81475ce4c2SSameer Sahasrabuddhe if (Instr.isTerminator()) 82475ce4c2SSameer Sahasrabuddhe return; 835022fc2aSJay Foad for (const MachineOperand &op : Instr.all_defs()) { 840a170eb7SSameer Sahasrabuddhe auto Reg = op.getReg(); 850a170eb7SSameer Sahasrabuddhe if (isDivergent(Reg)) 860a170eb7SSameer Sahasrabuddhe pushUsers(Reg); 87475ce4c2SSameer Sahasrabuddhe } 88475ce4c2SSameer Sahasrabuddhe } 89475ce4c2SSameer Sahasrabuddhe 90475ce4c2SSameer Sahasrabuddhe template <> 91475ce4c2SSameer Sahasrabuddhe bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::usesValueFromCycle( 92475ce4c2SSameer Sahasrabuddhe const MachineInstr &I, const MachineCycle &DefCycle) const { 93475ce4c2SSameer Sahasrabuddhe assert(!isAlwaysUniform(I)); 94475ce4c2SSameer Sahasrabuddhe for (auto &Op : I.operands()) { 95475ce4c2SSameer Sahasrabuddhe if (!Op.isReg() || !Op.readsReg()) 96475ce4c2SSameer Sahasrabuddhe continue; 97475ce4c2SSameer Sahasrabuddhe auto Reg = Op.getReg(); 985230f6c1SYashwant Singh 995230f6c1SYashwant Singh // FIXME: Physical registers need to be properly checked instead of always 1005230f6c1SYashwant Singh // returning true 1015230f6c1SYashwant Singh if (Reg.isPhysical()) 1025230f6c1SYashwant Singh return true; 1035230f6c1SYashwant Singh 104475ce4c2SSameer Sahasrabuddhe auto *Def = F.getRegInfo().getVRegDef(Reg); 105475ce4c2SSameer Sahasrabuddhe if (DefCycle.contains(Def->getParent())) 106475ce4c2SSameer Sahasrabuddhe return true; 107475ce4c2SSameer Sahasrabuddhe } 108475ce4c2SSameer Sahasrabuddhe return false; 109475ce4c2SSameer Sahasrabuddhe } 110475ce4c2SSameer Sahasrabuddhe 111f90849dfSpvanhout template <> 112b0f0dd25SSameer Sahasrabuddhe void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>:: 113b0f0dd25SSameer Sahasrabuddhe propagateTemporalDivergence(const MachineInstr &I, 114b0f0dd25SSameer Sahasrabuddhe const MachineCycle &DefCycle) { 115b0f0dd25SSameer Sahasrabuddhe const auto &RegInfo = F.getRegInfo(); 1165022fc2aSJay Foad for (auto &Op : I.all_defs()) { 117b0f0dd25SSameer Sahasrabuddhe if (!Op.getReg().isVirtual()) 118b0f0dd25SSameer Sahasrabuddhe continue; 119b0f0dd25SSameer Sahasrabuddhe auto Reg = Op.getReg(); 120b0f0dd25SSameer Sahasrabuddhe if (isDivergent(Reg)) 121b0f0dd25SSameer Sahasrabuddhe continue; 122b0f0dd25SSameer Sahasrabuddhe for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) { 123b0f0dd25SSameer Sahasrabuddhe if (DefCycle.contains(UserInstr.getParent())) 124b0f0dd25SSameer Sahasrabuddhe continue; 1250a170eb7SSameer Sahasrabuddhe markDivergent(UserInstr); 126b0f0dd25SSameer Sahasrabuddhe } 127b0f0dd25SSameer Sahasrabuddhe } 128b0f0dd25SSameer Sahasrabuddhe } 129b0f0dd25SSameer Sahasrabuddhe 130b0f0dd25SSameer Sahasrabuddhe template <> 131f90849dfSpvanhout bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::isDivergentUse( 132f90849dfSpvanhout const MachineOperand &U) const { 133f90849dfSpvanhout if (!U.isReg()) 134f90849dfSpvanhout return false; 135f90849dfSpvanhout 136f90849dfSpvanhout auto Reg = U.getReg(); 137f90849dfSpvanhout if (isDivergent(Reg)) 138f90849dfSpvanhout return true; 139f90849dfSpvanhout 140f90849dfSpvanhout const auto &RegInfo = F.getRegInfo(); 141f90849dfSpvanhout auto *Def = RegInfo.getOneDef(Reg); 142f90849dfSpvanhout if (!Def) 143f90849dfSpvanhout return true; 144f90849dfSpvanhout 145f90849dfSpvanhout auto *DefInstr = Def->getParent(); 146f90849dfSpvanhout auto *UseInstr = U.getParent(); 147f90849dfSpvanhout return isTemporalDivergent(*UseInstr->getParent(), *DefInstr); 148f90849dfSpvanhout } 149f90849dfSpvanhout 150475ce4c2SSameer Sahasrabuddhe // This ensures explicit instantiation of 151475ce4c2SSameer Sahasrabuddhe // GenericUniformityAnalysisImpl::ImplDeleter::operator() 152475ce4c2SSameer Sahasrabuddhe template class llvm::GenericUniformityInfo<MachineSSAContext>; 1535d98dc71SKrzysztof Drewniak template struct llvm::GenericUniformityAnalysisImplDeleter< 1545d98dc71SKrzysztof Drewniak llvm::GenericUniformityAnalysisImpl<MachineSSAContext>>; 155475ce4c2SSameer Sahasrabuddhe 156d61cba6dSMatt Arsenault MachineUniformityInfo llvm::computeMachineUniformityInfo( 157d61cba6dSMatt Arsenault MachineFunction &F, const MachineCycleInfo &cycleInfo, 158837dc542Spaperchalice const MachineDominatorTree &domTree, bool HasBranchDivergence) { 159ad3996c1SHaojian Wu assert(F.getRegInfo().isSSA() && "Expected to be run on SSA form!"); 160b14e30f1SSameer Sahasrabuddhe MachineUniformityInfo UI(domTree, cycleInfo); 161d61cba6dSMatt Arsenault if (HasBranchDivergence) 162d61cba6dSMatt Arsenault UI.compute(); 163d61cba6dSMatt Arsenault return UI; 164475ce4c2SSameer Sahasrabuddhe } 165475ce4c2SSameer Sahasrabuddhe 166475ce4c2SSameer Sahasrabuddhe namespace { 167475ce4c2SSameer Sahasrabuddhe 168475ce4c2SSameer Sahasrabuddhe class MachineUniformityInfoPrinterPass : public MachineFunctionPass { 169475ce4c2SSameer Sahasrabuddhe public: 170475ce4c2SSameer Sahasrabuddhe static char ID; 171475ce4c2SSameer Sahasrabuddhe 172475ce4c2SSameer Sahasrabuddhe MachineUniformityInfoPrinterPass(); 173475ce4c2SSameer Sahasrabuddhe 174475ce4c2SSameer Sahasrabuddhe bool runOnMachineFunction(MachineFunction &F) override; 175475ce4c2SSameer Sahasrabuddhe void getAnalysisUsage(AnalysisUsage &AU) const override; 176475ce4c2SSameer Sahasrabuddhe }; 177475ce4c2SSameer Sahasrabuddhe 178475ce4c2SSameer Sahasrabuddhe } // namespace 179475ce4c2SSameer Sahasrabuddhe 180475ce4c2SSameer Sahasrabuddhe char MachineUniformityAnalysisPass::ID = 0; 181475ce4c2SSameer Sahasrabuddhe 182475ce4c2SSameer Sahasrabuddhe MachineUniformityAnalysisPass::MachineUniformityAnalysisPass() 183475ce4c2SSameer Sahasrabuddhe : MachineFunctionPass(ID) { 184475ce4c2SSameer Sahasrabuddhe initializeMachineUniformityAnalysisPassPass(*PassRegistry::getPassRegistry()); 185475ce4c2SSameer Sahasrabuddhe } 186475ce4c2SSameer Sahasrabuddhe 187475ce4c2SSameer Sahasrabuddhe INITIALIZE_PASS_BEGIN(MachineUniformityAnalysisPass, "machine-uniformity", 188475ce4c2SSameer Sahasrabuddhe "Machine Uniformity Info Analysis", true, true) 189475ce4c2SSameer Sahasrabuddhe INITIALIZE_PASS_DEPENDENCY(MachineCycleInfoWrapperPass) 190837dc542Spaperchalice INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) 191475ce4c2SSameer Sahasrabuddhe INITIALIZE_PASS_END(MachineUniformityAnalysisPass, "machine-uniformity", 192475ce4c2SSameer Sahasrabuddhe "Machine Uniformity Info Analysis", true, true) 193475ce4c2SSameer Sahasrabuddhe 194475ce4c2SSameer Sahasrabuddhe void MachineUniformityAnalysisPass::getAnalysisUsage(AnalysisUsage &AU) const { 195475ce4c2SSameer Sahasrabuddhe AU.setPreservesAll(); 196475ce4c2SSameer Sahasrabuddhe AU.addRequired<MachineCycleInfoWrapperPass>(); 197837dc542Spaperchalice AU.addRequired<MachineDominatorTreeWrapperPass>(); 198475ce4c2SSameer Sahasrabuddhe MachineFunctionPass::getAnalysisUsage(AU); 199475ce4c2SSameer Sahasrabuddhe } 200475ce4c2SSameer Sahasrabuddhe 201475ce4c2SSameer Sahasrabuddhe bool MachineUniformityAnalysisPass::runOnMachineFunction(MachineFunction &MF) { 202*1562b70eSpaperchalice auto &DomTree = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); 203475ce4c2SSameer Sahasrabuddhe auto &CI = getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo(); 204d61cba6dSMatt Arsenault // FIXME: Query TTI::hasBranchDivergence. -run-pass seems to end up with a 205d61cba6dSMatt Arsenault // default NoTTI 206d61cba6dSMatt Arsenault UI = computeMachineUniformityInfo(MF, CI, DomTree, true); 207475ce4c2SSameer Sahasrabuddhe return false; 208475ce4c2SSameer Sahasrabuddhe } 209475ce4c2SSameer Sahasrabuddhe 210475ce4c2SSameer Sahasrabuddhe void MachineUniformityAnalysisPass::print(raw_ostream &OS, 211475ce4c2SSameer Sahasrabuddhe const Module *) const { 212475ce4c2SSameer Sahasrabuddhe OS << "MachineUniformityInfo for function: " << UI.getFunction().getName() 213475ce4c2SSameer Sahasrabuddhe << "\n"; 214475ce4c2SSameer Sahasrabuddhe UI.print(OS); 215475ce4c2SSameer Sahasrabuddhe } 216475ce4c2SSameer Sahasrabuddhe 217475ce4c2SSameer Sahasrabuddhe char MachineUniformityInfoPrinterPass::ID = 0; 218475ce4c2SSameer Sahasrabuddhe 219475ce4c2SSameer Sahasrabuddhe MachineUniformityInfoPrinterPass::MachineUniformityInfoPrinterPass() 220475ce4c2SSameer Sahasrabuddhe : MachineFunctionPass(ID) { 221475ce4c2SSameer Sahasrabuddhe initializeMachineUniformityInfoPrinterPassPass( 222475ce4c2SSameer Sahasrabuddhe *PassRegistry::getPassRegistry()); 223475ce4c2SSameer Sahasrabuddhe } 224475ce4c2SSameer Sahasrabuddhe 225475ce4c2SSameer Sahasrabuddhe INITIALIZE_PASS_BEGIN(MachineUniformityInfoPrinterPass, 226475ce4c2SSameer Sahasrabuddhe "print-machine-uniformity", 227475ce4c2SSameer Sahasrabuddhe "Print Machine Uniformity Info Analysis", true, true) 228475ce4c2SSameer Sahasrabuddhe INITIALIZE_PASS_DEPENDENCY(MachineUniformityAnalysisPass) 229475ce4c2SSameer Sahasrabuddhe INITIALIZE_PASS_END(MachineUniformityInfoPrinterPass, 230475ce4c2SSameer Sahasrabuddhe "print-machine-uniformity", 231475ce4c2SSameer Sahasrabuddhe "Print Machine Uniformity Info Analysis", true, true) 232475ce4c2SSameer Sahasrabuddhe 233475ce4c2SSameer Sahasrabuddhe void MachineUniformityInfoPrinterPass::getAnalysisUsage( 234475ce4c2SSameer Sahasrabuddhe AnalysisUsage &AU) const { 235475ce4c2SSameer Sahasrabuddhe AU.setPreservesAll(); 236475ce4c2SSameer Sahasrabuddhe AU.addRequired<MachineUniformityAnalysisPass>(); 237475ce4c2SSameer Sahasrabuddhe MachineFunctionPass::getAnalysisUsage(AU); 238475ce4c2SSameer Sahasrabuddhe } 239475ce4c2SSameer Sahasrabuddhe 240475ce4c2SSameer Sahasrabuddhe bool MachineUniformityInfoPrinterPass::runOnMachineFunction( 241475ce4c2SSameer Sahasrabuddhe MachineFunction &F) { 242475ce4c2SSameer Sahasrabuddhe auto &UI = getAnalysis<MachineUniformityAnalysisPass>(); 243475ce4c2SSameer Sahasrabuddhe UI.print(errs()); 244475ce4c2SSameer Sahasrabuddhe return false; 245475ce4c2SSameer Sahasrabuddhe } 246