[msl-out] test put_expession stack footprint in debug

Also change io::Error to fmt::Error
This commit is contained in:
Dzmitry Malyshau
2021-03-18 09:53:57 -04:00
committed by Dzmitry Malyshau
parent 6e71366bd3
commit 8c4598a141
2 changed files with 56 additions and 7 deletions

View File

@@ -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::<Error>(), 96);
}

View File

@@ -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<W> {
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<W: Write> Writer<W> {
named_expressions: BitSet::new(),
typifier: Typifier::new(),
namer: Namer::default(),
#[cfg(test)]
put_expression_stack_pointers: Default::default(),
}
}
@@ -203,6 +206,11 @@ impl<W: Write> Writer<W> {
expr_handle: Handle<crate::Expression>,
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<W: Write> Writer<W> {
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);
}