diff --git a/src/nouveau/compiler/nak_assign_regs.rs b/src/nouveau/compiler/nak_assign_regs.rs index 5d4d7648074..58be634963a 100644 --- a/src/nouveau/compiler/nak_assign_regs.rs +++ b/src/nouveau/compiler/nak_assign_regs.rs @@ -509,9 +509,9 @@ fn instr_remap_srcs_file( pcopy: &mut OpParCopy, ra: &mut RegFileAllocation, ) { - if let Pred::SSA(pred) = instr.pred { + if let PredRef::SSA(pred) = instr.pred.pred_ref { if pred.file() == ra.file() { - instr.pred = ra.get_scalar(pred).into(); + instr.pred.pred_ref = ra.get_scalar(pred).into(); } } @@ -787,7 +787,7 @@ impl AssignRegsBlock { None } Op::PhiDsts(phi) => { - assert!(instr.pred.is_none()); + assert!(instr.pred.is_true()); for (id, dst) in phi.iter() { if let Dst::SSA(ssa) = dst { @@ -836,7 +836,7 @@ impl AssignRegsBlock { for (ip, instr) in b.instrs.drain(..).enumerate() { /* Build up the kill set */ killed.clear(); - if let Pred::SSA(ssa) = &instr.pred { + if let PredRef::SSA(ssa) = &instr.pred.pred_ref { if !bl.is_live_after(ssa, ip) { killed.insert(*ssa); } diff --git a/src/nouveau/compiler/nak_calc_instr_deps.rs b/src/nouveau/compiler/nak_calc_instr_deps.rs index 8639ab91c84..6180d42c6f6 100644 --- a/src/nouveau/compiler/nak_calc_instr_deps.rs +++ b/src/nouveau/compiler/nak_calc_instr_deps.rs @@ -331,7 +331,9 @@ impl Shader { instr.deps.set_wr_bar(0); wt |= 1 << 0; } - if !instr.pred.is_none() || instr.srcs().len() > 0 { + if !instr.pred.pred_ref.is_none() + || instr.srcs().len() > 0 + { instr.deps.set_rd_bar(1); wt |= 1 << 1; } diff --git a/src/nouveau/compiler/nak_encode_sm75.rs b/src/nouveau/compiler/nak_encode_sm75.rs index 9af51b8817a..e0370ad3ffd 100644 --- a/src/nouveau/compiler/nak_encode_sm75.rs +++ b/src/nouveau/compiler/nak_encode_sm75.rs @@ -228,17 +228,17 @@ impl SM75Instr { self.set_field(0..12, opcode); } - fn set_pred(&mut self, pred: &Pred, pred_inv: bool) { - assert!(!pred.is_none() || !pred_inv); + fn set_pred(&mut self, pred: &Pred) { + assert!(!pred.is_false()); self.set_pred_reg( 12..15, - match pred { - Pred::None => RegRef::zero(RegFile::Pred, 1), - Pred::Reg(reg) => *reg, - Pred::SSA(_) => panic!("SSA values must be lowered"), + match pred.pred_ref { + PredRef::None => RegRef::zero(RegFile::Pred, 1), + PredRef::Reg(reg) => reg, + PredRef::SSA(_) => panic!("SSA values must be lowered"), }, ); - self.set_bit(15, pred_inv); + self.set_bit(15, pred.pred_inv); } fn set_dst(&mut self, dst: Dst) { @@ -1507,7 +1507,7 @@ impl SM75Instr { _ => panic!("Unhandled instruction"), } - si.set_pred(&instr.pred, instr.pred_inv); + si.set_pred(&instr.pred); si.set_instr_deps(&instr.deps); si.inst diff --git a/src/nouveau/compiler/nak_from_nir.rs b/src/nouveau/compiler/nak_from_nir.rs index c37df0d7706..4a6fe746a3a 100644 --- a/src/nouveau/compiler/nak_from_nir.rs +++ b/src/nouveau/compiler/nak_from_nir.rs @@ -1382,7 +1382,7 @@ impl<'a> ShaderFromNir<'a> { let if_bra = self.blocks.last_mut().unwrap().branch_mut().unwrap(); if_bra.pred = cond.into(); /* This is the branch to jump to the else */ - if_bra.pred_inv = true; + if_bra.pred.pred_inv = true; self.parse_cf_list(ni.iter_then_list()); self.parse_cf_list(ni.iter_else_list()); diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index 26b0a5099e8..09e5aafeaaa 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -2991,17 +2991,17 @@ pub enum Op { FSOut(OpFSOut), } -pub enum Pred { +pub enum PredRef { None, SSA(SSAValue), Reg(RegRef), } -impl Pred { +impl PredRef { #[allow(dead_code)] pub fn as_reg(&self) -> Option<&RegRef> { match self { - Pred::Reg(r) => Some(r), + PredRef::Reg(r) => Some(r), _ => None, } } @@ -3009,39 +3009,71 @@ impl Pred { #[allow(dead_code)] pub fn as_ssa(&self) -> Option<&SSAValue> { match self { - Pred::SSA(r) => Some(r), + PredRef::SSA(r) => Some(r), _ => None, } } pub fn is_none(&self) -> bool { match self { - Pred::None => true, + PredRef::None => true, _ => false, } } } -impl From for Pred { - fn from(reg: RegRef) -> Pred { - Pred::Reg(reg) +impl From for PredRef { + fn from(reg: RegRef) -> PredRef { + PredRef::Reg(reg) } } -impl From for Pred { - fn from(ssa: SSAValue) -> Pred { - Pred::SSA(ssa) +impl From for PredRef { + fn from(ssa: SSAValue) -> PredRef { + PredRef::SSA(ssa) + } +} + +impl fmt::Display for PredRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + PredRef::None => write!(f, "PT"), + PredRef::SSA(ssa) => ssa.fmt(f), + PredRef::Reg(reg) => reg.fmt(f), + } + } +} + +pub struct Pred { + pub pred_ref: PredRef, + pub pred_inv: bool, +} + +impl Pred { + pub fn is_true(&self) -> bool { + self.pred_ref.is_none() && !self.pred_inv + } + + pub fn is_false(&self) -> bool { + self.pred_ref.is_none() && self.pred_inv + } +} + +impl> From for Pred { + fn from(p: T) -> Self { + Pred { + pred_ref: p.into(), + pred_inv: false, + } } } impl fmt::Display for Pred { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Pred::None => (), - Pred::SSA(s) => s.fmt(f)?, - Pred::Reg(r) => r.fmt(f)?, + if self.pred_inv { + write!(f, "!")?; } - Ok(()) + self.pred_ref.fmt(f) } } @@ -3141,7 +3173,6 @@ impl fmt::Display for InstrDeps { pub struct Instr { pub pred: Pred, - pub pred_inv: bool, pub op: Op, pub deps: InstrDeps, } @@ -3150,8 +3181,7 @@ impl Instr { pub fn new(op: impl Into) -> Instr { Instr { op: op.into(), - pred: Pred::None, - pred_inv: false, + pred: PredRef::None.into(), deps: InstrDeps::new(), } } @@ -3514,12 +3544,8 @@ impl Instr { impl fmt::Display for Instr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if !self.pred.is_none() { - if self.pred_inv { - write!(f, "@!{} ", self.pred)?; - } else { - write!(f, "@{} ", self.pred)?; - } + if !self.pred.is_true() { + write!(f, "@{} ", self.pred)?; } write!(f, "{} {}", self.op, self.deps) } @@ -3582,7 +3608,7 @@ impl BasicBlock { pub fn falls_through(&self) -> bool { if let Some(i) = self.branch() { - !i.pred.is_none() + !i.pred.is_true() } else { true } diff --git a/src/nouveau/compiler/nak_liveness.rs b/src/nouveau/compiler/nak_liveness.rs index 0fa9d503b4f..d52d0ec2fee 100644 --- a/src/nouveau/compiler/nak_liveness.rs +++ b/src/nouveau/compiler/nak_liveness.rs @@ -42,7 +42,7 @@ impl BlockLiveness { fn add_live_block(&mut self, block: &BasicBlock) { for (ip, instr) in block.instrs.iter().enumerate() { - if let Pred::SSA(val) = &instr.pred { + if let PredRef::SSA(val) = &instr.pred.pred_ref { self.add_use(val, ip); } diff --git a/src/nouveau/compiler/nak_lower_par_copies.rs b/src/nouveau/compiler/nak_lower_par_copies.rs index 5aa2ec0dd5f..c055e1360a2 100644 --- a/src/nouveau/compiler/nak_lower_par_copies.rs +++ b/src/nouveau/compiler/nak_lower_par_copies.rs @@ -188,7 +188,7 @@ impl Shader { self.map_instrs(&|instr, _| -> Vec { match instr.op { Op::ParCopy(pc) => { - assert!(instr.pred.is_none()); + assert!(instr.pred.is_true()); lower_par_copy(pc) } _ => vec![instr], diff --git a/src/nouveau/compiler/nak_opt_copy_prop.rs b/src/nouveau/compiler/nak_opt_copy_prop.rs index c47712b9871..ddefb43087f 100644 --- a/src/nouveau/compiler/nak_opt_copy_prop.rs +++ b/src/nouveau/compiler/nak_opt_copy_prop.rs @@ -71,10 +71,10 @@ impl CopyPropPass { self.ssa_map.get(dst) } - fn prop_to_pred(&self, pred: &mut Pred, pred_inv: &mut bool) { + fn prop_to_pred(&self, pred: &mut Pred) { loop { - let src_ssa = match &pred { - Pred::SSA(ssa) => ssa, + let src_ssa = match &pred.pred_ref { + PredRef::SSA(ssa) => ssa, _ => return, }; @@ -85,15 +85,15 @@ impl CopyPropPass { match entry.src.src_ref { SrcRef::True => { - *pred = Pred::None; + pred.pred_ref = PredRef::None; } SrcRef::False => { - *pred = Pred::None; - *pred_inv = !*pred_inv; + pred.pred_ref = PredRef::None; + pred.pred_inv = !pred.pred_inv; } SrcRef::SSA(ssa) => { assert!(ssa.comps() == 1); - *pred = Pred::SSA(ssa[0]); + pred.pred_ref = PredRef::SSA(ssa[0]); } _ => return, } @@ -101,7 +101,7 @@ impl CopyPropPass { match entry.src.src_mod { SrcMod::None => (), SrcMod::BNot => { - *pred_inv = !*pred_inv; + pred.pred_inv = !pred.pred_inv; } _ => panic!("Invalid predicate modifier"), } @@ -427,7 +427,7 @@ impl CopyPropPass { _ => (), } - self.prop_to_pred(&mut instr.pred, &mut instr.pred_inv); + self.prop_to_pred(&mut instr.pred); let src_types = instr.src_types(); for (i, src) in instr.srcs_mut().iter_mut().enumerate() { diff --git a/src/nouveau/compiler/nak_opt_dce.rs b/src/nouveau/compiler/nak_opt_dce.rs index 2051e2898a9..4d13182540c 100644 --- a/src/nouveau/compiler/nak_opt_dce.rs +++ b/src/nouveau/compiler/nak_opt_dce.rs @@ -60,7 +60,7 @@ impl DeadCodePass { } fn is_instr_live(&self, instr: &Instr) -> bool { - if instr.pred.is_none() && instr.pred_inv { + if instr.pred.is_false() { return false; } @@ -80,7 +80,7 @@ impl DeadCodePass { fn mark_instr(&mut self, instr: &Instr) { match &instr.op { Op::PhiSrcs(phi) => { - assert!(instr.pred.is_none()); + assert!(instr.pred.is_true()); for (id, src) in phi.iter() { if self.is_phi_live(*id) { self.mark_src_live(src); @@ -90,7 +90,7 @@ impl DeadCodePass { } } Op::PhiDsts(phi) => { - assert!(instr.pred.is_none()); + assert!(instr.pred.is_true()); for (id, dst) in phi.iter() { if self.is_dst_live(dst) { self.mark_phi_live(*id); @@ -100,7 +100,7 @@ impl DeadCodePass { } } Op::ParCopy(pcopy) => { - assert!(instr.pred.is_none()); + assert!(instr.pred.is_true()); for (src, dst) in pcopy.iter() { if self.is_dst_live(dst) { self.mark_src_live(src); @@ -111,7 +111,7 @@ impl DeadCodePass { } _ => { if self.is_instr_live(instr) { - if let Pred::SSA(ssa) = &instr.pred { + if let PredRef::SSA(ssa) = &instr.pred.pred_ref { self.mark_ssa_live(ssa); } diff --git a/src/nouveau/compiler/nak_opt_lop.rs b/src/nouveau/compiler/nak_opt_lop.rs index 69f9ec05d87..39152c73916 100644 --- a/src/nouveau/compiler/nak_opt_lop.rs +++ b/src/nouveau/compiler/nak_opt_lop.rs @@ -33,7 +33,7 @@ impl LopPass { let mut use_counts = HashMap::new(); for b in &f.blocks { for instr in &b.instrs { - if let Pred::SSA(ssa) = instr.pred { + if let PredRef::SSA(ssa) = instr.pred.pred_ref { use_counts.entry(ssa).and_modify(|e| *e += 1).or_insert(1); }