-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Fixed coverage map issues; better aligned with LLVM APIs #74733
Conversation
I have more to upload, but I'm going to do separate PRs for the recent changes I've made to add more counters based on MIR branching. |
e4cf98d
to
a7053dc
Compare
Found some problems with the coverage map encoding when testing with more than one counter per function. While debugging, I realized some better ways to structure the Rust implementation of the coverage mapping generator. I refactored somewhat, resulting in less code overall, expanded coverage of LLVM Coverage Map capabilities, and much closer alignment with LLVM data structures, APIs, and naming. This should be easier to follow and easier to maintain.
a7053dc
to
12ddd60
Compare
r? @tmandry |
@tmandry As discussed, I just added a second commit covering the recent refactoring of MIR pass in instrument_coverage.rs. This PR had no effect on the I'll submit a "WIP"/draft PR separately, with the changes we reviewed, injecting counters before each BasicBlock. I have to regenerate the test expected results for that one. |
a5c2c04
to
fa86fc4
Compare
Interesting side note... The format check failed, even though I had run I had copied a snapshot of the
I had to delete |
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.
Left a few small comments
Lays a better foundation for injecting more counters in each function.
fa86fc4
to
b58afc0
Compare
I responded to all but one of the feedback comments (if a change was needed) in 20f55c1, but I pushed a separate commit b58afc0 with changes to use |
Some were in librustc_codegen_llvm, but others are not tied to LLVM, so I put them in a new crate: librustc_codegen_ssa/coverageinfo/ffi.rs
18518ae
to
5b2e2b2
Compare
I think this is ready to merge. |
📌 Commit 5b2e2b2 has been approved by |
☀️ Test successful - checks-actions, checks-azure |
@wesleywiser @tmandry FYI - In this version of Rust Coverage, I intentionally reintroduced the "assert_eq" that the start and end of a code region are from the same file. I know this breaks when attempting to compile larger crates with dependencies, but to ignore the problem simply produced bad results. The good news is, I found a way to fix the problem, and I'm getting clean coverage and code regions across both local and external crates now, when I compile a crate with dependencies! I'm going to push a small PR tomorrow with this fix. I mentioned this to Tyler tonight as well: I know the fix works better and produces clean results. I'm not 100% sure it is producing complete results yet. After I post the new PR so you can see what I'm doing, I'll explain the new solution, why I think it works, and what I'm not sure is covered. (I'm sure I can create some tests to confirm things, either way.) |
@richkadel By the way, thanks for splitting this work up into lots of PRs! I'm sure it would probably be easier for you to just iterate on the code and dump it over the fence but doing it this way makes reviewing it much more manageable. When you have this a bit closer to working (which sounds like it may be very soon!), we might want to think about adding a lot more tests both to ensure things are working correctly and to make sure they keep working correctly in the future. |
@wesleywiser On the subject of tests, since testing the end product requires building and then running a binary, and then running llvm tools, plus the Generating the Do you think it would be reasonable for me to update the test framework to allow I would use this if it existed. |
@richkadel That seems fine to me. I don't think I've ever touched those tests but I think in general, we'd like to see Full integration tests would be great but I'd also like to see more |
I completely agree. My first paragraph was poorly worded. I definitely plan to include a lot more mir-opt tests as well. |
…r=tmandry Rust function-level coverage now works on external crates Follow-up to a known issue discussed (post-merge) in rust-lang#74733: Resolves a known issue in the coverage map where some regions had nonsensical source code locations. External crate functions are already included in their own coverage maps, per library, and don't need to also be added to the importing crate's coverage map. (In fact, their source start and end byte positions are not relevant to the importing crate's SourceMap.) The fix was to simply skip trying to add imported coverage info to the coverage map if the instrumented function is not "local". The injected counters are still relevant, however, and the LLVM `instrprof.increment` intrinsic call parameters will map those counters to the external crates' coverage maps, when generating runtime coverage data. Now Rust Coverage can cleanly instrument and analyze coverage on an entire crate and its dependencies. Example (instrumenting https://github.com/google/json5format): ```bash $ ./x.py build rust-demangler # make sure the demangler is built $ cd ~/json5format $ RUSTC=$HOME/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc \ RUSTFLAGS="-Zinstrument-coverage" \ cargo build --example formatjson5 $ LLVM_PROFILE_FILE="formatjson5.profraw" \ ./target/debug/examples/formatjson5 session_manager.cml $ ~/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-profdata merge \ -sparse formatjson5.profraw -o formatjson5.profdata $ ~/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show --use-color \ --instr-profile=formatjson5.profdata target/debug/examples/formatjson5 \ --show-line-counts-or-regions \ --Xdemangler=$HOME/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler \ --show-instantiations \ 2>&1 | less -R ``` (Scan forward for some of the non-zero coverage results, with `/^....[0-9]\| *[^ |0]`.) <img width="1071" alt="Screen Shot 2020-07-30 at 1 21 01 PM" src="https://user-images.githubusercontent.com/3827298/88970627-97e43000-d267-11ea-8e4d-fe40a091f756.png">
Found some problems with the coverage map encoding when testing with more than one counter per function.
While debugging, I realized some better ways to structure the Rust implementation of the coverage mapping generator. I refactored somewhat, resulting in less code overall, expanded coverage of LLVM Coverage Map capabilities, and much closer alignment with LLVM data structures, APIs, and naming.
This should be easier to follow and easier to maintain.
r? @tmandry
Rust compiler MCP rust-lang/compiler-team#278
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation