Skip to content
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

coverage: Allow each coverage statement to have multiple code regions #115301

Merged
merged 7 commits into from
Oct 3, 2023

Conversation

Zalathar
Copy link
Contributor

@Zalathar Zalathar commented Aug 28, 2023

The original implementation of coverage instrumentation was built around the assumption that a coverage counter/expression would be associated with up to one code region. When it was discovered that multiple regions would sometimes need to share a counter, a workaround was found: for the remaining regions, the instrumentor would create a fresh expression that adds zero to the existing counter/expression.

That got the job done, but resulted in some awkward code, and produces unnecessarily complicated coverage maps in the final binary.


This PR removes that tension by changing StatementKind::Coverage's code region field from Option<CodeRegion> to Vec<CodeRegion>.

The changes on the codegen side are fairly straightforward. As long as each CoverageKind::Counter only injects one llvm.instrprof.increment, the rest of coverage codegen is happy to handle multiple regions mapped to the same counter/expression, with only minor option-to-vec adjustments.

On the instrumentor/mir-transform side, we can get rid of the code that creates extra (x + 0) expressions. Instead we gather all of the code regions associated with a single BCB, and inject them all into one coverage statement.


There are several patches here but they can be divided in to three phases:

  • Preparatory work
  • Actually switching over to multiple regions per coverage statement
  • Cleaning up

So viewing the patches individually may be easier.

@rustbot
Copy link
Collaborator

rustbot commented Aug 28, 2023

r? @davidtwco

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

@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 28, 2023
@rustbot
Copy link
Collaborator

rustbot commented Aug 28, 2023

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @celinval, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Aug 28, 2023
@Zalathar
Copy link
Contributor Author

(Cargo.toml changes are part of #114843 and won't remain in the final version of this PR.)

Comment on lines -126 to -129
debug!(
"adding counter to coverage_map: instance={:?}, id={:?}, region={:?}",
instance, id, code_region,
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These debug! invocations have been replaced with #[instrument(...)] tracing on the methods being called.

);
func_coverage.add_counter(id, code_region);
}
func_coverage.add_counter(id, code_regions);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We now call add_counter unconditionally here, and leave the callee to decide how to handle counters with zero code regions.

@Zalathar Zalathar force-pushed the regions-vec branch 4 times, most recently from 823b02b to 39cfe01 Compare August 28, 2023 07:59
@davidtwco davidtwco added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 28, 2023
@davidtwco
Copy link
Member

davidtwco commented Aug 28, 2023

There's still lots of discussion and changes happening here, use @rustbot ready when you've got something you're looking to have merged. I mixed this up with one of the other coverage pull requests.

I'll review this once its dependencies land.

@Zalathar Zalathar force-pushed the regions-vec branch 3 times, most recently from 17b3653 to e08eb2e Compare August 29, 2023 03:03
@bors

This comment was marked as resolved.

@Zalathar Zalathar force-pushed the regions-vec branch 2 times, most recently from 594c85c to d280856 Compare August 30, 2023 10:35
@bors

This comment was marked as resolved.

@Zalathar Zalathar force-pushed the regions-vec branch 3 times, most recently from 08cff5b to 36c1667 Compare October 2, 2023 02:06
There is no need to include a dummy counter reference in the coverage mappings
for an unused function.
By encapsulating the coverage spans in a struct, we can change the internal
representation without disturbing existing call sites. This will be useful for
grouping coverage spans by BCB.

This patch includes some changes that were originally in rust-lang#115912, which avoid
the need for a particular test to deal with coverage spans at all.

(Comments/logs referring to `CoverageSpan` are updated in a subsequent patch.)
The concrete type `CoverageSpan` is no longer used outside of the `spans`
module.

This is a separate patch to avoid noise in the preceding patch that actually
encapsulates coverage spans.
This makes it possible for a `StatementKind::Coverage` to hold more than one
code region, but that capability is not yet used.
If a BCB has more than one code region, those extra regions can now all be
stored in the same coverage statement, instead of being stored in additional
statements.
Now that coverage statements can have multiple code regions attached to them,
this code is never used.
When these methods were originally written, I wasn't aware that
`newtype_index!` already supports addition with ordinary numbers, without
needing to unwrap and re-wrap.
Copy link
Member

@davidtwco davidtwco left a comment

Choose a reason for hiding this comment

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

Apologies for the delay in getting to this, looks good to me.

@davidtwco
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Oct 3, 2023

📌 Commit 053c4f9 has been approved by davidtwco

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 Oct 3, 2023
@bors
Copy link
Contributor

bors commented Oct 3, 2023

⌛ Testing commit 053c4f9 with merge 36aab8d...

@bors
Copy link
Contributor

bors commented Oct 3, 2023

☀️ Test successful - checks-actions
Approved by: davidtwco
Pushing 36aab8d to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 3, 2023
@bors bors merged commit 36aab8d into rust-lang:master Oct 3, 2023
@rustbot rustbot added this to the 1.75.0 milestone Oct 3, 2023
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (36aab8d): comparison URL.

Overall result: ✅ improvements - no action needed

@rustbot label: -perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.7% [-0.7%, -0.6%] 4
Improvements ✅
(secondary)
-0.4% [-0.6%, -0.2%] 15
All ❌✅ (primary) -0.7% [-0.7%, -0.6%] 4

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)
1.1% [1.1%, 1.1%] 1
Improvements ✅
(primary)
-0.8% [-0.8%, -0.8%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.8% [-0.8%, -0.8%] 1

Cycles

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

Binary size

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

Bootstrap: 622.003s -> 621.563s (-0.07%)
Artifact size: 272.02 MiB -> 272.01 MiB (-0.00%)

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.

7 participants