Skip to content

Commit

Permalink
[naga] Compact out unused anonymous overrides.
Browse files Browse the repository at this point in the history
In compaction, remove unused anonymous overrides.

To simplify overload processing, we plan to make all override-sized
arrays refer to their lengths via actual `Override`s. Arrays with
non-identifier override expressions as their lengths would refer to
anonymous `Override`s with interesting `init` expressions. But in
order to avoid re-introducing gfx-rs#6788, we need compaction to remove
anonymous overrides.
  • Loading branch information
jimblandy committed Feb 6, 2025
1 parent 4741e53 commit 9669b94
Show file tree
Hide file tree
Showing 4 changed files with 335 additions and 50 deletions.
37 changes: 23 additions & 14 deletions naga/src/compact/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::arena::{Arena, Handle};

pub struct ExpressionTracer<'tracer> {
pub constants: &'tracer Arena<crate::Constant>,
pub overrides: &'tracer Arena<crate::Override>,

/// The arena in which we are currently tracing expressions.
pub expressions: &'tracer Arena<crate::Expression>,
Expand All @@ -13,6 +14,9 @@ pub struct ExpressionTracer<'tracer> {
/// The used map for `constants`.
pub constants_used: &'tracer mut HandleSet<crate::Constant>,

/// The used map for `overrides`.
pub overrides_used: &'tracer mut HandleSet<crate::Override>,

/// The used set for `arena`.
///
/// This points to whatever arena holds the expressions we are
Expand Down Expand Up @@ -78,25 +82,32 @@ impl ExpressionTracer<'_> {
| Ex::SubgroupBallotResult
| Ex::RayQueryProceedResult => {}

// Expressions can refer to constants and overrides, which can refer
// in turn to expressions, which complicates our nice one-pass
// algorithm. But since constants and overrides don't refer to each
// other directly, only via expressions, we can get around this by
// looking *through* each constant/override and marking its
// initializer expression as used immediately. Since `expr` refers
// to the constant/override, which then refers to the initializer,
// the initializer must precede `expr` in the arena, so we know we
// have yet to visit the initializer, so it's not too late to mark
// it.
Ex::Constant(handle) => {
self.constants_used.insert(handle);
// Constants and expressions are mutually recursive, which
// complicates our nice one-pass algorithm. However, since
// constants don't refer to each other, we can get around
// this by looking *through* each constant and marking its
// initializer as used. Since `expr` refers to the constant,
// and the constant refers to the initializer, it must
// precede `expr` in the arena.
let init = self.constants[handle].init;
match self.global_expressions_used {
Some(ref mut used) => used.insert(init),
None => self.expressions_used.insert(init),
};
}
Ex::Override(_) => {
// All overrides are considered used by definition. We mark
// their types and initialization expressions as used in
// `compact::compact`, so we have no more work to do here.
Ex::Override(handle) => {
self.overrides_used.insert(handle);
if let Some(init) = self.overrides[handle].init {
match self.global_expressions_used {
Some(ref mut used) => used.insert(init),
None => self.expressions_used.insert(init),
};
}
}
Ex::ZeroValue(ty) => {
self.types_used.insert(ty);
Expand Down Expand Up @@ -256,11 +267,9 @@ impl ModuleMap {
| Ex::SubgroupBallotResult
| Ex::RayQueryProceedResult => {}

// All overrides are retained, so their handles never change.
Ex::Override(_) => {}

// Expressions that contain handles that need to be adjusted.
Ex::Constant(ref mut constant) => self.constants.adjust(constant),
Ex::Override(ref mut r#override) => self.overrides.adjust(r#override),
Ex::ZeroValue(ref mut ty) => self.types.adjust(ty),
Ex::Compose {
ref mut ty,
Expand Down
4 changes: 4 additions & 0 deletions naga/src/compact/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ use super::{FunctionMap, ModuleMap};
pub struct FunctionTracer<'a> {
pub function: &'a crate::Function,
pub constants: &'a crate::Arena<crate::Constant>,
pub overrides: &'a crate::Arena<crate::Override>,

pub types_used: &'a mut HandleSet<crate::Type>,
pub constants_used: &'a mut HandleSet<crate::Constant>,
pub overrides_used: &'a mut HandleSet<crate::Override>,
pub global_expressions_used: &'a mut HandleSet<crate::Expression>,

/// Function-local expressions used.
Expand Down Expand Up @@ -47,10 +49,12 @@ impl FunctionTracer<'_> {
fn as_expression(&mut self) -> super::expressions::ExpressionTracer {
super::expressions::ExpressionTracer {
constants: self.constants,
overrides: self.overrides,
expressions: &self.function.expressions,

types_used: self.types_used,
constants_used: self.constants_used,
overrides_used: self.overrides_used,
expressions_used: &mut self.expressions_used,
global_expressions_used: Some(&mut self.global_expressions_used),
}
Expand Down
Loading

0 comments on commit 9669b94

Please sign in to comment.