From 72ede02888f139b4f618aa08fc733b9babf648aa Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 18 Mar 2021 10:20:16 -0400 Subject: [PATCH] Reduce the typifier error sizes --- src/back/msl/mod.rs | 2 +- src/back/msl/writer.rs | 25 +++++++--- src/proc/typifier.rs | 104 ++++++++++++++++------------------------- 3 files changed, 60 insertions(+), 71 deletions(-) diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index 54082701da..e08df6b9d9 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -255,5 +255,5 @@ pub fn write_string( #[test] fn test_error_size() { use std::mem::size_of; - assert_eq!(size_of::(), 96); + assert_eq!(size_of::(), 48); } diff --git a/src/back/msl/writer.rs b/src/back/msl/writer.rs index ea37f82079..5ccbf842fb 100644 --- a/src/back/msl/writer.rs +++ b/src/back/msl/writer.rs @@ -209,7 +209,8 @@ impl Writer { // 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 ()); + 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())?; @@ -1500,19 +1501,28 @@ fn test_stack_size() { }, }); let mut fun = crate::Function::default(); - let const_expr = fun.expressions.append(crate::Expression::Constant(constant)); + 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() }); + 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(); + 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); @@ -1520,5 +1530,8 @@ fn test_stack_size() { } let stack_size = max_addr - min_addr; // check the size (in debug only) - debug_assert_eq!(stack_size, 39856); + // last observed macOS value: 25696 + if stack_size > 26000 { + panic!("`put_expression` stack size {} is too large!", stack_size); + } } diff --git a/src/proc/typifier.rs b/src/proc/typifier.rs index 2f3d3831e4..e849c31887 100644 --- a/src/proc/typifier.rs +++ b/src/proc/typifier.rs @@ -77,16 +77,11 @@ pub enum ResolveError { FunctionReturnsVoid, #[error("Type is not found in the given immutable arena")] TypeNotFound, - #[error("Incompatible operand: {op} {operand}")] - IncompatibleOperand { op: String, operand: String }, - #[error("Incompatible operands: {left} {op} {right}")] - IncompatibleOperands { - op: String, - left: String, - right: String, - }, + #[error("Incompatible operands: {0}")] + IncompatibleOperands(String), } +#[repr(C)] // pack this tighter: 48 -> 40 bytes #[derive(Clone, Debug, Error, PartialEq)] #[error("Type resolution of {0:?} failed")] pub struct TypifyError(Handle, #[source] ResolveError); @@ -441,11 +436,10 @@ impl Typifier { width, }) } else { - return Err(ResolveError::IncompatibleOperands { - op: "x".to_string(), - left: format!("{:?}", ty_left), - right: format!("{:?}", ty_right), - }); + return Err(ResolveError::IncompatibleOperands(format!( + "{:?} * {:?}", + ty_left, ty_right + ))); } } crate::BinaryOperator::Equal @@ -462,10 +456,10 @@ impl Typifier { Ti::Scalar { .. } => Ti::Scalar { kind, width }, Ti::Vector { size, .. } => Ti::Vector { size, kind, width }, ref other => { - return Err(ResolveError::IncompatibleOperand { - op: "logical".to_string(), - operand: format!("{:?}", other), - }) + return Err(ResolveError::IncompatibleOperands(format!( + "{:?}({:?}, _)", + op, other + ))) } }; Resolution::Value(inner) @@ -530,27 +524,21 @@ impl Typifier { size: _, width, } => Resolution::Value(Ti::Scalar { kind, width }), - ref other => { - return Err(ResolveError::IncompatibleOperand { - op: "dot product".to_string(), - operand: format!("{:?}", other), - }) - } + ref other => + return Err(ResolveError::IncompatibleOperands( + format!("{:?}({:?}, _)", fun, other) + )), }, Mf::Outer => { - let arg1 = arg1.ok_or_else(|| ResolveError::IncompatibleOperand { - op: "outer product".to_string(), - operand: "".to_string(), - })?; + let arg1 = arg1.ok_or_else(|| ResolveError::IncompatibleOperands( + format!("{:?}(_, None)", fun) + ))?; match (self.get(arg, types), self.get(arg1,types)) { (&Ti::Vector {kind: _, size: columns,width}, &Ti::Vector{ size: rows, .. }) => Resolution::Value(Ti::Matrix { columns, rows, width }), - (left, right) => { - return Err(ResolveError::IncompatibleOperands { - op: "outer product".to_string(), - left: format!("{:?}", left), - right: format!("{:?}", right), - }) - } + (left, right) => + return Err(ResolveError::IncompatibleOperands( + format!("{:?}({:?}, {:?})", fun, left, right) + )), } }, Mf::Cross => self.resolutions[arg.index()].clone(), @@ -558,12 +546,9 @@ impl Typifier { Mf::Length => match *self.get(arg, types) { Ti::Scalar {width,kind} | Ti::Vector {width,kind,size:_} => Resolution::Value(Ti::Scalar { kind, width }), - ref other => { - return Err(ResolveError::IncompatibleOperand { - op: format!("{:?}", fun), - operand: format!("{:?}", other), - }) - } + ref other => return Err(ResolveError::IncompatibleOperands( + format!("{:?}({:?})", fun, other) + )), }, Mf::Normalize | Mf::FaceForward | @@ -586,12 +571,9 @@ impl Typifier { rows: columns, width, }), - ref other => { - return Err(ResolveError::IncompatibleOperand { - op: "transpose".to_string(), - operand: format!("{:?}", other), - }) - } + ref other => return Err(ResolveError::IncompatibleOperands( + format!("{:?}({:?})", fun, other) + )), }, Mf::Inverse => match *self.get(arg, types) { Ti::Matrix { @@ -603,24 +585,18 @@ impl Typifier { rows, width, }), - ref other => { - return Err(ResolveError::IncompatibleOperand { - op: "inverse".to_string(), - operand: format!("{:?}", other), - }) - } + ref other => return Err(ResolveError::IncompatibleOperands( + format!("{:?}({:?})", fun, other) + )), }, Mf::Determinant => match *self.get(arg, types) { Ti::Matrix { width, .. } => Resolution::Value(Ti::Scalar { kind: crate::ScalarKind::Float, width }), - ref other => { - return Err(ResolveError::IncompatibleOperand { - op: "determinant".to_string(), - operand: format!("{:?}", other), - }) - } + ref other => return Err(ResolveError::IncompatibleOperands( + format!("{:?}({:?})", fun, other) + )), }, // bits Mf::CountOneBits | @@ -639,10 +615,10 @@ impl Typifier { width, } => Resolution::Value(Ti::Vector { kind, size, width }), ref other => { - return Err(ResolveError::IncompatibleOperand { - op: "as".to_string(), - operand: format!("{:?}", other), - }) + return Err(ResolveError::IncompatibleOperands(format!( + "{:?} as {:?}", + other, kind + ))) } }, crate::Expression::Call(function) => { @@ -696,6 +672,6 @@ impl Typifier { #[test] fn test_error_size() { use std::mem::size_of; - assert_eq!(size_of::(), 80); - assert_eq!(size_of::(), 88); + assert_eq!(size_of::(), 32); + assert_eq!(size_of::(), 40); }