diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/naga/src/compact/functions.rs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/naga/src/compact/functions.rs')
-rw-r--r-- | third_party/rust/naga/src/compact/functions.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/third_party/rust/naga/src/compact/functions.rs b/third_party/rust/naga/src/compact/functions.rs new file mode 100644 index 0000000000..b0d08c7e96 --- /dev/null +++ b/third_party/rust/naga/src/compact/functions.rs @@ -0,0 +1,106 @@ +use super::handle_set_map::HandleSet; +use super::{FunctionMap, ModuleMap}; + +pub struct FunctionTracer<'a> { + pub function: &'a crate::Function, + pub constants: &'a crate::Arena<crate::Constant>, + + pub types_used: &'a mut HandleSet<crate::Type>, + pub constants_used: &'a mut HandleSet<crate::Constant>, + pub const_expressions_used: &'a mut HandleSet<crate::Expression>, + + /// Function-local expressions used. + pub expressions_used: HandleSet<crate::Expression>, +} + +impl<'a> FunctionTracer<'a> { + pub fn trace(&mut self) { + for argument in self.function.arguments.iter() { + self.types_used.insert(argument.ty); + } + + if let Some(ref result) = self.function.result { + self.types_used.insert(result.ty); + } + + for (_, local) in self.function.local_variables.iter() { + self.types_used.insert(local.ty); + if let Some(init) = local.init { + self.expressions_used.insert(init); + } + } + + // Treat named expressions as alive, for the sake of our test suite, + // which uses `let blah = expr;` to exercise lots of things. + for (&value, _name) in &self.function.named_expressions { + self.expressions_used.insert(value); + } + + self.trace_block(&self.function.body); + + // Given that `trace_block` has marked the expressions used + // directly by statements, walk the arena to find all + // expressions used, directly or indirectly. + self.as_expression().trace_expressions(); + } + + fn as_expression(&mut self) -> super::expressions::ExpressionTracer { + super::expressions::ExpressionTracer { + constants: self.constants, + expressions: &self.function.expressions, + + types_used: self.types_used, + constants_used: self.constants_used, + expressions_used: &mut self.expressions_used, + const_expressions_used: Some(&mut self.const_expressions_used), + } + } +} + +impl FunctionMap { + pub fn compact( + &self, + function: &mut crate::Function, + module_map: &ModuleMap, + reuse: &mut crate::NamedExpressions, + ) { + assert!(reuse.is_empty()); + + for argument in function.arguments.iter_mut() { + module_map.types.adjust(&mut argument.ty); + } + + if let Some(ref mut result) = function.result { + module_map.types.adjust(&mut result.ty); + } + + for (_, local) in function.local_variables.iter_mut() { + log::trace!("adjusting local variable {:?}", local.name); + module_map.types.adjust(&mut local.ty); + if let Some(ref mut init) = local.init { + self.expressions.adjust(init); + } + } + + // Drop unused expressions, reusing existing storage. + function.expressions.retain_mut(|handle, expr| { + if self.expressions.used(handle) { + module_map.adjust_expression(expr, &self.expressions); + true + } else { + false + } + }); + + // Adjust named expressions. + for (mut handle, name) in function.named_expressions.drain(..) { + self.expressions.adjust(&mut handle); + reuse.insert(handle, name); + } + std::mem::swap(&mut function.named_expressions, reuse); + assert!(reuse.is_empty()); + + // Adjust statements. + self.adjust_body(function); + } +} |