-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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: Initial support for branch coverage instrumentation #122322
Conversation
r? @nnethercote rustbot has assigned @nnethercote. Use r? to explicitly pick a reviewer |
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred in match lowering cc @Nadrieril |
The changes that are most important in terms of reviewer attention are the alterations to non-coverage-specific code in (Whereas the coverage-specific modules are mostly self-contained, so there's less impact on the rest of the compiler.) |
Made some style improvements to |
@@ -837,7 +842,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | |||
self.fn_span, | |||
self.coroutine, | |||
None, | |||
) | |||
); | |||
body.coverage_hir_branch_info = self.coverage_branch_info.and_then(|b| b.into_done()); |
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.
Here I had a choice between two ways to set this field:
- Add an extra parameter to
Body::new
, andNone
to a half-dozen callers that don't care. - Leave the constructor as-is, and do an explicit field write in the one caller that does care.
I think I prefer the explicit write, as shown here.
I skimmed through this and it looks reasonable and is well-commented, and I like that you added the test first so the changes to it are clear later on. But I know very little about MIR and so am not a good reviewer for this. According to r? @oli-obk |
#122226 has been approved, so once that lands I'll rebase this and make the necessary adjustments. |
…hercote coverage: Remove or migrate all unstable values of `-Cinstrument-coverage` (This PR was substantially overhauled from its original version, which migrated all of the existing unstable values intact.) This PR takes the three nightly-only values that are currently accepted by `-Cinstrument-coverage`, completely removes two of them (`except-unused-functions` and `except-unused-generics`), and migrates the third (`branch`) over to a newly-introduced unstable flag `-Zcoverage-options`. I have a few motivations for wanting to do this: - It's unclear whether anyone actually uses the `except-unused-*` values, so this serves as an opportunity to either remove them, or prompt existing users to object to their removal. - After rust-lang#117199, the stable values of `-Cinstrument-coverage` treat it as a boolean-valued flag, so having nightly-only extra values feels out-of-place. - Nightly-only values also require extra ad-hoc code to make sure they aren't accidentally exposed to stable users. - The new system allows multiple different settings to be toggled independently, which isn't possible in the current single-value system. - The new system makes it easier to introduce new behaviour behind an unstable toggle, and then gather nightly-user feedback before possibly making it the default behaviour for all users. - The new system also gives us a convenient place to put relatively-narrow options that won't ever be the default, but that nightly users might still want access to. - It's likely that we will eventually want to give stable users more fine-grained control over coverage instrumentation. The new flag serves as a prototype of what that stable UI might eventually look like. The `branch` option is a placeholder that currently does nothing. It will be used by rust-lang#122322 to opt into branch coverage instrumentation. --- I see `-Zcoverage-options` as something that will exist more-or-less indefinitely, though individual sub-options might come and go as appropriate. I think there will always be some demand for nightly-only toggles, so I don't see `-Zcoverage-options` itself ever being stable, though we might eventually stabilize something similar to it.
…hercote coverage: Remove or migrate all unstable values of `-Cinstrument-coverage` (This PR was substantially overhauled from its original version, which migrated all of the existing unstable values intact.) This PR takes the three nightly-only values that are currently accepted by `-Cinstrument-coverage`, completely removes two of them (`except-unused-functions` and `except-unused-generics`), and migrates the third (`branch`) over to a newly-introduced unstable flag `-Zcoverage-options`. I have a few motivations for wanting to do this: - It's unclear whether anyone actually uses the `except-unused-*` values, so this serves as an opportunity to either remove them, or prompt existing users to object to their removal. - After rust-lang#117199, the stable values of `-Cinstrument-coverage` treat it as a boolean-valued flag, so having nightly-only extra values feels out-of-place. - Nightly-only values also require extra ad-hoc code to make sure they aren't accidentally exposed to stable users. - The new system allows multiple different settings to be toggled independently, which isn't possible in the current single-value system. - The new system makes it easier to introduce new behaviour behind an unstable toggle, and then gather nightly-user feedback before possibly making it the default behaviour for all users. - The new system also gives us a convenient place to put relatively-narrow options that won't ever be the default, but that nightly users might still want access to. - It's likely that we will eventually want to give stable users more fine-grained control over coverage instrumentation. The new flag serves as a prototype of what that stable UI might eventually look like. The `branch` option is a placeholder that currently does nothing. It will be used by rust-lang#122322 to opt into branch coverage instrumentation. --- I see `-Zcoverage-options` as something that will exist more-or-less indefinitely, though individual sub-options might come and go as appropriate. I think there will always be some demand for nightly-only toggles, so I don't see `-Zcoverage-options` itself ever being stable, though we might eventually stabilize something similar to it.
Rollup merge of rust-lang#122226 - Zalathar:zcoverage-options, r=nnethercote coverage: Remove or migrate all unstable values of `-Cinstrument-coverage` (This PR was substantially overhauled from its original version, which migrated all of the existing unstable values intact.) This PR takes the three nightly-only values that are currently accepted by `-Cinstrument-coverage`, completely removes two of them (`except-unused-functions` and `except-unused-generics`), and migrates the third (`branch`) over to a newly-introduced unstable flag `-Zcoverage-options`. I have a few motivations for wanting to do this: - It's unclear whether anyone actually uses the `except-unused-*` values, so this serves as an opportunity to either remove them, or prompt existing users to object to their removal. - After rust-lang#117199, the stable values of `-Cinstrument-coverage` treat it as a boolean-valued flag, so having nightly-only extra values feels out-of-place. - Nightly-only values also require extra ad-hoc code to make sure they aren't accidentally exposed to stable users. - The new system allows multiple different settings to be toggled independently, which isn't possible in the current single-value system. - The new system makes it easier to introduce new behaviour behind an unstable toggle, and then gather nightly-user feedback before possibly making it the default behaviour for all users. - The new system also gives us a convenient place to put relatively-narrow options that won't ever be the default, but that nightly users might still want access to. - It's likely that we will eventually want to give stable users more fine-grained control over coverage instrumentation. The new flag serves as a prototype of what that stable UI might eventually look like. The `branch` option is a placeholder that currently does nothing. It will be used by rust-lang#122322 to opt into branch coverage instrumentation. --- I see `-Zcoverage-options` as something that will exist more-or-less indefinitely, though individual sub-options might come and go as appropriate. I think there will always be some demand for nightly-only toggles, so I don't see `-Zcoverage-options` itself ever being stable, though we might eventually stabilize something similar to it.
This will allow MIR building to check whether a function is eligible for coverage instrumentation, and avoid collecting branch coverage info if it is not.
I've rebased and updated the tests for #122226, EDIT: Updates should be complete now. |
1085c76
to
a043c19
Compare
Shortened some identifiers, mostly by removing “hir” from them (diff). |
@bors r+ rollup |
…iaskrgr Rollup of 10 pull requests Successful merges: - rust-lang#117118 ([AIX] Remove AixLinker's debuginfo() implementation) - rust-lang#121650 (change std::process to drop supplementary groups based on CAP_SETGID) - rust-lang#121764 (Make incremental sessions identity no longer depend on the crate names provided by source code) - rust-lang#122212 (Copy byval argument to alloca if alignment is insufficient) - rust-lang#122322 (coverage: Initial support for branch coverage instrumentation) - rust-lang#122373 (Fix the conflict problem between the diagnostics fixes of lint `unnecessary_qualification` and `unused_imports`) - rust-lang#122479 (Implement `Duration::as_millis_{f64,f32}`) - rust-lang#122487 (Rename `StmtKind::Local` variant into `StmtKind::Let`) - rust-lang#122498 (Update version of cc crate) - rust-lang#122503 (Make `SubdiagMessageOp` well-formed) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 10 pull requests Successful merges: - rust-lang#117118 ([AIX] Remove AixLinker's debuginfo() implementation) - rust-lang#121650 (change std::process to drop supplementary groups based on CAP_SETGID) - rust-lang#121764 (Make incremental sessions identity no longer depend on the crate names provided by source code) - rust-lang#122212 (Copy byval argument to alloca if alignment is insufficient) - rust-lang#122322 (coverage: Initial support for branch coverage instrumentation) - rust-lang#122373 (Fix the conflict problem between the diagnostics fixes of lint `unnecessary_qualification` and `unused_imports`) - rust-lang#122479 (Implement `Duration::as_millis_{f64,f32}`) - rust-lang#122487 (Rename `StmtKind::Local` variant into `StmtKind::Let`) - rust-lang#122498 (Update version of cc crate) - rust-lang#122503 (Make `SubdiagMessageOp` well-formed) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#122322 - Zalathar:branch, r=oli-obk coverage: Initial support for branch coverage instrumentation (This is a review-ready version of the changes that were drafted in rust-lang#118305.) This PR adds support for branch coverage instrumentation, gated behind the unstable flag value `-Zcoverage-options=branch`. (Coverage instrumentation must also be enabled with `-Cinstrument-coverage`.) During THIR-to-MIR lowering (MIR building), if branch coverage is enabled, we collect additional information about branch conditions and their corresponding then/else blocks. We inject special marker statements into those blocks, so that the `InstrumentCoverage` MIR pass can reliably identify them even after the initially-built MIR has been simplified and renumbered. The rest of the changes are mostly just plumbing needed to gather up the information that was collected during MIR building, and include it in the coverage metadata that we embed in the final binary. Note that `llvm-cov show` doesn't print branch coverage information in its source views by default; that needs to be explicitly enabled with `--show-branches=count` or similar. --- The current implementation doesn't have any support for instrumenting `if let` or let-chains. I think it's still useful without that, and adding it would be non-trivial, so I'm happy to leave that for future work.
(This is a review-ready version of the changes that were drafted in #118305.)
This PR adds support for branch coverage instrumentation, gated behind the unstable flag value
-Zcoverage-options=branch
. (Coverage instrumentation must also be enabled with-Cinstrument-coverage
.)During THIR-to-MIR lowering (MIR building), if branch coverage is enabled, we collect additional information about branch conditions and their corresponding then/else blocks. We inject special marker statements into those blocks, so that the
InstrumentCoverage
MIR pass can reliably identify them even after the initially-built MIR has been simplified and renumbered.The rest of the changes are mostly just plumbing needed to gather up the information that was collected during MIR building, and include it in the coverage metadata that we embed in the final binary.
Note that
llvm-cov show
doesn't print branch coverage information in its source views by default; that needs to be explicitly enabled with--show-branches=count
or similar.The current implementation doesn't have any support for instrumenting
if let
or let-chains. I think it's still useful without that, and adding it would be non-trivial, so I'm happy to leave that for future work.