[llvm] [Uniformity] Implement per-output machine uniformity analysis (PR #179275)
Sameer Sahasrabuddhe via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 3 01:02:20 PST 2026
================
@@ -46,24 +46,86 @@ bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::markDefsDivergent(
return insertedDivergent;
}
+template <>
+bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::isAlwaysUniform(
+ const MachineInstr &Instr) const {
+ // For MIR, an instruction is "always uniform" only if it has at least one
+ // virtual register def AND all those defs are in UniformOverrides.
+ // Instructions with no virtual register defs (e.g., terminators like
+ // G_BRCOND, G_BR) return false to ensure they can be properly processed
+ // for divergence during propagation.
+ bool HasVirtualDef = false;
+ for (const MachineOperand &Op : Instr.all_defs()) {
+ if (!Op.getReg().isVirtual())
+ continue;
+ HasVirtualDef = true;
+ if (!UniformOverrides.contains(Op.getReg()))
+ return false;
+ }
+ // Only return true if we found at least one virtual def and all were uniform
+ return HasVirtualDef;
+}
+
template <>
void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() {
- const auto &InstrInfo = *F.getSubtarget().getInstrInfo();
-
- for (const MachineBasicBlock &block : F) {
- for (const MachineInstr &instr : block) {
- auto uniformity = InstrInfo.getInstructionUniformity(instr);
-
- switch (uniformity) {
- case InstructionUniformity::AlwaysUniform:
- addUniformOverride(instr);
- break;
- case InstructionUniformity::NeverUniform:
- markDivergent(instr);
- break;
- case InstructionUniformity::Default:
- break;
+ const TargetInstrInfo &InstrInfo = *F.getSubtarget().getInstrInfo();
+ const MachineRegisterInfo &MRI = F.getRegInfo();
+ const RegisterBankInfo &RBI = *F.getSubtarget().getRegBankInfo();
+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+
+ for (const MachineBasicBlock &Block : F) {
+ for (const MachineInstr &Instr : Block) {
+ // Terminators are handled separately because:
+ // 1. Many terminators (G_BRCOND, G_BR) have no def operands, so the
+ // per-def loop below would skip them entirely.
+ // 2. Divergent terminators mark the BLOCK as divergent
+ // (DivergentTermBlocks),
----------------
ssahasra wrote:
Fix indentation. Probably meant to be on the line above?
https://github.com/llvm/llvm-project/pull/179275
More information about the llvm-commits
mailing list