about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-11-25 17:23:32 -0500
committerGitHub <noreply@github.com>2023-11-25 17:23:32 -0500
commitfd1a263fc7029b06a8f041feadbcc85c65b0a6e8 (patch)
tree45032f8f123089d2b420e0c6cbde7ed821611528
parentec1393f14efa179a968ec5b99c1ed62719198267 (diff)
parent3163bc870016ac42f2204057f7e43ec81674aba1 (diff)
downloadrust-fd1a263fc7029b06a8f041feadbcc85c65b0a6e8.tar.gz
rust-fd1a263fc7029b06a8f041feadbcc85c65b0a6e8.zip
Rollup merge of #117651 - Zalathar:fold-sums, r=cjgillot
coverage: Simplify building coverage expressions based on sums

This is a combination of some interlinked changes to the code that creates coverage counters/expressions for nodes and edges in the coverage graph:

- Some preparatory cleanups in `MakeBcbCounters::make_branch_counters`
- Use `BcbCounter` (instead of `CovTerm`) when building coverage expressions
  - This makes it easier to introduce a fold for building sums
- Simplify the creation of coverage expressions based on sums, by having `Iterator::fold` do much of the work
- Get rid of the awkward `BcbBranch` enum, and replace it with graph edges represented as `(from_bcb, to_bcb)`
  - This further simplifies the body of the fold
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs309
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs66
-rw-r--r--tests/coverage/async.cov-map28
-rw-r--r--tests/coverage/conditions.cov-map10
-rw-r--r--tests/coverage/continue.cov-map46
-rw-r--r--tests/coverage/coroutine.cov-map8
-rw-r--r--tests/coverage/loops_branches.cov-map90
-rw-r--r--tests/coverage/try_error_result.cov-map18
8 files changed, 270 insertions, 305 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 1e11d8d09b6..604589e5b96 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -1,18 +1,16 @@
-use super::graph;
-
-use graph::{BasicCoverageBlock, BcbBranch, CoverageGraph, TraverseCoverageGraphWithLoops};
-
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::WithNumNodes;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
 use rustc_middle::mir::coverage::*;
 
+use super::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops};
+
 use std::fmt::{self, Debug};
 
 /// The coverage counter or counter expression associated with a particular
 /// BCB node or BCB edge.
-#[derive(Clone)]
+#[derive(Clone, Copy)]
 pub(super) enum BcbCounter {
     Counter { id: CounterId },
     Expression { id: ExpressionId },
@@ -88,11 +86,20 @@ impl CoverageCounters {
         BcbCounter::Counter { id }
     }
 
-    fn make_expression(&mut self, lhs: CovTerm, op: Op, rhs: CovTerm) -> BcbCounter {
-        let id = self.expressions.push(Expression { lhs, op, rhs });
+    fn make_expression(&mut self, lhs: BcbCounter, op: Op, rhs: BcbCounter) -> BcbCounter {
+        let expression = Expression { lhs: lhs.as_term(), op, rhs: rhs.as_term() };
+        let id = self.expressions.push(expression);
         BcbCounter::Expression { id }
     }
 
+    /// Variant of `make_expression` that makes `lhs` optional and assumes [`Op::Add`].
+    ///
+    /// This is useful when using [`Iterator::fold`] to build an arbitrary-length sum.
+    fn make_sum_expression(&mut self, lhs: Option<BcbCounter>, rhs: BcbCounter) -> BcbCounter {
+        let Some(lhs) = lhs else { return rhs };
+        self.make_expression(lhs, Op::Add, rhs)
+    }
+
     /// Counter IDs start from one and go up.
     fn next_counter(&mut self) -> CounterId {
         let next = self.next_counter_id;
@@ -109,7 +116,7 @@ impl CoverageCounters {
         self.expressions.len()
     }
 
-    fn set_bcb_counter(&mut self, bcb: BasicCoverageBlock, counter_kind: BcbCounter) -> CovTerm {
+    fn set_bcb_counter(&mut self, bcb: BasicCoverageBlock, counter_kind: BcbCounter) -> BcbCounter {
         assert!(
             // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
             // have an expression (to be injected into an existing `BasicBlock` represented by this
@@ -118,14 +125,13 @@ impl CoverageCounters {
             "attempt to add a `Counter` to a BCB target with existing incoming edge counters"
         );
 
-        let term = counter_kind.as_term();
         if let Some(replaced) = self.bcb_counters[bcb].replace(counter_kind) {
             bug!(
                 "attempt to set a BasicCoverageBlock coverage counter more than once; \
                 {bcb:?} already had counter {replaced:?}",
             );
         } else {
-            term
+            counter_kind
         }
     }
 
@@ -134,7 +140,7 @@ impl CoverageCounters {
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
         counter_kind: BcbCounter,
-    ) -> CovTerm {
+    ) -> BcbCounter {
         // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
         // have an expression (to be injected into an existing `BasicBlock` represented by this
         // `BasicCoverageBlock`).
@@ -148,19 +154,18 @@ impl CoverageCounters {
         }
 
         self.bcb_has_incoming_edge_counters.insert(to_bcb);
-        let term = counter_kind.as_term();
         if let Some(replaced) = self.bcb_edge_counters.insert((from_bcb, to_bcb), counter_kind) {
             bug!(
                 "attempt to set an edge counter more than once; from_bcb: \
                 {from_bcb:?} already had counter {replaced:?}",
             );
         } else {
-            term
+            counter_kind
         }
     }
 
-    pub(super) fn bcb_counter(&self, bcb: BasicCoverageBlock) -> Option<&BcbCounter> {
-        self.bcb_counters[bcb].as_ref()
+    pub(super) fn bcb_counter(&self, bcb: BasicCoverageBlock) -> Option<BcbCounter> {
+        self.bcb_counters[bcb]
     }
 
     pub(super) fn bcb_node_counters(
@@ -226,11 +231,7 @@ impl<'a> MakeBcbCounters<'a> {
         while let Some(bcb) = traversal.next() {
             if bcb_has_coverage_spans(bcb) {
                 debug!("{:?} has at least one coverage span. Get or make its counter", bcb);
-                let branching_counter_operand = self.get_or_make_counter_operand(bcb);
-
-                if self.bcb_needs_branch_counters(bcb) {
-                    self.make_branch_counters(&traversal, bcb, branching_counter_operand);
-                }
+                self.make_node_and_branch_counters(&traversal, bcb);
             } else {
                 debug!(
                     "{:?} does not have any coverage spans. A counter will only be added if \
@@ -247,100 +248,93 @@ impl<'a> MakeBcbCounters<'a> {
         );
     }
 
-    fn make_branch_counters(
+    fn make_node_and_branch_counters(
         &mut self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
-        branching_bcb: BasicCoverageBlock,
-        branching_counter_operand: CovTerm,
+        from_bcb: BasicCoverageBlock,
     ) {
-        let branches = self.bcb_branches(branching_bcb);
+        // First, ensure that this node has a counter of some kind.
+        // We might also use its term later to compute one of the branch counters.
+        let from_bcb_operand = self.get_or_make_counter_operand(from_bcb);
+
+        let branch_target_bcbs = self.basic_coverage_blocks.successors[from_bcb].as_slice();
+
+        // If this node doesn't have multiple out-edges, or all of its out-edges
+        // already have counters, then we don't need to create edge counters.
+        let needs_branch_counters = branch_target_bcbs.len() > 1
+            && branch_target_bcbs
+                .iter()
+                .any(|&to_bcb| self.branch_has_no_counter(from_bcb, to_bcb));
+        if !needs_branch_counters {
+            return;
+        }
+
         debug!(
-            "{:?} has some branch(es) without counters:\n  {}",
-            branching_bcb,
-            branches
+            "{from_bcb:?} has some branch(es) without counters:\n  {}",
+            branch_target_bcbs
                 .iter()
-                .map(|branch| { format!("{:?}: {:?}", branch, self.branch_counter(branch)) })
+                .map(|&to_bcb| {
+                    format!("{from_bcb:?}->{to_bcb:?}: {:?}", self.branch_counter(from_bcb, to_bcb))
+                })
                 .collect::<Vec<_>>()
                 .join("\n  "),
         );
 
-        // Use the `traversal` state to decide if a subset of the branches exit a loop, making it
-        // likely that branch is executed less than branches that do not exit the same loop. In this
-        // case, any branch that does not exit the loop (and has not already been assigned a
-        // counter) should be counted by expression, if possible. (If a preferred expression branch
-        // is not selected based on the loop context, select any branch without an existing
-        // counter.)
-        let expression_branch = self.choose_preferred_expression_branch(traversal, &branches);
-
-        // Assign a Counter or Expression to each branch, plus additional `Expression`s, as needed,
-        // to sum up intermediate results.
-        let mut some_sumup_counter_operand = None;
-        for branch in branches {
-            // Skip the selected `expression_branch`, if any. It's expression will be assigned after
-            // all others.
-            if branch != expression_branch {
-                let branch_counter_operand = if branch.is_only_path_to_target() {
-                    debug!(
-                        "  {:?} has only one incoming edge (from {:?}), so adding a \
-                        counter",
-                        branch, branching_bcb
-                    );
-                    self.get_or_make_counter_operand(branch.target_bcb)
-                } else {
-                    debug!("  {:?} has multiple incoming edges, so adding an edge counter", branch);
-                    self.get_or_make_edge_counter_operand(branching_bcb, branch.target_bcb)
-                };
-                if let Some(sumup_counter_operand) =
-                    some_sumup_counter_operand.replace(branch_counter_operand)
-                {
-                    let intermediate_expression = self.coverage_counters.make_expression(
-                        branch_counter_operand,
-                        Op::Add,
-                        sumup_counter_operand,
-                    );
-                    debug!("  [new intermediate expression: {:?}]", intermediate_expression);
-                    let intermediate_expression_operand = intermediate_expression.as_term();
-                    some_sumup_counter_operand.replace(intermediate_expression_operand);
-                }
-            }
-        }
+        // Of the branch edges that don't have counters yet, one can be given an expression
+        // (computed from the other edges) instead of a dedicated counter.
+        let expression_to_bcb = self.choose_preferred_expression_branch(traversal, from_bcb);
 
-        // Assign the final expression to the `expression_branch` by subtracting the total of all
-        // other branches from the counter of the branching BCB.
-        let sumup_counter_operand =
-            some_sumup_counter_operand.expect("sumup_counter_operand should have a value");
+        // For each branch arm other than the one that was chosen to get an expression,
+        // ensure that it has a counter (existing counter/expression or a new counter),
+        // and accumulate the corresponding terms into a single sum term.
+        let sum_of_all_other_branches: BcbCounter = {
+            let _span = debug_span!("sum_of_all_other_branches", ?expression_to_bcb).entered();
+            branch_target_bcbs
+                .iter()
+                .copied()
+                // Skip the chosen branch, since we'll calculate it from the other branches.
+                .filter(|&to_bcb| to_bcb != expression_to_bcb)
+                .fold(None, |accum, to_bcb| {
+                    let _span = debug_span!("to_bcb", ?accum, ?to_bcb).entered();
+                    let branch_counter = self.get_or_make_edge_counter_operand(from_bcb, to_bcb);
+                    Some(self.coverage_counters.make_sum_expression(accum, branch_counter))
+                })
+                .expect("there must be at least one other branch")
+        };
+
+        // For the branch that was chosen to get an expression, create that expression
+        // by taking the count of the node we're branching from, and subtracting the
+        // sum of all the other branches.
         debug!(
-            "Making an expression for the selected expression_branch: {:?} \
-            (expression_branch predecessors: {:?})",
-            expression_branch,
-            self.bcb_predecessors(expression_branch.target_bcb),
+            "Making an expression for the selected expression_branch: \
+            {expression_to_bcb:?} (expression_branch predecessors: {:?})",
+            self.bcb_predecessors(expression_to_bcb),
         );
         let expression = self.coverage_counters.make_expression(
-            branching_counter_operand,
+            from_bcb_operand,
             Op::Subtract,
-            sumup_counter_operand,
+            sum_of_all_other_branches,
         );
-        debug!("{:?} gets an expression: {:?}", expression_branch, expression);
-        let bcb = expression_branch.target_bcb;
-        if expression_branch.is_only_path_to_target() {
-            self.coverage_counters.set_bcb_counter(bcb, expression);
+        debug!("{expression_to_bcb:?} gets an expression: {expression:?}");
+        if self.basic_coverage_blocks.bcb_has_multiple_in_edges(expression_to_bcb) {
+            self.coverage_counters.set_bcb_edge_counter(from_bcb, expression_to_bcb, expression);
         } else {
-            self.coverage_counters.set_bcb_edge_counter(branching_bcb, bcb, expression);
+            self.coverage_counters.set_bcb_counter(expression_to_bcb, expression);
         }
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn get_or_make_counter_operand(&mut self, bcb: BasicCoverageBlock) -> CovTerm {
+    fn get_or_make_counter_operand(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
         // If the BCB already has a counter, return it.
-        if let Some(counter_kind) = &self.coverage_counters.bcb_counters[bcb] {
+        if let Some(counter_kind) = self.coverage_counters.bcb_counters[bcb] {
             debug!("{bcb:?} already has a counter: {counter_kind:?}");
-            return counter_kind.as_term();
+            return counter_kind;
         }
 
         // A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`).
         // Also, a BCB that loops back to itself gets a simple `Counter`. This may indicate the
         // program results in a tight infinite loop, but it should still compile.
-        let one_path_to_target = self.bcb_has_one_path_to_target(bcb);
+        let one_path_to_target = !self.basic_coverage_blocks.bcb_has_multiple_in_edges(bcb);
         if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) {
             let counter_kind = self.coverage_counters.make_counter();
             if one_path_to_target {
@@ -355,40 +349,25 @@ impl<'a> MakeBcbCounters<'a> {
             return self.coverage_counters.set_bcb_counter(bcb, counter_kind);
         }
 
-        // A BCB with multiple incoming edges can compute its count by `Expression`, summing up the
-        // counters and/or expressions of its incoming edges. This will recursively get or create
-        // counters for those incoming edges first, then call `make_expression()` to sum them up,
-        // with additional intermediate expressions as needed.
-        let _sumup_debug_span = debug_span!("(preparing sum-up expression)").entered();
-
-        let mut predecessors = self.bcb_predecessors(bcb).to_owned().into_iter();
-        let first_edge_counter_operand =
-            self.get_or_make_edge_counter_operand(predecessors.next().unwrap(), bcb);
-        let mut some_sumup_edge_counter_operand = None;
-        for predecessor in predecessors {
-            let edge_counter_operand = self.get_or_make_edge_counter_operand(predecessor, bcb);
-            if let Some(sumup_edge_counter_operand) =
-                some_sumup_edge_counter_operand.replace(edge_counter_operand)
-            {
-                let intermediate_expression = self.coverage_counters.make_expression(
-                    sumup_edge_counter_operand,
-                    Op::Add,
-                    edge_counter_operand,
-                );
-                debug!("new intermediate expression: {intermediate_expression:?}");
-                let intermediate_expression_operand = intermediate_expression.as_term();
-                some_sumup_edge_counter_operand.replace(intermediate_expression_operand);
-            }
-        }
-        let counter_kind = self.coverage_counters.make_expression(
-            first_edge_counter_operand,
-            Op::Add,
-            some_sumup_edge_counter_operand.unwrap(),
-        );
-        drop(_sumup_debug_span);
-
-        debug!("{bcb:?} gets a new counter (sum of predecessor counters): {counter_kind:?}");
-        self.coverage_counters.set_bcb_counter(bcb, counter_kind)
+        // A BCB with multiple incoming edges can compute its count by ensuring that counters
+        // exist for each of those edges, and then adding them up to get a total count.
+        let sum_of_in_edges: BcbCounter = {
+            let _span = debug_span!("sum_of_in_edges", ?bcb).entered();
+            // We avoid calling `self.bcb_predecessors` here so that we can
+            // call methods on `&mut self` inside the fold.
+            self.basic_coverage_blocks.predecessors[bcb]
+                .iter()
+                .copied()
+                .fold(None, |accum, from_bcb| {
+                    let _span = debug_span!("from_bcb", ?accum, ?from_bcb).entered();
+                    let edge_counter = self.get_or_make_edge_counter_operand(from_bcb, bcb);
+                    Some(self.coverage_counters.make_sum_expression(accum, edge_counter))
+                })
+                .expect("there must be at least one in-edge")
+        };
+
+        debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}");
+        self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges)
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -396,20 +375,26 @@ impl<'a> MakeBcbCounters<'a> {
         &mut self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
-    ) -> CovTerm {
+    ) -> BcbCounter {
+        // If the target BCB has only one in-edge (i.e. this one), then create
+        // a node counter instead, since it will have the same value.
+        if !self.basic_coverage_blocks.bcb_has_multiple_in_edges(to_bcb) {
+            assert_eq!([from_bcb].as_slice(), self.basic_coverage_blocks.predecessors[to_bcb]);
+            return self.get_or_make_counter_operand(to_bcb);
+        }
+
         // If the source BCB has only one successor (assumed to be the given target), an edge
         // counter is unnecessary. Just get or make a counter for the source BCB.
-        let successors = self.bcb_successors(from_bcb).iter();
-        if successors.len() == 1 {
+        if self.bcb_successors(from_bcb).len() == 1 {
             return self.get_or_make_counter_operand(from_bcb);
         }
 
         // If the edge already has a counter, return it.
-        if let Some(counter_kind) =
+        if let Some(&counter_kind) =
             self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
         {
             debug!("Edge {from_bcb:?}->{to_bcb:?} already has a counter: {counter_kind:?}");
-            return counter_kind.as_term();
+            return counter_kind;
         }
 
         // Make a new counter to count this edge.
@@ -423,16 +408,19 @@ impl<'a> MakeBcbCounters<'a> {
     fn choose_preferred_expression_branch(
         &self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
-        branches: &[BcbBranch],
-    ) -> BcbBranch {
-        let good_reloop_branch = self.find_good_reloop_branch(traversal, branches);
-        if let Some(reloop_branch) = good_reloop_branch {
-            assert!(self.branch_has_no_counter(&reloop_branch));
-            debug!("Selecting reloop branch {reloop_branch:?} to get an expression");
-            reloop_branch
+        from_bcb: BasicCoverageBlock,
+    ) -> BasicCoverageBlock {
+        let good_reloop_branch = self.find_good_reloop_branch(traversal, from_bcb);
+        if let Some(reloop_target) = good_reloop_branch {
+            assert!(self.branch_has_no_counter(from_bcb, reloop_target));
+            debug!("Selecting reloop target {reloop_target:?} to get an expression");
+            reloop_target
         } else {
-            let &branch_without_counter =
-                branches.iter().find(|&branch| self.branch_has_no_counter(branch)).expect(
+            let &branch_without_counter = self
+                .bcb_successors(from_bcb)
+                .iter()
+                .find(|&&to_bcb| self.branch_has_no_counter(from_bcb, to_bcb))
+                .expect(
                     "needs_branch_counters was `true` so there should be at least one \
                     branch",
                 );
@@ -453,26 +441,28 @@ impl<'a> MakeBcbCounters<'a> {
     fn find_good_reloop_branch(
         &self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
-        branches: &[BcbBranch],
-    ) -> Option<BcbBranch> {
+        from_bcb: BasicCoverageBlock,
+    ) -> Option<BasicCoverageBlock> {
+        let branch_target_bcbs = self.bcb_successors(from_bcb);
+
         // Consider each loop on the current traversal context stack, top-down.
         for reloop_bcbs in traversal.reloop_bcbs_per_loop() {
             let mut all_branches_exit_this_loop = true;
 
             // Try to find a branch that doesn't exit this loop and doesn't
             // already have a counter.
-            for &branch in branches {
+            for &branch_target_bcb in branch_target_bcbs {
                 // A branch is a reloop branch if it dominates any BCB that has
                 // an edge back to the loop header. (Other branches are exits.)
                 let is_reloop_branch = reloop_bcbs.iter().any(|&reloop_bcb| {
-                    self.basic_coverage_blocks.dominates(branch.target_bcb, reloop_bcb)
+                    self.basic_coverage_blocks.dominates(branch_target_bcb, reloop_bcb)
                 });
 
                 if is_reloop_branch {
                     all_branches_exit_this_loop = false;
-                    if self.branch_has_no_counter(&branch) {
+                    if self.branch_has_no_counter(from_bcb, branch_target_bcb) {
                         // We found a good branch to be given an expression.
-                        return Some(branch);
+                        return Some(branch_target_bcb);
                     }
                     // Keep looking for another reloop branch without a counter.
                 } else {
@@ -505,36 +495,23 @@ impl<'a> MakeBcbCounters<'a> {
     }
 
     #[inline]
-    fn bcb_branches(&self, from_bcb: BasicCoverageBlock) -> Vec<BcbBranch> {
-        self.bcb_successors(from_bcb)
-            .iter()
-            .map(|&to_bcb| BcbBranch::from_to(from_bcb, to_bcb, self.basic_coverage_blocks))
-            .collect::<Vec<_>>()
-    }
-
-    fn bcb_needs_branch_counters(&self, bcb: BasicCoverageBlock) -> bool {
-        let branch_needs_a_counter = |branch: &BcbBranch| self.branch_has_no_counter(branch);
-        let branches = self.bcb_branches(bcb);
-        branches.len() > 1 && branches.iter().any(branch_needs_a_counter)
-    }
-
-    fn branch_has_no_counter(&self, branch: &BcbBranch) -> bool {
-        self.branch_counter(branch).is_none()
+    fn branch_has_no_counter(
+        &self,
+        from_bcb: BasicCoverageBlock,
+        to_bcb: BasicCoverageBlock,
+    ) -> bool {
+        self.branch_counter(from_bcb, to_bcb).is_none()
     }
 
-    fn branch_counter(&self, branch: &BcbBranch) -> Option<&BcbCounter> {
-        let to_bcb = branch.target_bcb;
-        if let Some(from_bcb) = branch.edge_from_bcb {
+    fn branch_counter(
+        &self,
+        from_bcb: BasicCoverageBlock,
+        to_bcb: BasicCoverageBlock,
+    ) -> Option<&BcbCounter> {
+        if self.basic_coverage_blocks.bcb_has_multiple_in_edges(to_bcb) {
             self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
         } else {
             self.coverage_counters.bcb_counters[to_bcb].as_ref()
         }
     }
-
-    /// Returns true if the BasicCoverageBlock has zero or one incoming edge. (If zero, it should be
-    /// the entry point for the function.)
-    #[inline]
-    fn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool {
-        self.bcb_predecessors(bcb).len() <= 1
-    }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 0d807db404c..263bfdaaaba 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -62,6 +62,14 @@ impl CoverageGraph {
             Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None };
         let dominators = dominators::dominators(&basic_coverage_blocks);
         basic_coverage_blocks.dominators = Some(dominators);
+
+        // The coverage graph's entry-point node (bcb0) always starts with bb0,
+        // which never has predecessors. Any other blocks merged into bcb0 can't
+        // have multiple (coverage-relevant) predecessors, so bcb0 always has
+        // zero in-edges.
+        assert!(basic_coverage_blocks[START_BCB].leader_bb() == mir::START_BLOCK);
+        assert!(basic_coverage_blocks.predecessors[START_BCB].is_empty());
+
         basic_coverage_blocks
     }
 
@@ -199,6 +207,25 @@ impl CoverageGraph {
     pub fn cmp_in_dominator_order(&self, a: BasicCoverageBlock, b: BasicCoverageBlock) -> Ordering {
         self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
     }
+
+    /// Returns true if the given node has 2 or more in-edges, i.e. 2 or more
+    /// predecessors.
+    ///
+    /// This property is interesting to code that assigns counters to nodes and
+    /// edges, because if a node _doesn't_ have multiple in-edges, then there's
+    /// no benefit in having a separate counter for its in-edge, because it
+    /// would have the same value as the node's own counter.
+    ///
+    /// FIXME: That assumption might not be true for [`TerminatorKind::Yield`]?
+    #[inline(always)]
+    pub(super) fn bcb_has_multiple_in_edges(&self, bcb: BasicCoverageBlock) -> bool {
+        // Even though bcb0 conceptually has an extra virtual in-edge due to
+        // being the entry point, we've already asserted that it has no _other_
+        // in-edges, so there's no possibility of it having _multiple_ in-edges.
+        // (And since its virtual in-edge doesn't exist in the graph, that edge
+        // can't have a separate counter anyway.)
+        self.predecessors[bcb].len() > 1
+    }
 }
 
 impl Index<BasicCoverageBlock> for CoverageGraph {
@@ -319,45 +346,6 @@ impl BasicCoverageBlockData {
     }
 }
 
-/// Represents a successor from a branching BasicCoverageBlock (such as the arms of a `SwitchInt`)
-/// as either the successor BCB itself, if it has only one incoming edge, or the successor _plus_
-/// the specific branching BCB, representing the edge between the two. The latter case
-/// distinguishes this incoming edge from other incoming edges to the same `target_bcb`.
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub(super) struct BcbBranch {
-    pub edge_from_bcb: Option<BasicCoverageBlock>,
-    pub target_bcb: BasicCoverageBlock,
-}
-
-impl BcbBranch {
-    pub fn from_to(
-        from_bcb: BasicCoverageBlock,
-        to_bcb: BasicCoverageBlock,
-        basic_coverage_blocks: &CoverageGraph,
-    ) -> Self {
-        let edge_from_bcb = if basic_coverage_blocks.predecessors[to_bcb].len() > 1 {
-            Some(from_bcb)
-        } else {
-            None
-        };
-        Self { edge_from_bcb, target_bcb: to_bcb }
-    }
-
-    pub fn is_only_path_to_target(&self) -> bool {
-        self.edge_from_bcb.is_none()
-    }
-}
-
-impl std::fmt::Debug for BcbBranch {
-    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        if let Some(from_bcb) = self.edge_from_bcb {
-            write!(fmt, "{:?}->{:?}", from_bcb, self.target_bcb)
-        } else {
-            write!(fmt, "{:?}", self.target_bcb)
-        }
-    }
-}
-
 // Returns the subset of a block's successors that are relevant to the coverage
 // graph, i.e. those that do not represent unwinds or unreachable branches.
 // FIXME(#78544): MIR InstrumentCoverage: Improve coverage of `#[should_panic]` tests and
diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map
index 598791537ad..857e0a536a7 100644
--- a/tests/coverage/async.cov-map
+++ b/tests/coverage/async.cov-map
@@ -197,12 +197,12 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 38, 1) to (start + 0, 19)
 
 Function name: async::i::{closure#0}
-Raw bytes (78): 0x[01, 01, 02, 19, 07, 1d, 21, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
-- expression 0 operands: lhs = Counter(6), rhs = Expression(1, Add)
-- expression 1 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(8)
+- expression 1 operands: lhs = Counter(6), rhs = Counter(7)
 Number of file 0 mappings: 14
 - Code(Counter(0)) at (prev + 38, 19) to (start + 4, 12)
 - Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10)
@@ -218,15 +218,15 @@ Number of file 0 mappings: 14
 - Code(Counter(7)) at (prev + 0, 36) to (start + 0, 38)
 - Code(Counter(8)) at (prev + 1, 14) to (start + 0, 16)
 - Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = (c6 + (c7 + c8))
+    = ((c6 + c7) + c8)
 
 Function name: async::j
-Raw bytes (53): 0x[01, 01, 02, 05, 07, 09, 0d, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
-- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 49, 1) to (start + 19, 12)
 - Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10)
@@ -237,7 +237,7 @@ Number of file 0 mappings: 9
 - Code(Counter(2)) at (prev + 0, 30) to (start + 0, 32)
 - Code(Counter(3)) at (prev + 1, 14) to (start + 0, 16)
 - Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = (c1 + (c2 + c3))
+    = ((c1 + c2) + c3)
 
 Function name: async::j::c
 Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 33, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06]
@@ -283,22 +283,22 @@ Number of file 0 mappings: 5
 - Code(Zero) at (prev + 2, 1) to (start + 0, 2)
 
 Function name: async::l
-Raw bytes (37): 0x[01, 01, 04, 01, 07, 09, 05, 09, 0f, 05, 02, 05, 01, 53, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
+Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 53, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(2), rhs = Expression(3, Add)
-- expression 3 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 2 operands: lhs = Expression(3, Add), rhs = Expression(0, Sub)
+- expression 3 operands: lhs = Counter(2), rhs = Counter(1)
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 83, 1) to (start + 1, 12)
 - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16)
-    = (c0 - (c2 + c1))
+    = (c0 - (c1 + c2))
 - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16)
 - Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16)
 - Code(Expression(2, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = (c2 + (c1 + (c0 - (c2 + c1))))
+    = ((c2 + c1) + (c0 - (c1 + c2)))
 
 Function name: async::m
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 00, 19]
diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map
index 7600d2d96bd..cfee55ed31a 100644
--- a/tests/coverage/conditions.cov-map
+++ b/tests/coverage/conditions.cov-map
@@ -1,5 +1,5 @@
 Function name: conditions::main
-Raw bytes (784): 0x[01, 01, 8e, 01, 09, 33, 37, 41, 3b, 3d, 35, 39, 05, 00, b7, 04, 09, 05, 00, 0d, 35, 26, 39, 0d, 35, 3b, 3d, 35, 39, 37, 41, 3b, 3d, 35, 39, b2, 04, 0d, b7, 04, 09, 05, 00, 45, 00, 83, 01, 49, 45, 00, 7e, 31, 83, 01, 49, 45, 00, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, 76, 51, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, a7, 01, 55, 4d, 51, a3, 01, 59, a7, 01, 55, 4d, 51, 49, 9f, 01, a3, 01, 59, a7, 01, 55, 4d, 51, 61, 00, e3, 01, 65, 61, 00, de, 01, 2d, e3, 01, 65, 61, 00, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, d6, 01, 6d, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, 8b, 02, 71, 69, 6d, 87, 02, 75, 8b, 02, 71, 69, 6d, ff, 01, 00, 65, 83, 02, 87, 02, 75, 8b, 02, 71, 69, 6d, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 79, 00, d7, 02, 7d, 79, 00, d2, 02, 29, d7, 02, 7d, 79, 00, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, ca, 02, 85, 01, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, f3, 03, 89, 01, 81, 01, 85, 01, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, da, 03, 19, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 9b, 04, 1d, 15, 19, 97, 04, 21, 9b, 04, 1d, 15, 19, 8f, 04, 9f, 04, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, a3, 04, ae, 04, a7, 04, ab, 04, 25, 29, 2d, 31, b2, 04, 0d, b7, 04, 09, 05, 00, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, b7, 04, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, b2, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 26, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 37, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 33, 01, 09, 01, 12, ae, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 83, 01, 02, 08, 00, 15, 49, 00, 16, 02, 06, 7e, 02, 0f, 00, 1c, 7a, 01, 0c, 00, 19, 76, 00, 1d, 00, 2a, 72, 00, 2e, 00, 3c, a3, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, 9f, 01, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 9b, 01, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, e3, 01, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, de, 01, 03, 11, 00, 1e, da, 01, 01, 10, 00, 1d, d6, 01, 00, 21, 00, 2e, d2, 01, 00, 32, 00, 40, 87, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, 83, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, fb, 01, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, e7, 03, 02, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, d2, 02, 02, 0f, 00, 1c, ce, 02, 01, 0c, 00, 19, ca, 02, 00, 1d, 00, 2a, c6, 02, 00, 2e, 00, 3c, ef, 03, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, eb, 03, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, 8f, 04, 05, 09, 00, 0a, e7, 03, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, e2, 03, 02, 0f, 00, 1c, de, 03, 01, 0c, 00, 19, da, 03, 00, 1d, 00, 2a, d6, 03, 00, 2e, 00, 3c, 97, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, 93, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, 8b, 04, 02, 01, 00, 02]
+Raw bytes (784): 0x[01, 01, 8e, 01, 09, 33, 37, 41, 3b, 3d, 35, 39, 05, 00, b7, 04, 09, 05, 00, 0d, 35, 26, 39, 0d, 35, 3b, 3d, 35, 39, 37, 41, 3b, 3d, 35, 39, b2, 04, 0d, b7, 04, 09, 05, 00, 45, 00, 83, 01, 49, 45, 00, 7e, 31, 83, 01, 49, 45, 00, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, 76, 51, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, a7, 01, 55, 4d, 51, a3, 01, 59, a7, 01, 55, 4d, 51, 49, 9f, 01, a3, 01, 59, a7, 01, 55, 4d, 51, 61, 00, e3, 01, 65, 61, 00, de, 01, 2d, e3, 01, 65, 61, 00, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, d6, 01, 6d, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, 8b, 02, 71, 69, 6d, 87, 02, 75, 8b, 02, 71, 69, 6d, ff, 01, 00, 65, 83, 02, 87, 02, 75, 8b, 02, 71, 69, 6d, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 79, 00, d7, 02, 7d, 79, 00, d2, 02, 29, d7, 02, 7d, 79, 00, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, ca, 02, 85, 01, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, f3, 03, 89, 01, 81, 01, 85, 01, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, da, 03, 19, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 9b, 04, 1d, 15, 19, 97, 04, 21, 9b, 04, 1d, 15, 19, 8f, 04, 9f, 04, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, a3, 04, ae, 04, a7, 04, 31, ab, 04, 2d, 25, 29, b2, 04, 0d, b7, 04, 09, 05, 00, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, b7, 04, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, b2, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 26, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 37, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 33, 01, 09, 01, 12, ae, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 83, 01, 02, 08, 00, 15, 49, 00, 16, 02, 06, 7e, 02, 0f, 00, 1c, 7a, 01, 0c, 00, 19, 76, 00, 1d, 00, 2a, 72, 00, 2e, 00, 3c, a3, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, 9f, 01, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 9b, 01, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, e3, 01, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, de, 01, 03, 11, 00, 1e, da, 01, 01, 10, 00, 1d, d6, 01, 00, 21, 00, 2e, d2, 01, 00, 32, 00, 40, 87, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, 83, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, fb, 01, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, e7, 03, 02, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, d2, 02, 02, 0f, 00, 1c, ce, 02, 01, 0c, 00, 19, ca, 02, 00, 1d, 00, 2a, c6, 02, 00, 2e, 00, 3c, ef, 03, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, eb, 03, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, 8f, 04, 05, 09, 00, 0a, e7, 03, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, e2, 03, 02, 0f, 00, 1c, de, 03, 01, 0c, 00, 19, da, 03, 00, 1d, 00, 2a, d6, 03, 00, 2e, 00, 3c, 97, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, 93, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, 8b, 04, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 142
@@ -139,9 +139,9 @@ Number of expressions: 142
 - expression 133 operands: lhs = Expression(134, Add), rhs = Counter(7)
 - expression 134 operands: lhs = Counter(5), rhs = Counter(6)
 - expression 135 operands: lhs = Expression(136, Add), rhs = Expression(139, Sub)
-- expression 136 operands: lhs = Expression(137, Add), rhs = Expression(138, Add)
-- expression 137 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 138 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 136 operands: lhs = Expression(137, Add), rhs = Counter(12)
+- expression 137 operands: lhs = Expression(138, Add), rhs = Counter(11)
+- expression 138 operands: lhs = Counter(9), rhs = Counter(10)
 - expression 139 operands: lhs = Expression(140, Sub), rhs = Counter(3)
 - expression 140 operands: lhs = Expression(141, Add), rhs = Counter(2)
 - expression 141 operands: lhs = Counter(1), rhs = Zero
@@ -255,5 +255,5 @@ Number of file 0 mappings: 68
     = (((c5 + c6) + c7) + c8)
 - Code(Counter(9)) at (prev + 2, 9) to (start + 0, 15)
 - Code(Expression(130, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = ((c4 + (((c5 + c6) + c7) + c8)) + (((c9 + c10) + (c11 + c12)) + (((c1 + Zero) - c2) - c3)))
+    = ((c4 + (((c5 + c6) + c7) + c8)) + ((((c9 + c10) + c11) + c12) + (((c1 + Zero) - c2) - c3)))
 
diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map
index 82f3d7c6095..810694d7f66 100644
--- a/tests/coverage/continue.cov-map
+++ b/tests/coverage/continue.cov-map
@@ -1,26 +1,26 @@
 Function name: continue::main
-Raw bytes (210): 0x[01, 01, 1c, 01, 07, 05, 09, 03, 0d, 0d, 1f, 11, 15, 1b, 19, 0d, 1f, 11, 15, 19, 33, 1d, 21, 2f, 25, 19, 33, 1d, 21, 25, 47, 29, 2d, 43, 31, 25, 47, 29, 2d, 31, 5f, 35, 39, 57, 3d, 31, 5f, 35, 39, 35, 39, 3d, 41, 6b, 45, 3d, 41, 49, 45, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 15, 03, 09, 00, 0e, 2f, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 1d, 03, 09, 00, 0e, 43, 02, 0e, 00, 13, 3e, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 57, 03, 0e, 00, 13, 52, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 5f, 04, 09, 00, 0e, 6b, 02, 0e, 00, 13, 66, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 6f, 02, 0d, 01, 02]
+Raw bytes (210): 0x[01, 01, 1c, 07, 09, 01, 05, 03, 0d, 1f, 15, 0d, 11, 1b, 19, 1f, 15, 0d, 11, 33, 21, 19, 1d, 2f, 25, 33, 21, 19, 1d, 47, 2d, 25, 29, 43, 31, 47, 2d, 25, 29, 31, 5f, 35, 39, 57, 3d, 31, 5f, 35, 39, 35, 39, 3d, 41, 6b, 45, 3d, 41, 49, 45, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 15, 03, 09, 00, 0e, 2f, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 1d, 03, 09, 00, 0e, 43, 02, 0e, 00, 13, 3e, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 57, 03, 0e, 00, 13, 52, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 5f, 04, 09, 00, 0e, 6b, 02, 0e, 00, 13, 66, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 6f, 02, 0d, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 28
-- expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(3), rhs = Expression(7, Add)
-- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 3 operands: lhs = Expression(7, Add), rhs = Counter(5)
+- expression 4 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 5 operands: lhs = Expression(6, Add), rhs = Counter(6)
-- expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add)
-- expression 7 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 8 operands: lhs = Counter(6), rhs = Expression(12, Add)
-- expression 9 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(5)
+- expression 7 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 8 operands: lhs = Expression(12, Add), rhs = Counter(8)
+- expression 9 operands: lhs = Counter(6), rhs = Counter(7)
 - expression 10 operands: lhs = Expression(11, Add), rhs = Counter(9)
-- expression 11 operands: lhs = Counter(6), rhs = Expression(12, Add)
-- expression 12 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 13 operands: lhs = Counter(9), rhs = Expression(17, Add)
-- expression 14 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(8)
+- expression 12 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 13 operands: lhs = Expression(17, Add), rhs = Counter(11)
+- expression 14 operands: lhs = Counter(9), rhs = Counter(10)
 - expression 15 operands: lhs = Expression(16, Add), rhs = Counter(12)
-- expression 16 operands: lhs = Counter(9), rhs = Expression(17, Add)
-- expression 17 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(11)
+- expression 17 operands: lhs = Counter(9), rhs = Counter(10)
 - expression 18 operands: lhs = Counter(12), rhs = Expression(23, Add)
 - expression 19 operands: lhs = Counter(13), rhs = Counter(14)
 - expression 20 operands: lhs = Expression(21, Add), rhs = Counter(15)
@@ -34,29 +34,29 @@ Number of expressions: 28
 Number of file 0 mappings: 30
 - Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18)
 - Code(Expression(0, Add)) at (prev + 4, 14) to (start + 0, 19)
-    = (c0 + (c1 + c2))
+    = ((c0 + c1) + c2)
 - Code(Expression(2, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = ((c0 + (c1 + c2)) - c3)
+    = (((c0 + c1) + c2) - c3)
 - Code(Counter(1)) at (prev + 2, 17) to (start + 0, 25)
 - Code(Counter(2)) at (prev + 2, 18) to (start + 4, 14)
 - Code(Expression(6, Add)) at (prev + 6, 14) to (start + 0, 19)
-    = (c3 + (c4 + c5))
+    = ((c3 + c4) + c5)
 - Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = ((c3 + (c4 + c5)) - c6)
+    = (((c3 + c4) + c5) - c6)
 - Code(Counter(5)) at (prev + 1, 22) to (start + 2, 14)
 - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25)
 - Code(Counter(5)) at (prev + 3, 9) to (start + 0, 14)
 - Code(Expression(11, Add)) at (prev + 2, 14) to (start + 0, 19)
-    = (c6 + (c7 + c8))
+    = ((c6 + c7) + c8)
 - Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = ((c6 + (c7 + c8)) - c9)
+    = (((c6 + c7) + c8) - c9)
 - Code(Counter(7)) at (prev + 1, 21) to (start + 2, 14)
 - Code(Counter(8)) at (prev + 4, 17) to (start + 0, 25)
 - Code(Counter(7)) at (prev + 3, 9) to (start + 0, 14)
 - Code(Expression(16, Add)) at (prev + 2, 14) to (start + 0, 19)
-    = (c9 + (c10 + c11))
+    = ((c9 + c10) + c11)
 - Code(Expression(15, Sub)) at (prev + 1, 12) to (start + 0, 19)
-    = ((c9 + (c10 + c11)) - c12)
+    = (((c9 + c10) + c11) - c12)
 - Code(Counter(10)) at (prev + 1, 13) to (start + 0, 21)
 - Code(Counter(11)) at (prev + 1, 10) to (start + 1, 14)
 - Code(Expression(21, Add)) at (prev + 3, 14) to (start + 0, 19)
diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map
index 2f4936d9ab8..8dd03acc2f4 100644
--- a/tests/coverage/coroutine.cov-map
+++ b/tests/coverage/coroutine.cov-map
@@ -14,12 +14,12 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: coroutine::main
-Raw bytes (65): 0x[01, 01, 08, 05, 07, 09, 0d, 11, 15, 1e, 19, 11, 15, 15, 19, 1e, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 01, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 1e, 01, 22, 00, 27, 1a, 00, 2c, 00, 2e, 17, 01, 0e, 00, 35, 1a, 02, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 08, 07, 0d, 05, 09, 11, 15, 1e, 19, 11, 15, 15, 19, 1e, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 01, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 1e, 01, 22, 00, 27, 1a, 00, 2c, 00, 2e, 17, 01, 0e, 00, 35, 1a, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
-- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(4), rhs = Counter(5)
 - expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(6)
 - expression 4 operands: lhs = Counter(4), rhs = Counter(5)
@@ -31,7 +31,7 @@ Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46)
 - Code(Counter(4)) at (prev + 1, 43) to (start + 0, 45)
 - Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 53)
-    = (c1 + (c2 + c3))
+    = ((c1 + c2) + c3)
 - Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
 - Code(Expression(7, Sub)) at (prev + 1, 34) to (start + 0, 39)
     = (c4 - c5)
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index 813583a9de7..8dc35321133 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,5 +1,5 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (249): 0x[01, 01, 31, 05, 00, 00, 02, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, bf, 01, c3, 01, 0d, 00, 11, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, 00, ae, 01, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, ab, 01, 11, 00, ae, 01, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, 25, a3, 01, a6, 01, 19, ab, 01, 11, 00, ae, 01, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, b6, 01, 03, 0d, 00, 0e, bb, 01, 00, 12, 00, 17, b6, 01, 01, 10, 00, 14, b2, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, ae, 01, 01, 12, 00, 13, ab, 01, 01, 11, 00, 22, a6, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 9f, 01, 01, 05, 00, 06]
+Raw bytes (249): 0x[01, 01, 31, 05, 00, 00, 02, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, bf, 01, c3, 01, 0d, 00, 11, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, 00, ae, 01, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, ab, 01, 11, 00, ae, 01, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, a3, 01, 19, 25, a6, 01, ab, 01, 11, 00, ae, 01, b2, 01, 00, b6, 01, 00, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 00, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, b6, 01, 03, 0d, 00, 0e, bb, 01, 00, 12, 00, 17, b6, 01, 01, 10, 00, 14, b2, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, ae, 01, 01, 12, 00, 13, ab, 01, 01, 11, 00, 22, a6, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 9f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 49
@@ -42,8 +42,8 @@ Number of expressions: 49
 - expression 36 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
 - expression 37 operands: lhs = Counter(3), rhs = Zero
 - expression 38 operands: lhs = Counter(4), rhs = Zero
-- expression 39 operands: lhs = Counter(9), rhs = Expression(40, Add)
-- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(6)
+- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(6)
+- expression 40 operands: lhs = Counter(9), rhs = Expression(41, Sub)
 - expression 41 operands: lhs = Expression(42, Add), rhs = Counter(4)
 - expression 42 operands: lhs = Zero, rhs = Expression(43, Sub)
 - expression 43 operands: lhs = Expression(44, Sub), rhs = Zero
@@ -82,10 +82,10 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 20) to (start + 1, 14)
 - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
 - Code(Expression(39, Add)) at (prev + 1, 5) to (start + 0, 6)
-    = (c9 + (((Zero + (((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) - Zero)) - c4) + c6))
+    = ((c9 + ((Zero + (((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) - Zero)) - c4)) + c6)
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (253): 0x[01, 01, 33, 01, 00, 02, 00, 00, 0e, 02, 00, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, c3, 01, c7, 01, 00, 0d, 00, 15, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, b6, 01, 00, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, 00, b2, 01, b6, 01, 00, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, af, 01, 15, 00, b2, 01, b6, 01, 00, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, aa, 01, cb, 01, af, 01, 15, 00, b2, 01, b6, 01, 00, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 00, 0d, 00, 15, 19, 25, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, ba, 01, 02, 0d, 00, 0e, bf, 01, 00, 12, 00, 17, ba, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, b6, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b2, 01, 01, 12, 00, 13, af, 01, 01, 11, 00, 22, aa, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, a7, 01, 01, 05, 00, 06]
+Raw bytes (253): 0x[01, 01, 33, 01, 00, 02, 00, 00, 0e, 02, 00, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, c7, 01, cb, 01, 00, 0d, 00, 15, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, ba, 01, 00, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, 00, b6, 01, ba, 01, 00, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, b3, 01, 15, 00, b6, 01, ba, 01, 00, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, ab, 01, 25, ae, 01, 19, b3, 01, 15, 00, b6, 01, ba, 01, 00, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 00, 0d, 00, 15, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, be, 01, 02, 0d, 00, 0e, c3, 01, 00, 12, 00, 17, be, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, ba, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b6, 01, 01, 12, 00, 13, b3, 01, 01, 11, 00, 22, ae, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, a7, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 51
@@ -93,53 +93,53 @@ Number of expressions: 51
 - expression 1 operands: lhs = Expression(0, Sub), rhs = Zero
 - expression 2 operands: lhs = Zero, rhs = Expression(3, Sub)
 - expression 3 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 4 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 5 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 4 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 5 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 6 operands: lhs = Zero, rhs = Counter(3)
 - expression 7 operands: lhs = Zero, rhs = Counter(5)
-- expression 8 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 8 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 9 operands: lhs = Zero, rhs = Counter(3)
 - expression 10 operands: lhs = Zero, rhs = Counter(5)
-- expression 11 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 12 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 11 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 12 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 13 operands: lhs = Zero, rhs = Counter(3)
 - expression 14 operands: lhs = Zero, rhs = Counter(5)
-- expression 15 operands: lhs = Expression(46, Sub), rhs = Zero
-- expression 16 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 17 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 15 operands: lhs = Expression(47, Sub), rhs = Zero
+- expression 16 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 17 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 18 operands: lhs = Zero, rhs = Counter(3)
 - expression 19 operands: lhs = Zero, rhs = Counter(5)
-- expression 20 operands: lhs = Expression(45, Sub), rhs = Zero
-- expression 21 operands: lhs = Expression(46, Sub), rhs = Zero
-- expression 22 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 23 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 20 operands: lhs = Expression(46, Sub), rhs = Zero
+- expression 21 operands: lhs = Expression(47, Sub), rhs = Zero
+- expression 22 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 23 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 24 operands: lhs = Zero, rhs = Counter(3)
 - expression 25 operands: lhs = Zero, rhs = Counter(5)
-- expression 26 operands: lhs = Zero, rhs = Expression(44, Sub)
-- expression 27 operands: lhs = Expression(45, Sub), rhs = Zero
-- expression 28 operands: lhs = Expression(46, Sub), rhs = Zero
-- expression 29 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 30 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 26 operands: lhs = Zero, rhs = Expression(45, Sub)
+- expression 27 operands: lhs = Expression(46, Sub), rhs = Zero
+- expression 28 operands: lhs = Expression(47, Sub), rhs = Zero
+- expression 29 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 30 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 31 operands: lhs = Zero, rhs = Counter(3)
 - expression 32 operands: lhs = Zero, rhs = Counter(5)
-- expression 33 operands: lhs = Expression(43, Add), rhs = Counter(5)
-- expression 34 operands: lhs = Zero, rhs = Expression(44, Sub)
-- expression 35 operands: lhs = Expression(45, Sub), rhs = Zero
-- expression 36 operands: lhs = Expression(46, Sub), rhs = Zero
-- expression 37 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 38 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 33 operands: lhs = Expression(44, Add), rhs = Counter(5)
+- expression 34 operands: lhs = Zero, rhs = Expression(45, Sub)
+- expression 35 operands: lhs = Expression(46, Sub), rhs = Zero
+- expression 36 operands: lhs = Expression(47, Sub), rhs = Zero
+- expression 37 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 38 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
 - expression 39 operands: lhs = Zero, rhs = Counter(3)
 - expression 40 operands: lhs = Zero, rhs = Counter(5)
-- expression 41 operands: lhs = Expression(42, Sub), rhs = Expression(50, Add)
-- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(5)
-- expression 43 operands: lhs = Zero, rhs = Expression(44, Sub)
-- expression 44 operands: lhs = Expression(45, Sub), rhs = Zero
+- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(9)
+- expression 42 operands: lhs = Expression(43, Sub), rhs = Counter(6)
+- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(5)
+- expression 44 operands: lhs = Zero, rhs = Expression(45, Sub)
 - expression 45 operands: lhs = Expression(46, Sub), rhs = Zero
-- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 48 operands: lhs = Zero, rhs = Counter(3)
-- expression 49 operands: lhs = Zero, rhs = Counter(5)
-- expression 50 operands: lhs = Counter(6), rhs = Counter(9)
+- expression 46 operands: lhs = Expression(47, Sub), rhs = Zero
+- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(6)
+- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
+- expression 49 operands: lhs = Zero, rhs = Counter(3)
+- expression 50 operands: lhs = Zero, rhs = Counter(5)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17)
 - Code(Zero) at (prev + 1, 18) to (start + 1, 10)
@@ -152,26 +152,26 @@ Number of file 0 mappings: 20
 - Code(Expression(2, Add)) at (prev + 1, 13) to (start + 0, 30)
     = (Zero + ((c0 - Zero) - Zero))
 - Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Expression(46, Sub)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Expression(47, Sub)) at (prev + 2, 13) to (start + 0, 14)
     = (((Zero + c3) + (Zero + c5)) - c6)
-- Code(Expression(47, Add)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Expression(48, Add)) at (prev + 0, 18) to (start + 0, 23)
     = ((Zero + c3) + (Zero + c5))
-- Code(Expression(46, Sub)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Expression(47, Sub)) at (prev + 1, 16) to (start + 0, 21)
     = (((Zero + c3) + (Zero + c5)) - c6)
 - Code(Zero) at (prev + 0, 22) to (start + 1, 14)
-- Code(Expression(45, Sub)) at (prev + 2, 20) to (start + 0, 25)
+- Code(Expression(46, Sub)) at (prev + 2, 20) to (start + 0, 25)
     = ((((Zero + c3) + (Zero + c5)) - c6) - Zero)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 19)
+- Code(Expression(45, Sub)) at (prev + 1, 18) to (start + 0, 19)
     = (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero)
-- Code(Expression(43, Add)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Expression(44, Add)) at (prev + 1, 17) to (start + 0, 34)
     = (Zero + (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero))
-- Code(Expression(42, Sub)) at (prev + 0, 34) to (start + 0, 35)
+- Code(Expression(43, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((Zero + (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero)) - c5)
 - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
 - Code(Expression(41, Add)) at (prev + 1, 5) to (start + 0, 6)
-    = (((Zero + (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero)) - c5) + (c6 + c9))
+    = ((((Zero + (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero)) - c5) + c6) + c9)
 
 Function name: loops_branches::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02]
diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map
index 8367103a21a..a9a18a180dd 100644
--- a/tests/coverage/try_error_result.cov-map
+++ b/tests/coverage/try_error_result.cov-map
@@ -59,7 +59,7 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: try_error_result::test1
-Raw bytes (77): 0x[01, 01, 09, 01, 07, 05, 09, 03, 0d, 1d, 11, 16, 1d, 03, 0d, 1f, 0d, 11, 23, 15, 19, 0b, 01, 0c, 01, 02, 17, 03, 07, 09, 00, 0e, 16, 02, 09, 04, 1a, 1d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 0e, 01, 0d, 00, 2a, 15, 00, 2a, 00, 2b, 12, 04, 0d, 00, 2a, 19, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 1b, 01, 01, 00, 02]
+Raw bytes (77): 0x[01, 01, 09, 01, 07, 05, 09, 03, 0d, 1d, 11, 16, 1d, 03, 0d, 1f, 0d, 23, 19, 11, 15, 0b, 01, 0c, 01, 02, 17, 03, 07, 09, 00, 0e, 16, 02, 09, 04, 1a, 1d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 0e, 01, 0d, 00, 2a, 15, 00, 2a, 00, 2b, 12, 04, 0d, 00, 2a, 19, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 1b, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 9
@@ -70,8 +70,8 @@ Number of expressions: 9
 - expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(7)
 - expression 5 operands: lhs = Expression(0, Add), rhs = Counter(3)
 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
-- expression 7 operands: lhs = Counter(4), rhs = Expression(8, Add)
-- expression 8 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(6)
+- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 11
 - Code(Counter(0)) at (prev + 12, 1) to (start + 2, 23)
 - Code(Expression(0, Add)) at (prev + 7, 9) to (start + 0, 14)
@@ -88,10 +88,10 @@ Number of file 0 mappings: 11
 - Code(Counter(6)) at (prev + 0, 42) to (start + 0, 43)
 - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11)
 - Code(Expression(6, Add)) at (prev + 1, 1) to (start + 0, 2)
-    = ((c4 + (c5 + c6)) + c3)
+    = (((c4 + c5) + c6) + c3)
 
 Function name: try_error_result::test2
-Raw bytes (358): 0x[01, 01, 3b, 01, 07, 05, 09, 03, 0d, 41, 11, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 4a, 15, 41, 11, 46, 19, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 5e, 25, 49, 21, 49, 21, 5e, 25, 49, 21, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, 92, 01, 41, 03, 0d, 8e, 01, 29, 92, 01, 41, 03, 0d, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, a6, 01, 35, 45, 31, 45, 31, a6, 01, 35, 45, 31, ba, 01, 3d, 4d, 39, 4d, 39, ba, 01, 3d, 4d, 39, c3, 01, 0d, 11, c7, 01, cb, 01, db, 01, 15, cf, 01, d3, 01, d7, 01, 19, 1d, 21, 25, df, 01, e3, 01, 29, 2d, e7, 01, eb, 01, 31, 35, 39, 3d, 28, 01, 3c, 01, 03, 17, 03, 08, 09, 00, 0e, 92, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 4a, 00, 31, 03, 35, 15, 04, 11, 00, 12, 46, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 46, 00, 17, 00, 41, 19, 00, 41, 00, 42, 42, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 5e, 00, 43, 00, 60, 25, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 8e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 8a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, a6, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, ba, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02]
+Raw bytes (358): 0x[01, 01, 3b, 01, 07, 05, 09, 03, 0d, 41, 11, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 4a, 15, 41, 11, 46, 19, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 5e, 25, 49, 21, 49, 21, 5e, 25, 49, 21, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, 92, 01, 41, 03, 0d, 8e, 01, 29, 92, 01, 41, 03, 0d, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, a6, 01, 35, 45, 31, 45, 31, a6, 01, 35, 45, 31, ba, 01, 3d, 4d, 39, 4d, 39, ba, 01, 3d, 4d, 39, c3, 01, 0d, c7, 01, db, 01, cb, 01, cf, 01, 11, 15, d3, 01, d7, 01, 19, 1d, 21, 25, df, 01, e3, 01, 29, 2d, e7, 01, eb, 01, 31, 35, 39, 3d, 28, 01, 3c, 01, 03, 17, 03, 08, 09, 00, 0e, 92, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 4a, 00, 31, 03, 35, 15, 04, 11, 00, 12, 46, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 46, 00, 17, 00, 41, 19, 00, 41, 00, 42, 42, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 5e, 00, 43, 00, 60, 25, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 8e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 8a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, a6, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, ba, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 59
@@ -143,9 +143,9 @@ Number of expressions: 59
 - expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(15)
 - expression 46 operands: lhs = Counter(19), rhs = Counter(14)
 - expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3)
-- expression 48 operands: lhs = Counter(4), rhs = Expression(49, Add)
-- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(54, Add)
-- expression 50 operands: lhs = Counter(5), rhs = Expression(51, Add)
+- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(54, Add)
+- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(51, Add)
+- expression 50 operands: lhs = Counter(4), rhs = Counter(5)
 - expression 51 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
 - expression 52 operands: lhs = Counter(6), rhs = Counter(7)
 - expression 53 operands: lhs = Counter(8), rhs = Counter(9)
@@ -216,5 +216,5 @@ Number of file 0 mappings: 40
     = ((c19 - c14) - c15)
 - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11)
 - Code(Expression(47, Add)) at (prev + 1, 1) to (start + 0, 2)
-    = ((c4 + ((c5 + ((c6 + c7) + (c8 + c9))) + ((c10 + c11) + ((c12 + c13) + (c14 + c15))))) + c3)
+    = ((((c4 + c5) + ((c6 + c7) + (c8 + c9))) + ((c10 + c11) + ((c12 + c13) + (c14 + c15)))) + c3)