about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-05-14 13:51:24 +1000
committerZalathar <Zalathar@users.noreply.github.com>2024-05-14 13:58:40 +1000
commitd01df6f9aadf58a00357bd89b8fc25a44822ba77 (patch)
tree4b2aa4b799457fe91c953b5462682577b793c54f /compiler/rustc_mir_transform
parenta68bb5e176ff7f250c0af00467a6793952be7489 (diff)
downloadrust-d01df6f9aadf58a00357bd89b8fc25a44822ba77.tar.gz
rust-d01df6f9aadf58a00357bd89b8fc25a44822ba77.zip
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.
Diffstat (limited to 'compiler/rustc_mir_transform')
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 908b1495b66..b5968517d77 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -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 }
     }