Skip to content

coverage: Give the instrumentor its own counter type, separate from MIR #114791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 20, 2023

Conversation

Zalathar
Copy link
Contributor

@Zalathar Zalathar commented Aug 14, 2023

Within the MIR representation of coverage data, CoverageKind is an important part of StatementKind::Coverage, but the InstrumentCoverage pass also uses it heavily as an internal data structure. This means that any change to CoverageKind also needs to update all of the internal parts of InstrumentCoverage that manipulate it directly, making the MIR representation difficult to modify.


This change fixes that by giving the instrumentor its own BcbCounter type for internal use, which is then converted to a CoverageKind when injecting coverage information into MIR.

The main change is mostly mechanical, because the initial BcbCounter is drop-in compatible with CoverageKind, minus the unnecessary CoverageKind::Unreachable variant.

I've then removed the function_source_hash field from BcbCounter::Counter, as a small example of how the two types can now usefully differ from each other. Every counter in a MIR-level function should have the same source hash, so we can supply the hash during the conversion to CoverageKind::Counter instead.


Background: BCB stands for “basic coverage block”, which is a node in the simplified control-flow graph used by coverage instrumentation. The instrumentor pass uses the function's actual MIR control-flow graph to build a simplified BCB graph, then assigns coverage counters and counter expressions to various nodes/edges in that simplified graph, and then finally injects corresponding coverage information into the underlying MIR.

@rustbot
Copy link
Collaborator

rustbot commented Aug 14, 2023

r? @cjgillot

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 14, 2023
@rustbot
Copy link
Collaborator

rustbot commented Aug 14, 2023

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added the A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) label Aug 14, 2023
@Zalathar
Copy link
Contributor Author

This is one step in my larger coverage refactoring ambitions described at rust-lang/compiler-team#645.

@Zalathar Zalathar force-pushed the bcb-counter branch 5 times, most recently from 221d4d3 to 8b93430 Compare August 18, 2023 02:29
This splits off `BcbCounter` from MIR's `CoverageKind`, allowing the two types
to evolve in different directions as necessary.
This shows one small benefit of separating `BcbCounter` from `CoverageKind`.
The function source hash will be the same for all counters within a function,
so instead of passing it through `CoverageCounters` and storing it in every
counter, we can just supply it during the final conversion to `CoverageKind`.
source_map.span_to_diagnostic_string(span),
source_map.span_to_diagnostic_string(body_span)
);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use #[instrument(level="debug", skip(source_map))] attribute macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this isn't new code; I'm just moving it here as-is so that it's out of the way of other changes to inject_coverage_span_counters (which is the only caller).

/// Tracks which BCBs have a counter associated with some incoming edge.
/// Only used by debug assertions, to verify that BCBs with incoming edge
/// counters do not have their own physical counters (expressions are allowed).
bcb_has_incoming_edge_counters: BitSet<BasicCoverageBlock>,
/// Expression nodes that are not directly associated with any particular
/// BCB/edge, but are needed as operands to more complex expressions.
/// These are always `CoverageKind::Expression`.
pub(super) intermediate_expressions: Vec<CoverageKind>,
/// These are always [`BcbCounter::Expression`].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they always are the same variant, should they get a specific struct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes they should, and I've tried to make that change in the past, but it ends up being pretty fiddly because of how the existing code interacts with counters/expressions.

For this PR I wanted to keep things mostly simple and mechanical, and treat BcbCounter as a drop-in replacement for CoverageKind, without disturbing other code too much.

@cjgillot
Copy link
Contributor

@bors r+

@bors
Copy link
Collaborator

bors commented Aug 20, 2023

📌 Commit 72f4c78 has been approved by cjgillot

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 20, 2023
@bors
Copy link
Collaborator

bors commented Aug 20, 2023

⌛ Testing commit 72f4c78 with merge 0510a15...

@bors
Copy link
Collaborator

bors commented Aug 20, 2023

☀️ Test successful - checks-actions
Approved by: cjgillot
Pushing 0510a15 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 20, 2023
@bors bors merged commit 0510a15 into rust-lang:master Aug 20, 2023
@rustbot rustbot added this to the 1.73.0 milestone Aug 20, 2023
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (0510a15): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.4% [3.4%, 3.4%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.0% [-2.2%, -1.9%] 3
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 637.88s -> 636.195s (-0.26%)
Artifact size: 347.07 MiB -> 346.98 MiB (-0.03%)

@Zalathar Zalathar deleted the bcb-counter branch August 20, 2023 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants