coverage: Allow each coverage statement to have multiple code regions#115301
coverage: Allow each coverage statement to have multiple code regions#115301bors merged 7 commits intorust-lang:masterfrom
Conversation
|
r? @davidtwco (rustbot has picked a reviewer for you, use r? to override) |
|
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. This PR changes MIR cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @celinval, @vakaras Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
|
(Cargo.toml changes are part of #114843 and won't remain in the final version of this PR.) |
There was a problem hiding this comment.
These debug! invocations have been replaced with #[instrument(...)] tracing on the methods being called.
There was a problem hiding this comment.
We now call add_counter unconditionally here, and leave the callee to decide how to handle counters with zero code regions.
823b02b to
39cfe01
Compare
|
I'll review this once its dependencies land. |
17b3653 to
e08eb2e
Compare
This comment was marked as resolved.
This comment was marked as resolved.
594c85c to
d280856
Compare
This comment was marked as resolved.
This comment was marked as resolved.
9086c92 to
ef8cfd5
Compare
504dc99 to
cf05f7c
Compare
|
(I've been rebasing this for the benefit of other PRs/patches that rely on it.) |
fc16cbc to
08cff5b
Compare
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.
davidtwco
left a comment
There was a problem hiding this comment.
Apologies for the delay in getting to this, looks good to me.
|
@bors r+ |
|
☀️ Test successful - checks-actions |
|
Finished benchmarking commit (36aab8d): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis 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.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 622.003s -> 621.563s (-0.07%) |
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 fromOption<CodeRegion>toVec<CodeRegion>.The changes on the codegen side are fairly straightforward. As long as each
CoverageKind::Counteronly injects onellvm.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:
So viewing the patches individually may be easier.