nak: Add some helpers for uniform instructions and registers

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29591>
This commit is contained in:
Faith Ekstrand
2024-05-28 12:50:48 -05:00
committed by Marge Bot
parent 0f70b14d9a
commit ebd16d1a56
2 changed files with 66 additions and 0 deletions
+48
View File
@@ -105,6 +105,22 @@ impl RegFile {
}
}
pub fn to_uniform(&self) -> Option<RegFile> {
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
+18
View File
@@ -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()