-
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
first stage of implementing LLVM code coverage #73011
Conversation
update from upstream
r? @davidtwco (rust_highfive has picked a reviewer for you, use r? to override) |
|
|
@wesleywiser - PTAL. Note that Tyler and I also discussed the possibility of implementing the code generation with a custom Statement (rather than injecting a Call Terminator, as I did in this PR). The Call Terminator allowed me to model the injected intrinsic the way that other intrinsics are handled (with a few important differences). An alternative, suggested by Tyler, would be to define a new, custom StatementKind. Knowing that the My only hesitation is that a new StatementKind for this intrinsic becomes a very special case, different from all other intrinsics, and there may be hidden expectations and assumptions in the compiler that could add unexpected complexity. But, I'm open to this alternative approach if there's a good reason to make that change. Let us know your thoughts. @tmandry - Please feel free to expand on or correct my explanation here. Thank you! |
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.
Looks great! Left a couple comments but otherwise I think this is ready to land.
@bors d+ r=me after comments |
@bors r+ |
📌 Commit 84d4424ff88db00736e940da9443c29ef5911101 has been approved by |
Did not mean to close the PR. The GitHub app on Android has a Pull Request status window with a "Close" button. It looks like that button is how you close the window, but it closes the PR... Ach! |
Please add tests in You'll need to add |
Done |
Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
@bors r+ |
📌 Commit c338729 has been approved by |
@Dylan-DPC - Would you be willing to include this in the next rollup? Thanks! |
Please hold off. We're going to do another bors try with macos and windows tests enabled, to make sure there are no more surprises. |
testing platform-specific changes
2238705
to
b9f0304
Compare
@bors try |
⌛ Trying commit b9f0304 with merge 7e5ef77edd62e7082b227400416e103834f1ef1a... |
|
it's not next on the queue 🤔 it's on "try" which is separate so it won't be merged |
@Dylan-DPC right, I mistook |
☀️ Try build successful - checks-azure |
I removed the "try" config changes (PR passes on all platforms now!). This version should be good to merge, assuming no new merge conflicts. Thanks! |
@bors r+ |
📌 Commit 36c9014 has been approved by |
Rollup of 10 pull requests Successful merges: - rust-lang#72280 (Fix up autoderef when reborrowing) - rust-lang#72785 (linker: MSVC supports linking static libraries as a whole archive) - rust-lang#73011 (first stage of implementing LLVM code coverage) - rust-lang#73044 (compiletest: Add directives to detect sanitizer support) - rust-lang#73054 (memory access sanity checks: abort instead of panic) - rust-lang#73136 (Change how compiler-builtins gets many CGUs) - rust-lang#73280 (Add E0763) - rust-lang#73317 (bootstrap: read config from $RUST_BOOTSTRAP_CONFIG) - rust-lang#73350 (bootstrap/install.rs: support a nonexistent `prefix` in `x.py install`) - rust-lang#73352 (Speed up bootstrap a little.) Failed merges: r? @ghost
…tmandry code coverage foundation for hash and num_counters This PR is the next iteration after PR rust-lang#73011 (which is still waiting on bors to merge). @wesleywiser - PTAL r? @tmandry (FYI, I'm also working on injecting the coverage maps, in another branch, while waiting for these to merge.) Thanks!
…tmandry code coverage foundation for hash and num_counters This PR is the next iteration after PR rust-lang#73011 (which is still waiting on bors to merge). @wesleywiser - PTAL r? @tmandry (FYI, I'm also working on injecting the coverage maps, in another branch, while waiting for these to merge.) Thanks!
@@ -389,6 +389,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |||
); | |||
self.copy_op(self.operand_index(args[0], index)?, dest)?; | |||
} | |||
// FIXME(#73156): Handle source code coverage in const eval | |||
sym::count_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.
Please always ping @rust-lang/wg-const-eval for new intrinsics in CTFE.
It is not great when I realize by mere accident that we have a new intrinsic here. It's just a stub this time, so no big deal, but who knows what it might be next time. ;)
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.
Also, note that as per this comment, T-lang should have been involved as well:
rust/src/libcore/intrinsics.rs
Lines 8 to 9 in 394e1b4
//! Note: any changes to the constness of intrinsics should be discussed with the language team. | |
//! This includes changes in the stability of the constness. |
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.
amusingly this intrinsic is not marked as const at all. The static checks preventing non-const intrinsics from being invoked happen before mir optimizations. Since instrumentation is a MIR transformation... this isn't caught. Maybe instrumentation should happen before const checking and such?
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.
Oh, so this intrinsic is not called by users, but the call is inserted by an instrumentation pass later? Interesting. That reduces my T-lang concern.
Maybe instrumentation should happen before const checking and such?
Maybe -- I am not sure to what extend it would be useful to check the instrumented code as if it was user-written.
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.
If I write
const fn a() -> u8 {
42
}
const A: u8 = a();
fn main() {
println!("{}", A);
}
Then currently a
will contribute towards coverage, yet it is not marked as executed. I think the count_code_region
intrinsic should also mark code as executed during CTFE.
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.
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.
Didn't see that issue, thanks.
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.
Sorry about that @RalfJung! That was my fault; I didn't realize we should be pinging that group. I will try to keep that in mind in the future.
Do you think we still need to get the lang team involved? This intrinsic is used by an unstable -Z
compiler flag which generates code coverage data using LLVM features. The compiler team already signed off on this approach via an MCP.
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.
I doubt they will have any objections, but sending T-lang an "FYI this is what we did here" would still be a good idea I think.
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.
Thanks for flagging the issue @RalfJung ...
Note also, the next PR increment is under review, and adds some additional Rust intrinsics that I believe we need for coverage map generation.
See this related note:
Since the MIR analysis is minimal at the moment (injecting at the function level only) I'm not generating calls to these intrinsics yet, but when I do, I suspect I may need to add these new intrinsics to src/librustc_mir/interpret/intrinsics.rs as well, similarly stubbed out.
This PR replaces #70680 (WIP toward LLVM Code Coverage for Rust) since I am re-implementing the Rust LLVM code coverage feature in a different part of the compiler (in MIR pass(es) vs AST).
This PR updates rustc with
-Zinstrument-coverage
option that injects the llvm intrinsicinstrprof.increment()
for code generation.This initial version only injects counters at the top of each function, and does not yet implement the required coverage map.
Upcoming PRs will add the coverage map, and add more counters and/or counter expressions for each conditional code branch.
Rust compiler MCP rust-lang/compiler-team#278
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
I put together some development notes here, under a separate branch.