Skip to content

Commit 135cd69

Browse files
authored
Rollup merge of rust-lang#135873 - Zalathar:be-prepared, r=oli-obk
coverage: Prepare for upcoming changes to counter creation This is a collection of smaller changes to coverage instrumentation code that have been extracted from a larger PR that I'm still working on, in order to hopefully make review easier. Each individual change should hopefully be mostly self-explanatory. One of the big goals of the upcoming PR will be to defer certain parts of counter-creation until codegen, via the query system, so that ends up being a recurring theme in these changes. Several of the changes are follow-ups to rust-lang#135481. There should be no observable change in compiler output.
2 parents 8231e85 + 7f10ab2 commit 135cd69

File tree

15 files changed

+182
-200
lines changed

15 files changed

+182
-200
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub(crate) fn prepare_covfun_record<'tcx>(
5151
is_used: bool,
5252
) -> Option<CovfunRecord<'tcx>> {
5353
let fn_cov_info = tcx.instance_mir(instance.def).function_coverage_info.as_deref()?;
54-
let ids_info = tcx.coverage_ids_info(instance.def);
54+
let ids_info = tcx.coverage_ids_info(instance.def)?;
5555

5656
let expressions = prepare_expressions(fn_cov_info, ids_info, is_used);
5757

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_codegen_ssa::traits::{
88
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
99
use rustc_middle::mir::coverage::CoverageKind;
1010
use rustc_middle::ty::Instance;
11-
use rustc_middle::ty::layout::HasTyCtxt;
1211
use tracing::{debug, instrument};
1312

1413
use crate::builder::Builder;
@@ -147,6 +146,10 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
147146
debug!("function has a coverage statement but no coverage info");
148147
return;
149148
};
149+
let Some(ids_info) = bx.tcx.coverage_ids_info(instance.def) else {
150+
debug!("function has a coverage statement but no IDs info");
151+
return;
152+
};
150153

151154
// Mark the instance as used in this CGU, for coverage purposes.
152155
// This includes functions that were not partitioned into this CGU,
@@ -162,8 +165,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
162165
// be smaller than the number originally inserted by the instrumentor,
163166
// if some high-numbered counters were removed by MIR optimizations.
164167
// If so, LLVM's profiler runtime will use fewer physical counters.
165-
let num_counters =
166-
bx.tcx().coverage_ids_info(instance.def).num_counters_after_mir_opts();
168+
let num_counters = ids_info.num_counters_after_mir_opts();
167169
assert!(
168170
num_counters as usize <= function_coverage_info.num_counters,
169171
"num_counters disagreement: query says {num_counters} but function info only has {}",

compiler/rustc_middle/src/mir/coverage.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter};
44

55
use rustc_index::IndexVec;
66
use rustc_index::bit_set::DenseBitSet;
7-
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
7+
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
88
use rustc_span::Span;
99

1010
rustc_index::newtype_index! {
@@ -72,7 +72,7 @@ impl ConditionId {
7272
/// Enum that can hold a constant zero value, the ID of an physical coverage
7373
/// counter, or the ID of a coverage-counter expression.
7474
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
75-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
75+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
7676
pub enum CovTerm {
7777
Zero,
7878
Counter(CounterId),
@@ -89,7 +89,7 @@ impl Debug for CovTerm {
8989
}
9090
}
9191

92-
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
92+
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
9393
pub enum CoverageKind {
9494
/// Marks a span that might otherwise not be represented in MIR, so that
9595
/// coverage instrumentation can associate it with its enclosing block/BCB.
@@ -151,7 +151,7 @@ impl Debug for CoverageKind {
151151
}
152152

153153
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
154-
#[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
154+
#[derive(TyEncodable, TyDecodable)]
155155
pub enum Op {
156156
Subtract,
157157
Add,
@@ -168,15 +168,15 @@ impl Op {
168168
}
169169

170170
#[derive(Clone, Debug, PartialEq, Eq)]
171-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
171+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
172172
pub struct Expression {
173173
pub lhs: CovTerm,
174174
pub op: Op,
175175
pub rhs: CovTerm,
176176
}
177177

178178
#[derive(Clone, Debug)]
179-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
179+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
180180
pub enum MappingKind {
181181
/// Associates a normal region of code with a counter/expression/zero.
182182
Code(CovTerm),
@@ -208,7 +208,7 @@ impl MappingKind {
208208
}
209209

210210
#[derive(Clone, Debug)]
211-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
211+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
212212
pub struct Mapping {
213213
pub kind: MappingKind,
214214
pub span: Span,
@@ -218,7 +218,7 @@ pub struct Mapping {
218218
/// to be used in conjunction with the individual coverage statements injected
219219
/// into the function's basic blocks.
220220
#[derive(Clone, Debug)]
221-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
221+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
222222
pub struct FunctionCoverageInfo {
223223
pub function_source_hash: u64,
224224
pub body_span: Span,
@@ -238,7 +238,7 @@ pub struct FunctionCoverageInfo {
238238
/// ("Hi" indicates that this is "high-level" information collected at the
239239
/// THIR/MIR boundary, before the MIR-based coverage instrumentation pass.)
240240
#[derive(Clone, Debug)]
241-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
241+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
242242
pub struct CoverageInfoHi {
243243
/// 1 more than the highest-numbered [`CoverageKind::BlockMarker`] that was
244244
/// injected into the MIR body. This makes it possible to allocate per-ID
@@ -252,23 +252,23 @@ pub struct CoverageInfoHi {
252252
}
253253

254254
#[derive(Clone, Debug)]
255-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
255+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
256256
pub struct BranchSpan {
257257
pub span: Span,
258258
pub true_marker: BlockMarkerId,
259259
pub false_marker: BlockMarkerId,
260260
}
261261

262262
#[derive(Copy, Clone, Debug)]
263-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
263+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
264264
pub struct ConditionInfo {
265265
pub condition_id: ConditionId,
266266
pub true_next_id: Option<ConditionId>,
267267
pub false_next_id: Option<ConditionId>,
268268
}
269269

270270
#[derive(Clone, Debug)]
271-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
271+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
272272
pub struct MCDCBranchSpan {
273273
pub span: Span,
274274
pub condition_info: ConditionInfo,
@@ -277,14 +277,14 @@ pub struct MCDCBranchSpan {
277277
}
278278

279279
#[derive(Copy, Clone, Debug)]
280-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
280+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
281281
pub struct DecisionInfo {
282282
pub bitmap_idx: u32,
283283
pub num_conditions: u16,
284284
}
285285

286286
#[derive(Clone, Debug)]
287-
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
287+
#[derive(TyEncodable, TyDecodable, Hash, HashStable)]
288288
pub struct MCDCDecisionSpan {
289289
pub span: Span,
290290
pub end_markers: Vec<BlockMarkerId>,

compiler/rustc_middle/src/mir/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ pub struct Body<'tcx> {
358358
///
359359
/// Only present if coverage is enabled and this function is eligible.
360360
/// Boxed to limit space overhead in non-coverage builds.
361+
#[type_foldable(identity)]
362+
#[type_visitable(ignore)]
361363
pub coverage_info_hi: Option<Box<coverage::CoverageInfoHi>>,
362364

363365
/// Per-function coverage information added by the `InstrumentCoverage`
@@ -366,6 +368,8 @@ pub struct Body<'tcx> {
366368
///
367369
/// If `-Cinstrument-coverage` is not active, or if an individual function
368370
/// is not eligible for coverage, then this should always be `None`.
371+
#[type_foldable(identity)]
372+
#[type_visitable(ignore)]
369373
pub function_coverage_info: Option<Box<coverage::FunctionCoverageInfo>>,
370374
}
371375

compiler/rustc_middle/src/mir/syntax.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,14 @@ pub enum StatementKind<'tcx> {
417417
///
418418
/// Interpreters and codegen backends that don't support coverage instrumentation
419419
/// can usually treat this as a no-op.
420-
Coverage(CoverageKind),
420+
Coverage(
421+
// Coverage statements are unlikely to ever contain type information in
422+
// the foreseeable future, so excluding them from TypeFoldable/TypeVisitable
423+
// avoids some unhelpful derive boilerplate.
424+
#[type_foldable(identity)]
425+
#[type_visitable(ignore)]
426+
CoverageKind,
427+
),
421428

422429
/// Denotes a call to an intrinsic that does not require an unwind path and always returns.
423430
/// This avoids adding a new block and a terminator for simple intrinsics.

compiler/rustc_middle/src/query/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ rustc_queries! {
618618
/// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass
619619
/// (for compiler option `-Cinstrument-coverage`), after MIR optimizations
620620
/// have had a chance to potentially remove some of them.
621-
query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> &'tcx mir::coverage::CoverageIdsInfo {
621+
///
622+
/// Returns `None` for functions that were not instrumented.
623+
query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> {
622624
desc { |tcx| "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
623625
arena_cache
624626
}

compiler/rustc_mir_transform/src/coverage/counters.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId,
1111

1212
use crate::coverage::counters::balanced_flow::BalancedFlowGraph;
1313
use crate::coverage::counters::iter_nodes::IterNodes;
14-
use crate::coverage::counters::node_flow::{CounterTerm, MergedNodeFlowGraph, NodeCounters};
14+
use crate::coverage::counters::node_flow::{
15+
CounterTerm, NodeCounters, make_node_counters, node_flow_data_for_balanced_graph,
16+
};
1517
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
1618

1719
mod balanced_flow;
@@ -27,20 +29,20 @@ pub(super) fn make_bcb_counters(
2729
) -> CoverageCounters {
2830
// Create the derived graphs that are necessary for subsequent steps.
2931
let balanced_graph = BalancedFlowGraph::for_graph(graph, |n| !graph[n].is_out_summable);
30-
let merged_graph = MergedNodeFlowGraph::for_balanced_graph(&balanced_graph);
32+
let node_flow_data = node_flow_data_for_balanced_graph(&balanced_graph);
3133

3234
// Use those graphs to determine which nodes get physical counters, and how
3335
// to compute the execution counts of other nodes from those counters.
34-
let nodes = make_node_counter_priority_list(graph, balanced_graph);
35-
let node_counters = merged_graph.make_node_counters(&nodes);
36+
let priority_list = make_node_flow_priority_list(graph, balanced_graph);
37+
let node_counters = make_node_counters(&node_flow_data, &priority_list);
3638

3739
// Convert the counters into a form suitable for embedding into MIR.
3840
transcribe_counters(&node_counters, bcb_needs_counter)
3941
}
4042

4143
/// Arranges the nodes in `balanced_graph` into a list, such that earlier nodes
4244
/// take priority in being given a counter expression instead of a physical counter.
43-
fn make_node_counter_priority_list(
45+
fn make_node_flow_priority_list(
4446
graph: &CoverageGraph,
4547
balanced_graph: BalancedFlowGraph<&CoverageGraph>,
4648
) -> Vec<BasicCoverageBlock> {
@@ -81,11 +83,11 @@ fn transcribe_counters(
8183
let mut new = CoverageCounters::with_num_bcbs(bcb_needs_counter.domain_size());
8284

8385
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
86+
// Our counter-creation algorithm doesn't guarantee that a node's list
87+
// of terms starts or ends with a positive term, so partition the
8688
// counters into "positive" and "negative" lists for easier handling.
8789
let (mut pos, mut neg): (Vec<_>, Vec<_>) =
88-
old.counter_expr(bcb).iter().partition_map(|&CounterTerm { node, op }| match op {
90+
old.counter_terms[bcb].iter().partition_map(|&CounterTerm { node, op }| match op {
8991
Op::Add => Either::Left(node),
9092
Op::Subtract => Either::Right(node),
9193
});

0 commit comments

Comments
 (0)