aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-07-26 19:03:47 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-07-26 19:04:23 +0000
commit7fa27ce4a07f19b07799a767fc29416f3b625afb (patch)
tree27825c83636c4de341eb09a74f49f5d38a15d165 /llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
parente3b557809604d036af6e00c60f012c2025b59a5e (diff)
Diffstat (limited to 'llvm/lib/CodeGen/MachineUniformityAnalysis.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineUniformityAnalysis.cpp95
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;
}