From e201d4fa771a9baac46d46068989dffa1ba220df Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 2 Apr 2026 13:46:05 +0200 Subject: [PATCH] compiler/rust: Move VecPair from NAK to shared compiler crate Move the VecPair data structure from NAK's ir.rs to the shared compiler Rust crate so it can be reused by other backends. The fields are private, and NAK's ir.rs (now in a different crate) needs to read and mutate the inner Vecs. Add a_as_slice(..), a_as_mut_slice(..), b_as_slice(..) and b_as_mut_slice(..), and update NAK's SrcsAsSlice and DstsAsSlice impls to call them. Returning slices keeps callers from changing the length of one side without the other, which is what VecPair is built to prevent. Signed-off-by: Christian Gmeiner Reviewed-by: Mel Henning Reviewed-by: Faith Ekstrand Part-of: --- src/compiler/rust/lib.rs | 1 + src/compiler/rust/meson.build | 1 + src/compiler/rust/vec_pair.rs | 104 +++++++++++++++++++++++++++++++++ src/nouveau/compiler/nak/ir.rs | 101 +++----------------------------- 4 files changed, 115 insertions(+), 92 deletions(-) create mode 100644 src/compiler/rust/vec_pair.rs diff --git a/src/compiler/rust/lib.rs b/src/compiler/rust/lib.rs index 68b0087f18b..318fda2d3d6 100644 --- a/src/compiler/rust/lib.rs +++ b/src/compiler/rust/lib.rs @@ -11,3 +11,4 @@ pub mod memstream; pub mod nir; pub mod nir_instr_printer; pub mod smallvec; +pub mod vec_pair; diff --git a/src/compiler/rust/meson.build b/src/compiler/rust/meson.build index 2dbf2bfe176..e7638718350 100644 --- a/src/compiler/rust/meson.build +++ b/src/compiler/rust/meson.build @@ -11,6 +11,7 @@ _compiler_rs_sources = [ 'nir_instr_printer.rs', 'nir.rs', 'smallvec.rs', + 'vec_pair.rs', ] _compiler_binding_types = [ diff --git a/src/compiler/rust/vec_pair.rs b/src/compiler/rust/vec_pair.rs new file mode 100644 index 00000000000..ed216be2eef --- /dev/null +++ b/src/compiler/rust/vec_pair.rs @@ -0,0 +1,104 @@ +// Copyright © 2022 Collabora, Ltd. +// SPDX-License-Identifier: MIT + +use std::iter::Zip; +use std::slice; + +pub struct VecPair { + a: Vec, + b: Vec, +} + +impl VecPair { + pub fn a_as_slice(&self) -> &[A] { + &self.a + } + + pub fn a_as_mut_slice(&mut self) -> &mut [A] { + &mut self.a + } + + pub fn b_as_slice(&self) -> &[B] { + &self.b + } + + pub fn b_as_mut_slice(&mut self) -> &mut [B] { + &mut self.b + } + + pub fn append(&mut self, other: &mut VecPair) { + self.a.append(&mut other.a); + self.b.append(&mut other.b); + } + + pub fn is_empty(&self) -> bool { + debug_assert!(self.a.len() == self.b.len()); + self.a.is_empty() + } + + pub fn iter(&self) -> Zip, slice::Iter<'_, B>> { + debug_assert!(self.a.len() == self.b.len()); + self.a.iter().zip(self.b.iter()) + } + + pub fn iter_mut( + &mut self, + ) -> Zip, slice::IterMut<'_, B>> { + debug_assert!(self.a.len() == self.b.len()); + self.a.iter_mut().zip(self.b.iter_mut()) + } + + pub fn len(&self) -> usize { + debug_assert!(self.a.len() == self.b.len()); + self.a.len() + } + + pub fn new() -> Self { + Self { + a: Vec::new(), + b: Vec::new(), + } + } + + pub fn push(&mut self, a: A, b: B) { + debug_assert!(self.a.len() == self.b.len()); + self.a.push(a); + self.b.push(b); + } +} + +impl VecPair { + pub fn retain(&mut self, mut f: impl FnMut(&A, &B) -> bool) { + debug_assert!(self.a.len() == self.b.len()); + let len = self.a.len(); + let mut i = 0_usize; + while i < len { + if !f(&self.a[i], &self.b[i]) { + break; + } + i += 1; + } + + let mut new_len = i; + + // Don't check this one twice. + i += 1; + + while i < len { + // This could be more efficient but it's good enough for our + // purposes since everything we're storing is small and has a + // trivial Drop. + if f(&self.a[i], &self.b[i]) { + self.a[new_len] = self.a[i].clone(); + self.b[new_len] = self.b[i].clone(); + new_len += 1; + } + i += 1; + } + + if new_len < len { + self.a.truncate(new_len); + self.b.truncate(new_len); + } + } +} diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index 29c9a5cb93a..8e7418f6c05 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -19,11 +19,11 @@ use compiler::as_slice::*; use compiler::cfg::CFG; use compiler::dataflow::ForwardDataflow; use compiler::smallvec::SmallVec; +use compiler::vec_pair::VecPair; use nak_ir_proc::*; use std::cmp::{max, min}; use std::fmt; use std::fmt::Write; -use std::iter::Zip; use std::ops::{BitAnd, BitOr, Deref, DerefMut, Index, IndexMut, Not, Range}; use std::slice; @@ -7627,89 +7627,6 @@ impl DisplayOp for OpSrcBar { } impl_display_for_op!(OpSrcBar); -pub struct VecPair { - a: Vec, - b: Vec, -} - -impl VecPair { - pub fn append(&mut self, other: &mut VecPair) { - self.a.append(&mut other.a); - self.b.append(&mut other.b); - } - - pub fn is_empty(&self) -> bool { - debug_assert!(self.a.len() == self.b.len()); - self.a.is_empty() - } - - pub fn iter(&self) -> Zip, slice::Iter<'_, B>> { - debug_assert!(self.a.len() == self.b.len()); - self.a.iter().zip(self.b.iter()) - } - - pub fn iter_mut( - &mut self, - ) -> Zip, slice::IterMut<'_, B>> { - debug_assert!(self.a.len() == self.b.len()); - self.a.iter_mut().zip(self.b.iter_mut()) - } - - pub fn len(&self) -> usize { - debug_assert!(self.a.len() == self.b.len()); - self.a.len() - } - - pub fn new() -> Self { - Self { - a: Vec::new(), - b: Vec::new(), - } - } - - pub fn push(&mut self, a: A, b: B) { - debug_assert!(self.a.len() == self.b.len()); - self.a.push(a); - self.b.push(b); - } -} - -impl VecPair { - pub fn retain(&mut self, mut f: impl FnMut(&A, &B) -> bool) { - debug_assert!(self.a.len() == self.b.len()); - let len = self.a.len(); - let mut i = 0_usize; - while i < len { - if !f(&self.a[i], &self.b[i]) { - break; - } - i += 1; - } - - let mut new_len = i; - - // Don't check this one twice. - i += 1; - - while i < len { - // This could be more efficient but it's good enough for our - // purposes since everything we're storing is small and has a - // trivial Drop. - if f(&self.a[i], &self.b[i]) { - self.a[new_len] = self.a[i].clone(); - self.b[new_len] = self.b[i].clone(); - new_len += 1; - } - i += 1; - } - - if new_len < len { - self.a.truncate(new_len); - self.b.truncate(new_len); - } - } -} - mod phi { #[allow(unused_imports)] use crate::ir::{OpPhiDsts, OpPhiSrcs}; @@ -7804,11 +7721,11 @@ impl OpPhiSrcs { impl SrcsAsSlice for OpPhiSrcs { fn srcs_as_slice(&self) -> &[Src] { - &self.srcs.b + self.srcs.b_as_slice() } fn srcs_as_mut_slice(&mut self) -> &mut [Src] { - &mut self.srcs.b + self.srcs.b_as_mut_slice() } fn src_types(&self) -> SrcTypeList { @@ -7851,11 +7768,11 @@ impl OpPhiDsts { impl DstsAsSlice for OpPhiDsts { fn dsts_as_slice(&self) -> &[Dst] { - &self.dsts.b + self.dsts.b_as_slice() } fn dsts_as_mut_slice(&mut self) -> &mut [Dst] { - &mut self.dsts.b + self.dsts.b_as_mut_slice() } fn dst_types(&self) -> DstTypeList { @@ -7966,11 +7883,11 @@ impl OpParCopy { impl SrcsAsSlice for OpParCopy { fn srcs_as_slice(&self) -> &[Src] { - &self.dsts_srcs.b + self.dsts_srcs.b_as_slice() } fn srcs_as_mut_slice(&mut self) -> &mut [Src] { - &mut self.dsts_srcs.b + self.dsts_srcs.b_as_mut_slice() } fn src_types(&self) -> SrcTypeList { @@ -7980,11 +7897,11 @@ impl SrcsAsSlice for OpParCopy { impl DstsAsSlice for OpParCopy { fn dsts_as_slice(&self) -> &[Dst] { - &self.dsts_srcs.a + self.dsts_srcs.a_as_slice() } fn dsts_as_mut_slice(&mut self) -> &mut [Dst] { - &mut self.dsts_srcs.a + self.dsts_srcs.a_as_mut_slice() } fn dst_types(&self) -> DstTypeList {