diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:03:47 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:04:23 +0000 |
commit | 7fa27ce4a07f19b07799a767fc29416f3b625afb (patch) | |
tree | 27825c83636c4de341eb09a74f49f5d38a15d165 /llvm/lib/CodeGen/MachineUniformityAnalysis.cpp | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'llvm/lib/CodeGen/MachineUniformityAnalysis.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineUniformityAnalysis.cpp | 95 |
1 files changed, 68 insertions, 27 deletions
diff --git a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp index 2fe5e40a58c2..0e02c50284c6 100644 --- a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp +++ b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp @@ -20,9 +20,7 @@ using namespace llvm; template <> bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::hasDivergentDefs( const MachineInstr &I) const { - for (auto &op : I.operands()) { - if (!op.isReg() || !op.isDef()) - continue; + for (auto &op : I.all_defs()) { if (isDivergent(op.getReg())) return true; } @@ -31,21 +29,17 @@ bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::hasDivergentDefs( template <> bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::markDefsDivergent( - const MachineInstr &Instr, bool AllDefsDivergent) { + const MachineInstr &Instr) { bool insertedDivergent = false; const auto &MRI = F.getRegInfo(); + const auto &RBI = *F.getSubtarget().getRegBankInfo(); const auto &TRI = *MRI.getTargetRegisterInfo(); - for (auto &op : Instr.operands()) { - if (!op.isReg() || !op.isDef()) - continue; + for (auto &op : Instr.all_defs()) { if (!op.getReg().isVirtual()) continue; assert(!op.getSubReg()); - if (!AllDefsDivergent) { - auto *RC = MRI.getRegClassOrNull(op.getReg()); - if (RC && !TRI.isDivergentRegClass(RC)) - continue; - } + if (TRI.isUniformReg(MRI, RBI, op.getReg())) + continue; insertedDivergent |= markDivergent(op.getReg()); } return insertedDivergent; @@ -64,7 +58,7 @@ void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() { } if (uniformity == InstructionUniformity::NeverUniform) { - markDefsDivergent(instr, /* AllDefsDivergent = */ false); + markDivergent(instr); } } } @@ -73,12 +67,10 @@ void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() { template <> void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers( Register Reg) { + assert(isDivergent(Reg)); const auto &RegInfo = F.getRegInfo(); for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) { - if (isAlwaysUniform(UserInstr)) - continue; - if (markDivergent(UserInstr)) - Worklist.push_back(&UserInstr); + markDivergent(UserInstr); } } @@ -88,9 +80,10 @@ void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers( assert(!isAlwaysUniform(Instr)); if (Instr.isTerminator()) return; - for (const MachineOperand &op : Instr.operands()) { - if (op.isReg() && op.isDef() && op.getReg().isVirtual()) - pushUsers(op.getReg()); + for (const MachineOperand &op : Instr.all_defs()) { + auto Reg = op.getReg(); + if (isDivergent(Reg)) + pushUsers(Reg); } } @@ -102,7 +95,12 @@ bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::usesValueFromCycle( if (!Op.isReg() || !Op.readsReg()) continue; auto Reg = Op.getReg(); - assert(Reg.isVirtual()); + + // FIXME: Physical registers need to be properly checked instead of always + // returning true + if (Reg.isPhysical()) + return true; + auto *Def = F.getRegInfo().getVRegDef(Reg); if (DefCycle.contains(Def->getParent())) return true; @@ -110,18 +108,59 @@ bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::usesValueFromCycle( return false; } +template <> +void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>:: + propagateTemporalDivergence(const MachineInstr &I, + const MachineCycle &DefCycle) { + const auto &RegInfo = F.getRegInfo(); + for (auto &Op : I.all_defs()) { + if (!Op.getReg().isVirtual()) + continue; + auto Reg = Op.getReg(); + if (isDivergent(Reg)) + continue; + for (MachineInstr &UserInstr : RegInfo.use_instructions(Reg)) { + if (DefCycle.contains(UserInstr.getParent())) + continue; + markDivergent(UserInstr); + } + } +} + +template <> +bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::isDivergentUse( + const MachineOperand &U) const { + if (!U.isReg()) + return false; + + auto Reg = U.getReg(); + if (isDivergent(Reg)) + return true; + + const auto &RegInfo = F.getRegInfo(); + auto *Def = RegInfo.getOneDef(Reg); + if (!Def) + return true; + + auto *DefInstr = Def->getParent(); + auto *UseInstr = U.getParent(); + return isTemporalDivergent(*UseInstr->getParent(), *DefInstr); +} + // This ensures explicit instantiation of // GenericUniformityAnalysisImpl::ImplDeleter::operator() template class llvm::GenericUniformityInfo<MachineSSAContext>; template struct llvm::GenericUniformityAnalysisImplDeleter< llvm::GenericUniformityAnalysisImpl<MachineSSAContext>>; -MachineUniformityInfo -llvm::computeMachineUniformityInfo(MachineFunction &F, - const MachineCycleInfo &cycleInfo, - const MachineDomTree &domTree) { +MachineUniformityInfo llvm::computeMachineUniformityInfo( + MachineFunction &F, const MachineCycleInfo &cycleInfo, + const MachineDomTree &domTree, bool HasBranchDivergence) { assert(F.getRegInfo().isSSA() && "Expected to be run on SSA form!"); - return MachineUniformityInfo(F, domTree, cycleInfo); + MachineUniformityInfo UI(F, domTree, cycleInfo); + if (HasBranchDivergence) + UI.compute(); + return UI; } namespace { @@ -181,7 +220,9 @@ void MachineUniformityAnalysisPass::getAnalysisUsage(AnalysisUsage &AU) const { bool MachineUniformityAnalysisPass::runOnMachineFunction(MachineFunction &MF) { auto &DomTree = getAnalysis<MachineDominatorTree>().getBase(); auto &CI = getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo(); - UI = computeMachineUniformityInfo(MF, CI, DomTree); + // FIXME: Query TTI::hasBranchDivergence. -run-pass seems to end up with a + // default NoTTI + UI = computeMachineUniformityInfo(MF, CI, DomTree, true); return false; } |