-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
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.) |
debug!( | ||
"adding counter to coverage_map: instance={:?}, id={:?}, region={:?}", | ||
instance, id, code_region, | ||
); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
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.
08cff5b
to
36c1667
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.
There was a problem hiding this 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.
@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::Counter
only 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.