about summary refs log tree commit diff
path: root/src/librustc_mir/transform/instrument_coverage.rs
AgeCommit message (Collapse)AuthorLines
2020-08-30mv compiler to compiler/mark-247/+0
2020-08-18Moved coverage counter injection from BasicBlock to Statement.Rich Kadel-279/+99
2020-08-14LLVM IR coverage encoding aligns closer to Clang'sRich Kadel-0/+15
I found some areas for improvement while attempting to debug the SegFault issue when running rust programs compiled using MSVC, with coverage instrumentation. I discovered that LLVM's coverage writer was generating incomplete function name variable names (that's not a typo: the name of the variable that holds a function name). The existing implementation used one-up numbers to distinguish variables, and correcting the names did not fix the MSVC coverage bug, but the fix in this PR makes the names and resulting LLVM IR easier to follow and more consistent with Clang's implementation. I also changed the way the `-Zinstrument-coverage` option is supported in symbol_export.rs. The original implementation was incorrect, and the corrected version matches the handling for `-Zprofile-generate`, as it turns out. (An argument could be made that maybe `-Zinstrument-coverage` should automatically enable `-Cprofile-generate`. In fact, if `-Cprofile-generate` is analagous to Clang's `-fprofile-generate`, as some documentation implies, Clang always requires this flag for its implementation of source-based code coverage. This would require a little more validation, and if implemented, would probably require updating some of the user-facing messages related to `-Cprofile-generate` to not be so specific to the PGO use case.) None of these changes fixed the MSVC coverage problems, but they should still be welcome improvements. Lastly, I added some additional FIXME comments in instrument_coverage.rs describing issues I found with the generated LLVM IR that would be resolved if the coverage instrumentation is injected with a `Statement` instead of as a new `BasicBlock`. I describe seven advantages of this change, but it requires some discussion before making a change like this.
2020-08-04Completes support for coverage in external cratesRich Kadel-33/+61
The prior PR corrected for errors encountered when trying to generate the coverage map on source code inlined from external crates (including macros and generics) by avoiding adding external DefIds to the coverage map. This made it possible to generate a coverage report including external crates, but the external crate coverage was incomplete (did not include coverage for the DefIds that were eliminated. The root issue was that the coverage map was converting Span locations to source file and locations, using the SourceMap for the current crate, and this would not work for spans from external crates (compliled with a different SourceMap). The solution was to convert the Spans to filename and location during MIR generation instead, so precompiled external crates would already have the correct source code locations embedded in their MIR, when imported into another crate.
2020-07-28Refactor MIR coverage instrumentationRich Kadel-79/+105
Lays a better foundation for injecting more counters in each function.
2020-07-25Fixed coverage map issues; better aligned with LLVM APIsRich Kadel-6/+6
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.
2020-07-17Generating the coverage mapRich Kadel-56/+204
rustc now generates the coverage map and can support (limited) coverage report generation, at the function level. Example: $ BUILD=$HOME/rust/build/x86_64-unknown-linux-gnu $ $BUILD/stage1/bin/rustc -Zinstrument-coverage \ $HOME/rust/src/test/run-make-fulldeps/instrument-coverage/main.rs $ LLVM_PROFILE_FILE="main.profraw" ./main called $ $BUILD/llvm/bin/llvm-profdata merge -sparse main.profraw -o main.profdata $ $BUILD/llvm/bin/llvm-cov show --instr-profile=main.profdata main 1| 1|pub fn will_be_called() { 2| 1| println!("called"); 3| 1|} 4| | 5| 0|pub fn will_not_be_called() { 6| 0| println!("should not have been called"); 7| 0|} 8| | 9| 1|fn main() { 10| 1| let less = 1; 11| 1| let more = 100; 12| 1| 13| 1| if less < more { 14| 1| will_be_called(); 15| 1| } else { 16| 1| will_not_be_called(); 17| 1| } 18| 1|}
2020-07-05Use for<'tcx> fn pointers in Providers, instead of having Providers<'tcx>.Eduard-Mihai Burtescu-1/+1
2020-06-29add spans to injected coverage countersRich Kadel-55/+72
added regions with counter expressions and counters. Added codegen_llvm/coverageinfo mod for upcoming coverage map Move coverage region collection to CodegenCx finalization Moved from `query coverageinfo` (renamed from `query coverage_data`), as discussed in the PR at: https://github.com/rust-lang/rust/pull/73684#issuecomment-649882503 Address merge conflict in MIR instrument_coverage test The MIR test output format changed for int types. moved debug messages out of block.rs This makes the block.rs calls to add coverage mapping data to the CodegenCx much more concise and readable. move coverage intrinsic handling into llvm impl I realized that having half of the coverage intrinsic handling in `rustc_codegen_ssa` and half in `rustc_codegen_llvm` meant that any non-llvm backend would be bound to the same decisions about how the coverage-related MIR terminators should be handled. To fix this, I moved the non-codegen portion of coverage intrinsic handling into its own trait, and implemented it in `rustc_codegen_llvm` alongside `codegen_intrinsic_call`. I also added the (required?) stubs for the new intrinsics to `IntrepretCx::emulate_intrinsic()`, to ensure calls to this function do not fail if called with these new but known intrinsics. address PR Feedback on 28 June 2020 2:48pm PDT
2020-06-22Updated query for num_counters to compute from max indexRich Kadel-4/+24
Also added FIXME comments to note the possible need to accommodate counter increment calls in source-based functions that differ from the function context of the caller instance (e.g., inline functions).
2020-06-22using "mir_body" (vs "body") in InstrumentCoverageRich Kadel-2/+2
The mod uses both MIR bodies and HIR bodies, so I'm trying to maintain consistency with these names.
2020-06-22moves coverage data computation from pass to queryRich Kadel-23/+35
2020-06-22Address remaining feedback itemsRich Kadel-25/+2
2020-06-21num_counters to u32, after implementing TypeFoldableRich Kadel-3/+3
2020-06-19code coverage foundation for hash and num_countersRich Kadel-52/+144
Replaced dummy values for hash and num_counters with computed values, and refactored InstrumentCoverage pass to simplify injecting more counters per function in upcoming versions. Improved usage documentation and error messaging.
2020-06-15Add new `fn_span` to TerminatorKind::Call instanceRich Kadel-0/+1
2020-06-15added test, Operand::const_from_scalar, require_lang_item, & commentsRich Kadel-37/+15
Addresses feedback from @oli-obk (Thanks!)
2020-06-15moved instrument_coverage pass, optimized scalar, added FIXMERich Kadel-9/+18
2020-06-15moved to post_borrowck_cleanup & used MirPatchRich Kadel-54/+58
2020-06-15[WIP] injects llvm intrinsic instrprof.increment for coverage reportsRich Kadel-0/+100
This initial version only injects counters at the top of each function. Rust Coverage will require injecting additional counters at each conditional code branch.