coverage: Simplify counter expressions using simple algebra

Some of these cases currently don't occur in practice, but are included for
completeness, and to avoid having to add them later as branch coverage and
MC/DC coverage start building more complex expressions.
This commit is contained in:
Zalathar 2024-05-14 13:51:24 +10:00
parent a68bb5e176
commit d01df6f9aa
43 changed files with 845 additions and 1315 deletions

View file

@ -115,6 +115,43 @@ impl CoverageCounters {
expressions: &mut IndexVec<ExpressionId, BcbExpression>,
new_expr: BcbExpression,
) -> BcbCounter {
// Simplify expressions using basic algebra.
//
// Some of these cases might not actually occur in practice, depending
// on the details of how the instrumentor builds expressions.
let BcbExpression { lhs, op, rhs } = new_expr;
if let BcbCounter::Expression { id } = lhs {
let lhs_expr = &expressions[id];
// Simplify `(a - b) + b` to `a`.
if lhs_expr.op == Op::Subtract && op == Op::Add && lhs_expr.rhs == rhs {
return lhs_expr.lhs;
}
// Simplify `(a + b) - b` to `a`.
if lhs_expr.op == Op::Add && op == Op::Subtract && lhs_expr.rhs == rhs {
return lhs_expr.lhs;
}
// Simplify `(a + b) - a` to `b`.
if lhs_expr.op == Op::Add && op == Op::Subtract && lhs_expr.lhs == rhs {
return lhs_expr.rhs;
}
}
if let BcbCounter::Expression { id } = rhs {
let rhs_expr = &expressions[id];
// Simplify `a + (b - a)` to `b`.
if op == Op::Add && rhs_expr.op == Op::Subtract && lhs == rhs_expr.rhs {
return rhs_expr.lhs;
}
// Simplify `a - (a - b)` to `b`.
if op == Op::Subtract && rhs_expr.op == Op::Subtract && lhs == rhs_expr.lhs {
return rhs_expr.rhs;
}
}
// Simplification failed, so actually create the new expression.
let id = expressions.push(new_expr);
BcbCounter::Expression { id }
}