Skip to content

Commit 1973f84

Browse files
committed
Addressed all feedback to date
1 parent 5545c56 commit 1973f84

File tree

8 files changed

+41
-57
lines changed

8 files changed

+41
-57
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,19 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
8282
fn add_coverage_counter(
8383
&mut self,
8484
instance: Instance<'tcx>,
85-
function_source_hash: u64,
8685
id: CounterValueReference,
8786
region: CodeRegion,
8887
) -> bool {
8988
if let Some(coverage_context) = self.coverage_context() {
9089
debug!(
91-
"adding counter to coverage_map: instance={:?}, function_source_hash={}, id={:?}, \
92-
at {:?}",
93-
instance, function_source_hash, id, region,
90+
"adding counter to coverage_map: instance={:?}, id={:?}, region={:?}",
91+
instance, id, region,
9492
);
9593
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
9694
coverage_map
9795
.entry(instance)
9896
.or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
99-
.add_counter(function_source_hash, id, region);
97+
.add_counter(id, region);
10098
true
10199
} else {
102100
false

compiler/rustc_codegen_ssa/src/coverageinfo/map.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,8 @@ impl<'tcx> FunctionCoverage<'tcx> {
5252
}
5353
}
5454

55-
/// Although every function should have at least one `Counter`, the `Counter` isn't required to
56-
/// have a `CodeRegion`. (The `CodeRegion` may be associated only with `Expressions`.) This
57-
/// method supports the ability to ensure the `function_source_hash` is set from `Counters` that
58-
/// do not trigger the call to `add_counter()` because they don't have an associated
59-
/// `CodeRegion` to add.
55+
/// Sets the function source hash value. If called multiple times for the same function, all
56+
/// calls should have the same hash value.
6057
pub fn set_function_source_hash(&mut self, source_hash: u64) {
6158
if self.source_hash == 0 {
6259
self.source_hash = source_hash;
@@ -66,14 +63,7 @@ impl<'tcx> FunctionCoverage<'tcx> {
6663
}
6764

6865
/// Adds a code region to be counted by an injected counter intrinsic.
69-
/// The source_hash (computed during coverage instrumentation) should also be provided, and
70-
/// should be the same for all counters in a given function.
71-
pub fn add_counter(&mut self, source_hash: u64, id: CounterValueReference, region: CodeRegion) {
72-
if self.source_hash == 0 {
73-
self.source_hash = source_hash;
74-
} else {
75-
debug_assert_eq!(source_hash, self.source_hash);
76-
}
66+
pub fn add_counter(&mut self, id: CounterValueReference, region: CodeRegion) {
7767
self.counters[id].replace(region).expect_none("add_counter called with duplicate `id`");
7868
}
7969

compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1010
let Coverage { kind, code_region } = coverage;
1111
match kind {
1212
CoverageKind::Counter { function_source_hash, id } => {
13-
let covmap_updated = if let Some(code_region) = code_region {
14-
// Note: Some counters do not have code regions, but may still be referenced from
15-
// expressions.
16-
bx.add_coverage_counter(self.instance, function_source_hash, id, code_region)
17-
} else {
18-
bx.set_function_source_hash(self.instance, function_source_hash)
19-
};
13+
if bx.set_function_source_hash(self.instance, function_source_hash) {
14+
// If `set_function_source_hash()` returned true, the coverage map is enabled,
15+
// so continue adding the counter.
16+
if let Some(code_region) = code_region {
17+
// Note: Some counters do not have code regions, but may still be referenced
18+
// from expressions. In that case, don't add the counter to the coverage map,
19+
// but do inject the counter intrinsic.
20+
bx.add_coverage_counter(self.instance, id, code_region);
21+
}
2022

21-
if covmap_updated {
2223
let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id());
2324

2425
let fn_name = bx.create_pgo_func_name_var(self.instance);

compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ pub trait CoverageInfoMethods: BackendTypes {
99
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
1010
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
1111

12-
/// Returns true if the function source hash was added to the coverage map; false if
13-
/// `-Z instrument-coverage` is not enabled (a coverage map is not being generated).
12+
/// Returns true if the function source hash was added to the coverage map (even if it had
13+
/// already been added, for this instance). Returns false *only* if `-Z instrument-coverage` is
14+
/// not enabled (a coverage map is not being generated).
1415
fn set_function_source_hash(
1516
&mut self,
1617
instance: Instance<'tcx>,
@@ -22,7 +23,6 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
2223
fn add_coverage_counter(
2324
&mut self,
2425
instance: Instance<'tcx>,
25-
function_source_hash: u64,
2626
index: CounterValueReference,
2727
region: CodeRegion,
2828
) -> bool;

compiler/rustc_middle/src/mir/coverage.rs

-14
Original file line numberDiff line numberDiff line change
@@ -85,27 +85,13 @@ impl From<CounterValueReference> for ExpressionOperandId {
8585
}
8686
}
8787

88-
impl From<&mut CounterValueReference> for ExpressionOperandId {
89-
#[inline]
90-
fn from(v: &mut CounterValueReference) -> ExpressionOperandId {
91-
ExpressionOperandId::from(v.as_u32())
92-
}
93-
}
94-
9588
impl From<InjectedExpressionId> for ExpressionOperandId {
9689
#[inline]
9790
fn from(v: InjectedExpressionId) -> ExpressionOperandId {
9891
ExpressionOperandId::from(v.as_u32())
9992
}
10093
}
10194

102-
impl From<&mut InjectedExpressionId> for ExpressionOperandId {
103-
#[inline]
104-
fn from(v: &mut InjectedExpressionId) -> ExpressionOperandId {
105-
ExpressionOperandId::from(v.as_u32())
106-
}
107-
}
108-
10995
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
11096
pub enum CoverageKind {
11197
Counter {

compiler/rustc_mir/src/transform/coverage/counters.rs

+11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ use rustc_data_structures::graph::WithNumNodes;
1212
use rustc_index::bit_set::BitSet;
1313
use rustc_middle::mir::coverage::*;
1414

15+
// When evaluating an expression operand to determine if it references a `Counter` or an
16+
// `Expression`, the range of counter or expression IDs must be known in order to answer the
17+
// question: "Does this ID fall inside the range of counters," for example. If "yes," the ID refers
18+
// to a counter, otherwise the ID refers to an expression.
19+
//
20+
// But in situations where the range is not currently known, the only fallback is to assume a
21+
// specific range limit. `MAX_COUNTER_GUARD` enforces a limit on the number of counters, and
22+
// therefore a limit on the range of counter IDs.
23+
pub(crate) const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1;
24+
1525
/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
1626
/// `Coverage` statements.
1727
pub(crate) struct CoverageCounters {
@@ -95,6 +105,7 @@ impl CoverageCounters {
95105
/// Counter IDs start from one and go up.
96106
fn next_counter(&mut self) -> CounterValueReference {
97107
assert!(self.next_counter_id < u32::MAX - self.num_expressions);
108+
assert!(self.next_counter_id <= MAX_COUNTER_GUARD);
98109
let next = self.next_counter_id;
99110
self.next_counter_id += 1;
100111
CounterValueReference::from(next)

compiler/rustc_mir/src/transform/coverage/query.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use super::counters;
2+
13
use rustc_middle::mir::coverage::*;
24
use rustc_middle::mir::visit::Visitor;
35
use rustc_middle::mir::{Coverage, CoverageInfo, Location};
@@ -32,21 +34,16 @@ pub(crate) fn provide(providers: &mut Providers) {
3234
/// safeguard, with `add_missing_operands` set to `true`, to find any other counter or expression
3335
/// IDs referenced by expression operands, if not already seen.
3436
///
35-
/// Ideally, every expression operand in the MIR will have a corresponding Counter or Expression,
36-
/// but since current or future MIR optimizations can theoretically optimize out segments of a
37-
/// MIR, it may not be possible to guarantee this, so the second pass ensures the `CoverageInfo`
38-
/// counts include all referenced IDs.
37+
/// Ideally, each operand ID in a MIR `CoverageKind::Expression` will have a separate MIR `Coverage`
38+
/// statement for the `Counter` or `Expression` with the referenced ID. but since current or future
39+
/// MIR optimizations can theoretically optimize out segments of a MIR, it may not be possible to
40+
/// guarantee this, so the second pass ensures the `CoverageInfo` counts include all referenced IDs.
3941
struct CoverageVisitor {
4042
info: CoverageInfo,
4143
add_missing_operands: bool,
4244
}
4345

4446
impl CoverageVisitor {
45-
// If an expression operand is encountered with an ID outside the range of known counters and
46-
// expressions, the only way to determine if the ID is a counter ID or an expression ID is to
47-
// assume a maximum possible counter ID value.
48-
const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1;
49-
5047
#[inline(always)]
5148
fn update_num_counters(&mut self, counter_id: u32) {
5249
self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1);
@@ -62,7 +59,10 @@ impl CoverageVisitor {
6259
if operand_id >= self.info.num_counters {
6360
let operand_as_expression_index = u32::MAX - operand_id;
6461
if operand_as_expression_index >= self.info.num_expressions {
65-
if operand_id <= Self::MAX_COUNTER_GUARD {
62+
if operand_id <= counters::MAX_COUNTER_GUARD {
63+
// Since the complete range of counter and expression IDs is not known here, the
64+
// only way to determine if the ID is a counter ID or an expression ID is to
65+
// assume a maximum possible counter ID value.
6666
self.update_num_counters(operand_id)
6767
} else {
6868
self.update_num_expressions(operand_id)

compiler/rustc_mir/src/transform/coverage/spans.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
388388
bcb_data
389389
.basic_blocks
390390
.iter()
391-
.map(|bbref| {
392-
let bb = *bbref;
391+
.flat_map(|&bb| {
393392
let data = &self.mir_body[bb];
394393
data.statements
395394
.iter()
@@ -404,7 +403,6 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
404403
.map(|span| CoverageSpan::for_terminator(span, bcb, bb)),
405404
)
406405
})
407-
.flatten()
408406
.collect()
409407
}
410408

@@ -733,7 +731,7 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) -
733731
// However, in other cases, a visible `CoverageSpan` is not wanted, but the `Goto`
734732
// block must still be counted (for example, to contribute its count to an `Expression`
735733
// that reports the execution count for some other block). In these cases, the code region
736-
// is set to `None`.
734+
// is set to `None`. (See `Instrumentor::is_code_region_redundant()`.)
737735
TerminatorKind::Goto { .. } => {
738736
Some(function_source_span(terminator.source_info.span.shrink_to_hi(), body_span))
739737
}

0 commit comments

Comments
 (0)