Skip to content

Commit

Permalink
coverage: Simplify sorting of coverage spans extracted from MIR
Browse files Browse the repository at this point in the history
Switching to `Ordering::then_with` makes control-flow less complicated, and
there is no need to use `partial_cmp` here.
  • Loading branch information
Zalathar committed Sep 18, 2023
1 parent d6dd539 commit 7375ec7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 35 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/graph/dominators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ impl<Node: Idx> Dominators<Node> {
/// relationship, the dominator will always precede the dominated. (The relative ordering
/// of two unrelated nodes will also be consistent, but otherwise the order has no
/// meaning.) This method cannot be used to determine if either Node dominates the other.
pub fn rank_partial_cmp(&self, lhs: Node, rhs: Node) -> Option<Ordering> {
self.post_order_rank[rhs].partial_cmp(&self.post_order_rank[lhs])
pub fn cmp_in_dominator_order(&self, lhs: Node, rhs: Node) -> Ordering {
self.post_order_rank[rhs].cmp(&self.post_order_rank[lhs])
}

/// Returns true if `a` dominates `b`.
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_mir_transform/src/coverage/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,8 @@ impl CoverageGraph {
}

#[inline(always)]
pub fn rank_partial_cmp(
&self,
a: BasicCoverageBlock,
b: BasicCoverageBlock,
) -> Option<Ordering> {
self.dominators.as_ref().unwrap().rank_partial_cmp(a, b)
pub fn cmp_in_dominator_order(&self, a: BasicCoverageBlock, b: BasicCoverageBlock) -> Ordering {
self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
}
}

Expand Down
41 changes: 14 additions & 27 deletions compiler/rustc_mir_transform/src/coverage/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_span::source_map::original_sp;
use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol};

use std::cell::OnceCell;
use std::cmp::Ordering;

#[derive(Debug, Copy, Clone)]
pub(super) enum CoverageStatement {
Expand Down Expand Up @@ -334,32 +333,20 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
initial_spans.push(CoverageSpan::for_fn_sig(self.fn_sig_span));

initial_spans.sort_by(|a, b| {
if a.span.lo() == b.span.lo() {
if a.span.hi() == b.span.hi() {
if a.is_in_same_bcb(b) {
Some(Ordering::Equal)
} else {
// Sort equal spans by dominator relationship (so dominators always come
// before the dominated equal spans). When later comparing two spans in
// order, the first will either dominate the second, or they will have no
// dominator relationship.
self.basic_coverage_blocks.rank_partial_cmp(a.bcb, b.bcb)
}
} else {
// Sort hi() in reverse order so shorter spans are attempted after longer spans.
// This guarantees that, if a `prev` span overlaps, and is not equal to, a
// `curr` span, the prev span either extends further left of the curr span, or
// they start at the same position and the prev span extends further right of
// the end of the curr span.
b.span.hi().partial_cmp(&a.span.hi())
}
} else {
a.span.lo().partial_cmp(&b.span.lo())
}
.unwrap()
// If two spans are otherwise identical, put closure spans first,
// as this seems to be what the refinement step expects.
.then_with(|| Ord::cmp(&a.is_closure, &b.is_closure).reverse())
// First sort by span start.
Ord::cmp(&a.span.lo(), &b.span.lo())
// If span starts are the same, sort by span end in reverse order.
// This ensures that if spans A and B are adjacent in the list,
// and they overlap but are not equal, then either:
// - Span A extends further left, or
// - Both have the same start and span A extends further right
.then_with(|| Ord::cmp(&a.span.hi(), &b.span.hi()).reverse())
// If both spans are equal, sort the BCBs in dominator order,
// so that dominating BCBs come before other BCBs they dominate.
.then_with(|| self.basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb))
// If two spans are otherwise identical, put closure spans first,
// as this seems to be what the refinement step expects.
.then_with(|| Ord::cmp(&a.is_closure, &b.is_closure).reverse())
});

initial_spans
Expand Down

0 comments on commit 7375ec7

Please sign in to comment.