From ebd16d1a56a0d689a4eb04c48d4bd664a5edebe7 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Tue, 28 May 2024 12:50:48 -0500 Subject: [PATCH] nak: Add some helpers for uniform instructions and registers Part-of: --- src/nouveau/compiler/nak/ir.rs | 48 +++++++++++++++++++++++++++++ src/nouveau/compiler/nak/ir_proc.rs | 18 +++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index 0da720bb1f4..d58b88ddde7 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -105,6 +105,22 @@ impl RegFile { } } + pub fn to_uniform(&self) -> Option { + match self { + RegFile::GPR | RegFile::UGPR => Some(RegFile::UGPR), + RegFile::Pred | RegFile::UPred => Some(RegFile::UPred), + RegFile::Carry | RegFile::Bar | RegFile::Mem => None, + } + } + + pub fn to_warp(&self) -> RegFile { + match self { + RegFile::GPR | RegFile::UGPR => RegFile::GPR, + RegFile::Pred | RegFile::UPred => RegFile::Pred, + RegFile::Carry | RegFile::Bar | RegFile::Mem => *self, + } + } + /// Returns true if the register file is general-purpose pub fn is_gpr(&self) -> bool { match self { @@ -1412,9 +1428,27 @@ pub trait SrcsAsSlice { fn src_types(&self) -> SrcTypeList; } +fn all_dsts_uniform(dsts: &[Dst]) -> bool { + let mut uniform = None; + for dst in dsts { + let dst_uniform = match dst { + Dst::None => continue, + Dst::Reg(r) => r.is_uniform(), + Dst::SSA(r) => r.is_uniform(), + }; + assert!(uniform == None || uniform == Some(dst_uniform)); + uniform = Some(dst_uniform); + } + uniform == Some(true) +} + pub trait DstsAsSlice { fn dsts_as_slice(&self) -> &[Dst]; fn dsts_as_mut_slice(&mut self) -> &mut [Dst]; + + fn is_uniform(&self) -> bool { + all_dsts_uniform(self.dsts_as_slice()) + } } fn fmt_dst_slice(f: &mut fmt::Formatter<'_>, dsts: &[Dst]) -> fmt::Result { @@ -4928,6 +4962,10 @@ impl DstsAsSlice for OpPhiDsts { fn dsts_as_mut_slice(&mut self) -> &mut [Dst] { &mut self.dsts.b } + + fn is_uniform(&self) -> bool { + false + } } impl DisplayOp for OpPhiDsts { @@ -5590,6 +5628,16 @@ impl Instr { } } + pub fn is_uniform(&self) -> bool { + self.op.is_uniform() + } + + pub fn can_be_uniform(&self, sm: u8) -> bool { + match self.op { + _ => false, + } + } + pub fn has_fixed_latency(&self, _sm: u8) -> bool { match &self.op { // Float ALU diff --git a/src/nouveau/compiler/nak/ir_proc.rs b/src/nouveau/compiler/nak/ir_proc.rs index 23cd5780e26..032c2652178 100644 --- a/src/nouveau/compiler/nak/ir_proc.rs +++ b/src/nouveau/compiler/nak/ir_proc.rs @@ -191,6 +191,7 @@ fn derive_as_slice( let mut as_slice_cases = TokenStream2::new(); let mut as_mut_slice_cases = TokenStream2::new(); let mut src_types_cases = TokenStream2::new(); + let mut is_uniform_cases = TokenStream2::new(); for v in e.variants { let case = v.ident; as_slice_cases.extend(quote! { @@ -204,6 +205,11 @@ fn derive_as_slice( #ident::#case(x) => x.src_types(), }); } + if search_type == "Dst" { + is_uniform_cases.extend(quote! { + #ident::#case(x) => x.is_uniform(), + }); + } } let src_type_func = if search_type == "Src" { quote! { @@ -216,6 +222,17 @@ fn derive_as_slice( } else { TokenStream2::new() }; + let is_uniform_func = if search_type == "Dst" { + quote! { + fn is_uniform(&self) -> bool { + match self { + #is_uniform_cases + } + } + } + } else { + TokenStream2::new() + }; quote! { impl #trait_name for #ident { fn #as_slice(&self) -> &[#elem_type] { @@ -231,6 +248,7 @@ fn derive_as_slice( } #src_type_func + #is_uniform_func } } .into()