Reduce the typifier error sizes

This commit is contained in:
Dzmitry Malyshau
2021-03-18 10:20:16 -04:00
committed by Dzmitry Malyshau
parent 8c4598a141
commit 72ede02888
3 changed files with 60 additions and 71 deletions

View File

@@ -255,5 +255,5 @@ pub fn write_string(
#[test]
fn test_error_size() {
use std::mem::size_of;
assert_eq!(size_of::<Error>(), 96);
assert_eq!(size_of::<Error>(), 48);
}

View File

@@ -209,7 +209,8 @@ impl<W: Write> Writer<W> {
// 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);
}
}

View File

@@ -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<crate::Expression>, #[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::<ResolveError>(), 80);
assert_eq!(size_of::<TypifyError>(), 88);
assert_eq!(size_of::<ResolveError>(), 32);
assert_eq!(size_of::<TypifyError>(), 40);
}