From 8c4598a141b29515d9ee377dcfdbd097a0db889f Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 18 Mar 2021 09:53:57 -0400 Subject: [PATCH] [msl-out] test put_expession stack footprint in debug Also change io::Error to fmt::Error --- src/back/msl/mod.rs | 15 ++++++++----- src/back/msl/writer.rs | 48 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index 177a945967..54082701da 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -29,7 +29,7 @@ use crate::{ FastHashMap, }; use std::{ - io::{Error as IoError, Write}, + fmt::{Error as FmtError, Write}, string::FromUtf8Error, }; @@ -68,7 +68,7 @@ enum ResolvedBinding { #[derive(Debug, thiserror::Error)] pub enum Error { #[error(transparent)] - IO(#[from] IoError), + Format(#[from] FmtError), #[error(transparent)] Utf8(#[from] FromUtf8Error), #[error(transparent)] @@ -247,8 +247,13 @@ pub fn write_string( analysis: &Analysis, options: &Options, ) -> Result<(String, TranslationInfo), Error> { - let mut w = writer::Writer::new(Vec::new()); + let mut w = writer::Writer::new(String::new()); let info = w.write(module, analysis, options)?; - let string = String::from_utf8(w.finish())?; - Ok((string, info)) + Ok((w.finish(), info)) +} + +#[test] +fn test_error_size() { + use std::mem::size_of; + assert_eq!(size_of::(), 96); } diff --git a/src/back/msl/writer.rs b/src/back/msl/writer.rs index 0c82e72297..ea37f82079 100644 --- a/src/back/msl/writer.rs +++ b/src/back/msl/writer.rs @@ -9,8 +9,7 @@ use crate::{ }; use bit_set::BitSet; use std::{ - fmt::{Display, Error as FmtError, Formatter}, - io::Write, + fmt::{Display, Error as FmtError, Formatter, Write}, iter, }; @@ -73,6 +72,8 @@ pub struct Writer { named_expressions: BitSet, typifier: Typifier, namer: Namer, + #[cfg(test)] + put_expression_stack_pointers: crate::FastHashSet<*const ()>, } fn scalar_kind_string(kind: crate::ScalarKind) -> &'static str { @@ -158,6 +159,8 @@ impl Writer { named_expressions: BitSet::new(), typifier: Typifier::new(), namer: Namer::default(), + #[cfg(test)] + put_expression_stack_pointers: Default::default(), } } @@ -203,6 +206,11 @@ impl Writer { expr_handle: Handle, context: &ExpressionContext, ) -> Result<(), Error> { + // Add to the set in order to track the stack size. + #[cfg(test)] + #[allow(trivial_casts)] + self.put_expression_stack_pointers.insert(&expr_handle as *const _ as *const ()); + if self.named_expressions.contains(expr_handle.index()) { write!(self.out, "{}{}", BAKE_PREFIX, expr_handle.index())?; return Ok(()); @@ -1478,3 +1486,39 @@ impl Writer { Ok(info) } } + +#[test] +fn test_stack_size() { + // create a module with at least one expression nested + let mut module = crate::Module::default(); + let constant = module.constants.append(crate::Constant { + name: None, + specialization: None, + inner: crate::ConstantInner::Scalar { + value: crate::ScalarValue::Float(1.0), + width: 4, + }, + }); + let mut fun = crate::Function::default(); + let const_expr = fun.expressions.append(crate::Expression::Constant(constant)); + let nested_expr = fun.expressions.append(crate::Expression::Unary { + op: crate::UnaryOperator::Negate, + expr: const_expr, + }); + fun.body.push(crate::Statement::Emit(fun.expressions.range_from(1))); + fun.body.push(crate::Statement::If { condition: nested_expr, accept: Vec::new(), reject: Vec::new() }); + let _ = module.functions.append(fun); + // analyse the module + let analysis = Analysis::new(&module).unwrap(); + // process the module + let mut writer = Writer::new(String::new()); + writer.write(&module, &analysis, &Default::default()).unwrap(); + let (mut min_addr, mut max_addr) = (!0usize, 0usize); + for pointer in writer.put_expression_stack_pointers { + min_addr = min_addr.min(pointer as usize); + max_addr = max_addr.max(pointer as usize); + } + let stack_size = max_addr - min_addr; + // check the size (in debug only) + debug_assert_eq!(stack_size, 39856); +}