Skip to content

Commit 52c1bfa

Browse files
committed
coverage: Simplify how counter terms are stored
Using `SmallVec` here was fine when it was a module-private detail, but if we want to pass these terms across query boundaries then it's not worth the extra hassle. Replacing a method call with direct field access is slightly simpler. Using the name `counter_terms` is more consistent with other code that tries to maintain a distinction between (physical) "counters" and "expressions".
1 parent ff48331 commit 52c1bfa

File tree

3 files changed

+20
-30
lines changed

3 files changed

+20
-30
lines changed

compiler/rustc_mir_transform/src/coverage/counters.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ fn transcribe_counters(
8181
let mut new = CoverageCounters::with_num_bcbs(bcb_needs_counter.domain_size());
8282

8383
for bcb in bcb_needs_counter.iter() {
84-
// Our counter-creation algorithm doesn't guarantee that a counter
85-
// expression starts or ends with a positive term, so partition the
84+
// Our counter-creation algorithm doesn't guarantee that a node's list
85+
// of terms starts or ends with a positive term, so partition the
8686
// counters into "positive" and "negative" lists for easier handling.
8787
let (mut pos, mut neg): (Vec<_>, Vec<_>) =
88-
old.counter_expr(bcb).iter().partition_map(|&CounterTerm { node, op }| match op {
88+
old.counter_terms[bcb].iter().partition_map(|&CounterTerm { node, op }| match op {
8989
Op::Add => Either::Left(node),
9090
Op::Subtract => Either::Right(node),
9191
});

compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_data_structures::graph;
1010
use rustc_index::bit_set::DenseBitSet;
1111
use rustc_index::{Idx, IndexVec};
1212
use rustc_middle::mir::coverage::Op;
13-
use smallvec::SmallVec;
1413

1514
use crate::coverage::counters::iter_nodes::IterNodes;
1615
use crate::coverage::counters::union_find::{FrozenUnionFind, UnionFind};
@@ -100,26 +99,20 @@ impl<Node: Idx> MergedNodeFlowGraph<Node> {
10099
builder.visit_node(node);
101100
}
102101

103-
NodeCounters { counter_exprs: builder.finish() }
102+
NodeCounters { counter_terms: builder.finish() }
104103
}
105104
}
106105

107106
/// End result of allocating physical counters and counter expressions for the
108107
/// nodes of a graph.
109108
#[derive(Debug)]
110109
pub(crate) struct NodeCounters<Node: Idx> {
111-
counter_exprs: IndexVec<Node, CounterExprVec<Node>>,
112-
}
113-
114-
impl<Node: Idx> NodeCounters<Node> {
115110
/// For the given node, returns the finished list of terms that represent
116111
/// its physical counter or counter expression. Always non-empty.
117112
///
118-
/// If a node was given a physical counter, its "expression" will contain
113+
/// If a node was given a physical counter, the term list will contain
119114
/// that counter as its sole element.
120-
pub(crate) fn counter_expr(&self, this: Node) -> &[CounterTerm<Node>] {
121-
self.counter_exprs[this].as_slice()
122-
}
115+
pub(crate) counter_terms: IndexVec<Node, Vec<CounterTerm<Node>>>,
123116
}
124117

125118
#[derive(Debug)]
@@ -146,9 +139,6 @@ pub(crate) struct CounterTerm<Node> {
146139
pub(crate) node: Node,
147140
}
148141

149-
/// Stores the list of counter terms that make up a node's counter expression.
150-
type CounterExprVec<Node> = SmallVec<[CounterTerm<Node>; 2]>;
151-
152142
#[derive(Debug)]
153143
struct SpantreeBuilder<'a, Node: Idx> {
154144
graph: &'a MergedNodeFlowGraph<Node>,
@@ -163,7 +153,7 @@ struct SpantreeBuilder<'a, Node: Idx> {
163153
yank_buffer: Vec<Node>,
164154
/// An in-progress counter expression for each node. Each expression is
165155
/// initially empty, and will be filled in as relevant nodes are visited.
166-
counter_exprs: IndexVec<Node, CounterExprVec<Node>>,
156+
counter_terms: IndexVec<Node, Vec<CounterTerm<Node>>>,
167157
}
168158

169159
impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
@@ -174,7 +164,7 @@ impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
174164
is_unvisited: DenseBitSet::new_filled(num_nodes),
175165
span_edges: IndexVec::from_fn_n(|_| None, num_nodes),
176166
yank_buffer: vec![],
177-
counter_exprs: IndexVec::from_fn_n(|_| SmallVec::new(), num_nodes),
167+
counter_terms: IndexVec::from_fn_n(|_| vec![], num_nodes),
178168
}
179169
}
180170

@@ -268,8 +258,8 @@ impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
268258
// `this_supernode`.
269259

270260
// Instead of setting `this.measure = true` as in the original paper,
271-
// we just add the node's ID to its own "expression".
272-
self.counter_exprs[this].push(CounterTerm { node: this, op: Op::Add });
261+
// we just add the node's ID to its own list of terms.
262+
self.counter_terms[this].push(CounterTerm { node: this, op: Op::Add });
273263

274264
// Walk the spantree from `this.successor` back to `this`. For each
275265
// spantree edge along the way, add this node's physical counter to
@@ -279,7 +269,7 @@ impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
279269
let &SpantreeEdge { is_reversed, claiming_node, span_parent } =
280270
self.span_edges[curr].as_ref().unwrap();
281271
let op = if is_reversed { Op::Subtract } else { Op::Add };
282-
self.counter_exprs[claiming_node].push(CounterTerm { node: this, op });
272+
self.counter_terms[claiming_node].push(CounterTerm { node: this, op });
283273

284274
curr = span_parent;
285275
}
@@ -288,8 +278,8 @@ impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
288278

289279
/// Asserts that all nodes have been visited, and returns the computed
290280
/// counter expressions (made up of physical counters) for each node.
291-
fn finish(self) -> IndexVec<Node, CounterExprVec<Node>> {
292-
let Self { graph, is_unvisited, span_edges, yank_buffer: _, counter_exprs } = self;
281+
fn finish(self) -> IndexVec<Node, Vec<CounterTerm<Node>>> {
282+
let Self { graph, is_unvisited, span_edges, yank_buffer: _, counter_terms } = self;
293283
assert!(is_unvisited.is_empty(), "some nodes were never visited: {is_unvisited:?}");
294284
debug_assert!(
295285
span_edges
@@ -298,9 +288,9 @@ impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
298288
"only supernodes can have a span edge",
299289
);
300290
debug_assert!(
301-
counter_exprs.iter().all(|expr| !expr.is_empty()),
302-
"after visiting all nodes, every node should have a non-empty expression",
291+
counter_terms.iter().all(|terms| !terms.is_empty()),
292+
"after visiting all nodes, every node should have at least one term",
303293
);
304-
counter_exprs
294+
counter_terms
305295
}
306296
}

compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ fn format_counter_expressions<Node: Idx>(counters: &NodeCounters<Node>) -> Vec<S
5353
};
5454

5555
counters
56-
.counter_exprs
56+
.counter_terms
5757
.indices()
5858
.map(|node| {
59-
let mut expr = counters.counter_expr(node).iter().collect::<Vec<_>>();
60-
expr.sort_by_key(|item| item.node.index());
61-
format!("[{node:?}]: {}", expr.into_iter().map(format_item).join(" "))
59+
let mut terms = counters.counter_terms[node].iter().collect::<Vec<_>>();
60+
terms.sort_by_key(|item| item.node.index());
61+
format!("[{node:?}]: {}", terms.into_iter().map(format_item).join(" "))
6262
})
6363
.collect()
6464
}

0 commit comments

Comments
 (0)