-
Notifications
You must be signed in to change notification settings - Fork 69
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
Implement LLVM-compatible source-based code coverage #278
Comments
Tyler, Bob, Please review this submitted version of the MCP and note your approval, if I've captured all of your major comments. Thanks! |
Looks good to me! I reviewed this before @richkadel posted it and he's incorporated my initial feedback. I'd also like to volunteer as a reviewer for this MCP. |
@pnkfelix - For checklist item 4, does the "second" need to come from the Rust compiler team or is @bob-wilson a reasonable candidate since he has experience implementing LLVM coverage in Clang? (If compiler team, please recommend someone, if not yourself. Thanks!) |
I'm really glad to see this moving forward and I think this plan will work. The end goals sound exactly right to me. The approach is a bit more experimental than I would personally choose to take, but maybe I'm biased to go straight to the approach used in Clang and Swift. I'm not too worried about that, though. As long as it ends up with a good design, some early experimentation can't hurt. |
@rust-lang/wg-prioritization please add this proposal to the triage meeting agenda if there are no pending comments. Thanks! |
@pnkfelix @Centril - The mention "@rust-lang/wg-prioritization" above is not in bold text, like mentioning usernames. I'm not sure this actually "pings" the group (per the checklist instructions). Am I supposed to "ping" in some other way? (I added a comment to the document on MCP process regarding this confusion as well.) |
@richkadel thanks for the heads up. You do not need to worry about whether this proposal will get added to the agenda; the rustbot added the |
(i have not yet resolved why @richkadel 's attempts to reference @rust-lang/wg-prioritization do not end up as proper references to that wg's github identity.) |
FYI, I get a 404 page when I click on the highlighted link to wg-prioritization in your comment. It doesn't appear to be visible to me. |
IIRC, you must be a member of a group to at-mention it (to avoid abuse). |
(I do think the "second" is meant to come from the compiler team. The intent there, if I remember correctly, is to ensure that we have at least one person on the compiler team who is more than merely lukewarm about a proposed feature.) |
Thanks for the clarification @pnkfelix ! I removed the check. Can you recommend someone to be a "second" (if not yourself)? |
@wesleywiser - Thanks so much for ❤️-ing the MCP! Would you be willing to confirm the MCP is worthwhile pursuing, and allow me to count you as the "second" (checkbox 4 at the top)? Thanks for considering! |
Hi @richkadel! I'm really excited to see this proposal move forward! I've used code coverage tools in other languages before and the value you can get from high-quality implementations is really quite large. However, I'm not very familiar with the frontend part of My bad for not reading the *bold text* at the top of the issueIf you don't mind, I do have a few questions from a detailed reading of your proposal, the PR and the related issues:
Thanks @Mark-Simulacrum for the message. @richkadel I've copied my questions to the Zulip thread 🙂 |
Just as a note, it would be amazing to take the detailed technical discussion to the Zulip stream, and only post high level summaries here. The intent is to minimize traffic on this repository, so that compiler team members can reasonably subscribe without following the details of any given proposal, and then read the backscroll in Zulip as needed. Also, feel free to create dedicated topics in Zulip in the major changes stream, the primary one is just the starting point :) |
Hi @spastorino - Can you please clarify why you removed the to-announce label? This MCP is supposed to be announced at the triage meeting today. |
@Mark-Simulacrum - Thanks for highlighting that technical discussion goes to the zulip stream for this MCP (https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Implement.20LLVM-compatible.20source-based.20cod.20compiler-team.23278) @wesleywiser - I'll paste each of your question/comments there and respond to them. Thanks! |
Answering my own question: It looks like this MCP was announced in today's weekly meeting (woohoo!): I assume this starts the "1-week" clock, and await the "mcp-accepted" label. Thankyou @wesleywiser for raising the need for the "second". Process note (FYI @nikomatsakis ): I had hoped one outcome of the meeting and announcement would have been to resolve the issue of a need for a "second". (Should the compiler team have any obligation to follow up on requests for a reviewer or second?) I would assume there is at least one person on the compiler team that is (to quote @pnkfelix ) "more than merely lukewarm" about enabling code coverage in Rust. Please let me know if there is anything else that I should do to help wrap this up. Thanks! |
There was some good feedback on the design in the Zulip topic. I think we should incorporate it and try to clear up any major concerns as best we can before diving in. In particular, I think we should have general agreement on (roughly) what stage the instrumentation pass should go in. (That said, experimental implementation work focused on answering this question would be productive and useful.) I'm saying all this with the assumption that we do want source-level coverage support in rustc, given an agreeable design and implementation. This is based on a lot of the discussion in rust-lang/rust#34701 and especially our prior experience trying to implement coverage tooling using the current GCOV-based support. Though I realize now that there aren't a lot of current compiler team members that were involved in these discussions. For anyone on t-compiler following along, do you already agree with this general statement, or are you unsure / lacking context? (Does anyone disagree?) The MCP can be doing more to explain the motivation, but it'd be nice to have an idea of where people stand right now. |
Just to be clear: Without a "second", I don't think the 1-week clock has started yet. (Otherwise, you could get into a situation where people may not be looking carefully at this since the people might assume, in the absence of a "second", that there isn't enough support for the MCP to move forward, and therefore its not worth taking the time to raise formal concerns.) |
@pnkfelix @wesleywiser @bjorn3 @tmandry @WG-mir-opt tl;dr - I've updated the MCP to prioritize the approach recommended by (eddyb) in the Zulip thread. Please identify a member of your team who is willing to "second" the MCP, or let me know what I need to do to gain your approval. Thanks! I just want to make sure you are aware that I just updated the MCP to reflect the conversations in the Zulip thread and a strong recommendation to implement coverage as a MIR pass, which I am now attempting. I also trimmed out some of the discussion that was too focused on the initial prototype, not necessarily related to the now preferred approach. @tmandry gave me a quick overview of the MIR implementation and the CFG. I now have some idea how to implement a MIR->MIR pass, and I see the benefits. As you know, there has been some skepticism of the viability of the MIR->MIR approach, for various reasons, but I'm optimistic it can be done, and the updated MCP now reflects this is the recommended approach. If for some reason the MIR->MIR implementation doesn't work well, I have fallback approaches that I know will work, based on my initial prototyping. Thanks! |
@rustbot second The updated proposal looks to be inline with how I would expect to see this implemented. As a MIR pass, it also seems to me that this feature will be fairly isolated and not significantly impact the rest of the compiler. |
Similar to `-Z dump-mir-graphviz`, this adds the option to write HTML+CSS files that allow users to analyze the spans associated with MIR elements (by individual statement, just terminator, or overall basic block). This PR was split out from PR rust-lang#76004, and exposes an API for spanview HTML+CSS files that is also used to analyze code regions chosen for coverage instrumentation (in a follow-on PR). Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: rust-lang#34701 - Implement support for LLVMs code coverage instrumentation
…5.1, r=wesleywiser Add new `-Z dump-mir-spanview` option Similar to `-Z dump-mir-graphviz`, this adds the option to write HTML+CSS files that allow users to analyze the spans associated with MIR elements (by individual statement, just terminator, or overall basic block). This PR was split out from PR rust-lang#76004, and exposes an API for spanview HTML+CSS files that is also used to analyze code regions chosen for coverage instrumentation (in a follow-on PR). Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: rust-lang#34701 - Implement support for LLVMs code coverage instrumentation r? @tmandry FYI @wesleywiser
Adds a new mir_dump output file in HTML/CSS to visualize code regions and the MIR features that they came from (including overlapping spans). See example below: Includes a basic, MIR-block-based implementation of coverage injection, available via `-Zexperimental-coverage`. This implementation has known flaws and omissions, but is simple enough to validate the new tools and tests. The existing `-Zinstrument-coverage` option currently enables function-level coverage only, which at least appears to generate accurate coverage reports at that level. Experimental coverage is not accurate at this time. When branch coverage works as intended, the `-Zexperimental-coverage` option should be removed. This PR replaces the bulk of PR rust-lang#75828, with the remaining parts of that PR distributed among other separate and indentpent PRs. This PR depends on three of those other PRs: rust-lang#76000, rust-lang#76002, and Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: rust-lang#34701 - Implement support for LLVMs code coverage instrumentation ![Screen-Recording-2020-08-21-at-2](https://user-images.githubusercontent.com/3827298/90972923-ff417880-e4d1-11ea-92bb-8713c6198f6d.gif)
… r=tmandry Tools, tests, and experimenting with MIR-derived coverage counters Leverages the new mir_dump output file in HTML+CSS (from rust-lang#76074) to visualize coverage code regions and the MIR features that they came from (including overlapping spans). See example below. The `run-make-fulldeps/instrument-coverage` test has been refactored to maximize test coverage and reduce code duplication. The new tests support testing with and without `-Clink-dead-code`, so Rust coverage can be tested on MSVC (which, currently, only works with `link-dead-code` _disabled_). New tests validate coverage region generation and coverage reports with multiple counters per function. Starting with a simple `if-else` branch tests, coverage tests for each additional syntax type can be added by simply dropping in a new Rust sample program. Includes a basic, MIR-block-based implementation of coverage injection, available via `-Zexperimental-coverage`. This implementation has known flaws and omissions, but is simple enough to validate the new tools and tests. The existing `-Zinstrument-coverage` option currently enables function-level coverage only, which at least appears to generate accurate coverage reports at that level. Experimental coverage is not accurate at this time. When branch coverage works as intended, the `-Zexperimental-coverage` option should be removed. This PR replaces the bulk of PR rust-lang#75828, with the remaining parts of that PR distributed among other separate and indentpent PRs. This PR depends on two of those other PRs: rust-lang#76002, rust-lang#76003 and rust-lang#76074 Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: rust-lang#34701 - Implement support for LLVMs code coverage instrumentation ![Screen-Recording-2020-08-21-at-2](https://user-images.githubusercontent.com/3827298/90972923-ff417880-e4d1-11ea-92bb-8713c6198f6d.gif) r? @tmandry FYI: @wesleywiser
FYI: As of PR rust-lang/rust#78267, LLVM InstrProf-based code coverage is "feature complete"! (I believe this last PR will be in the Rust Usage is now documented in The Rust Unstable Book. |
That's great news! Thank you for your work on this, Rich |
I've implemented support for source-based code coverage in grcov, and used it to collect coverage for grcov itself. @richkadel want me to file an issue with STRs? |
Thanks for testing Marco! It will be helpful to have a separate issue with reproducible example. Definitely sounds unexpected so it will be good to track this down. |
Ok, I've filed rust-lang/rust#79456. |
…overage, r=wesleywiser Stabilize `-Z instrument-coverage` as `-C instrument-coverage` (Tracking issue for `instrument-coverage`: rust-lang#79121) This PR stabilizes support for instrumentation-based code coverage, previously provided via the `-Z instrument-coverage` option. (Continue supporting `-Z instrument-coverage` for compatibility for now, but show a deprecation warning for it.) Many, many people have tested this support, and there are numerous reports of it working as expected. Move the documentation from the unstable book to stable rustc documentation. Update uses and documentation to use the `-C` option. Addressing questions raised in the tracking issue: > If/when stabilized, will the compiler flag be updated to -C instrument-coverage? (If so, the -Z variant could also be supported for some time, to ease migrations for existing users and scripts.) This stabilization PR updates the option to `-C` and keeps the `-Z` variant to ease migration. > The Rust coverage implementation depends on (and automatically turns on) -Z symbol-mangling-version=v0. Will stabilizing this feature depend on stabilizing v0 symbol-mangling first? If so, what is the current status and timeline? This stabilization PR depends on rust-lang#90128 , which stabilizes `-C symbol-mangling-version=v0` (but does not change the default symbol-mangling-version). > The Rust coverage implementation implements the latest version of LLVM's Coverage Mapping Format (version 4), which forces a dependency on LLVM 11 or later. A compiler error is generated if attempting to compile with coverage, and using an older version of LLVM. Given that LLVM 13 has now been released, requiring LLVM 11 for coverage support seems like a reasonable requirement. If people don't have at least LLVM 11, nothing else breaks; they just can't use coverage support. Given that coverage support currently requires a nightly compiler and LLVM 11 or newer, allowing it on a stable compiler built with LLVM 11 or newer seems like an improvement. The [tracking issue](rust-lang#79121) and the [issue label A-code-coverage](https://github.com/rust-lang/rust/labels/A-code-coverage) link to a few open issues related to `instrument-coverage`, but none of them seem like showstoppers. All of them seem like improvements and refinements we can make after stabilization. The original `-Z instrument-coverage` support went through a compiler-team MCP at rust-lang/compiler-team#278 . Based on that, `@pnkfelix` suggested that this needed a stabilization PR and a compiler-team FCP.
…overage, r=wesleywiser Stabilize `-Z instrument-coverage` as `-C instrument-coverage` (Tracking issue for `instrument-coverage`: rust-lang#79121) This PR stabilizes support for instrumentation-based code coverage, previously provided via the `-Z instrument-coverage` option. (Continue supporting `-Z instrument-coverage` for compatibility for now, but show a deprecation warning for it.) Many, many people have tested this support, and there are numerous reports of it working as expected. Move the documentation from the unstable book to stable rustc documentation. Update uses and documentation to use the `-C` option. Addressing questions raised in the tracking issue: > If/when stabilized, will the compiler flag be updated to -C instrument-coverage? (If so, the -Z variant could also be supported for some time, to ease migrations for existing users and scripts.) This stabilization PR updates the option to `-C` and keeps the `-Z` variant to ease migration. > The Rust coverage implementation depends on (and automatically turns on) -Z symbol-mangling-version=v0. Will stabilizing this feature depend on stabilizing v0 symbol-mangling first? If so, what is the current status and timeline? This stabilization PR depends on rust-lang#90128 , which stabilizes `-C symbol-mangling-version=v0` (but does not change the default symbol-mangling-version). > The Rust coverage implementation implements the latest version of LLVM's Coverage Mapping Format (version 4), which forces a dependency on LLVM 11 or later. A compiler error is generated if attempting to compile with coverage, and using an older version of LLVM. Given that LLVM 13 has now been released, requiring LLVM 11 for coverage support seems like a reasonable requirement. If people don't have at least LLVM 11, nothing else breaks; they just can't use coverage support. Given that coverage support currently requires a nightly compiler and LLVM 11 or newer, allowing it on a stable compiler built with LLVM 11 or newer seems like an improvement. The [tracking issue](rust-lang#79121) and the [issue label A-code-coverage](https://github.com/rust-lang/rust/labels/A-code-coverage) link to a few open issues related to `instrument-coverage`, but none of them seem like showstoppers. All of them seem like improvements and refinements we can make after stabilization. The original `-Z instrument-coverage` support went through a compiler-team MCP at rust-lang/compiler-team#278 . Based on that, ``@pnkfelix`` suggested that this needed a stabilization PR and a compiler-team FCP.
…overage, r=wesleywiser Stabilize `-Z instrument-coverage` as `-C instrument-coverage` (Tracking issue for `instrument-coverage`: rust-lang#79121) This PR stabilizes support for instrumentation-based code coverage, previously provided via the `-Z instrument-coverage` option. (Continue supporting `-Z instrument-coverage` for compatibility for now, but show a deprecation warning for it.) Many, many people have tested this support, and there are numerous reports of it working as expected. Move the documentation from the unstable book to stable rustc documentation. Update uses and documentation to use the `-C` option. Addressing questions raised in the tracking issue: > If/when stabilized, will the compiler flag be updated to -C instrument-coverage? (If so, the -Z variant could also be supported for some time, to ease migrations for existing users and scripts.) This stabilization PR updates the option to `-C` and keeps the `-Z` variant to ease migration. > The Rust coverage implementation depends on (and automatically turns on) -Z symbol-mangling-version=v0. Will stabilizing this feature depend on stabilizing v0 symbol-mangling first? If so, what is the current status and timeline? This stabilization PR depends on rust-lang#90128 , which stabilizes `-C symbol-mangling-version=v0` (but does not change the default symbol-mangling-version). > The Rust coverage implementation implements the latest version of LLVM's Coverage Mapping Format (version 4), which forces a dependency on LLVM 11 or later. A compiler error is generated if attempting to compile with coverage, and using an older version of LLVM. Given that LLVM 13 has now been released, requiring LLVM 11 for coverage support seems like a reasonable requirement. If people don't have at least LLVM 11, nothing else breaks; they just can't use coverage support. Given that coverage support currently requires a nightly compiler and LLVM 11 or newer, allowing it on a stable compiler built with LLVM 11 or newer seems like an improvement. The [tracking issue](rust-lang#79121) and the [issue label A-code-coverage](https://github.com/rust-lang/rust/labels/A-code-coverage) link to a few open issues related to `instrument-coverage`, but none of them seem like showstoppers. All of them seem like improvements and refinements we can make after stabilization. The original `-Z instrument-coverage` support went through a compiler-team MCP at rust-lang/compiler-team#278 . Based on that, ```@pnkfelix``` suggested that this needed a stabilization PR and a compiler-team FCP.
…overage, r=wesleywiser Stabilize `-Z instrument-coverage` as `-C instrument-coverage` (Tracking issue for `instrument-coverage`: rust-lang#79121) This PR stabilizes support for instrumentation-based code coverage, previously provided via the `-Z instrument-coverage` option. (Continue supporting `-Z instrument-coverage` for compatibility for now, but show a deprecation warning for it.) Many, many people have tested this support, and there are numerous reports of it working as expected. Move the documentation from the unstable book to stable rustc documentation. Update uses and documentation to use the `-C` option. Addressing questions raised in the tracking issue: > If/when stabilized, will the compiler flag be updated to -C instrument-coverage? (If so, the -Z variant could also be supported for some time, to ease migrations for existing users and scripts.) This stabilization PR updates the option to `-C` and keeps the `-Z` variant to ease migration. > The Rust coverage implementation depends on (and automatically turns on) -Z symbol-mangling-version=v0. Will stabilizing this feature depend on stabilizing v0 symbol-mangling first? If so, what is the current status and timeline? This stabilization PR depends on rust-lang#90128 , which stabilizes `-C symbol-mangling-version=v0` (but does not change the default symbol-mangling-version). > The Rust coverage implementation implements the latest version of LLVM's Coverage Mapping Format (version 4), which forces a dependency on LLVM 11 or later. A compiler error is generated if attempting to compile with coverage, and using an older version of LLVM. Given that LLVM 13 has now been released, requiring LLVM 11 for coverage support seems like a reasonable requirement. If people don't have at least LLVM 11, nothing else breaks; they just can't use coverage support. Given that coverage support currently requires a nightly compiler and LLVM 11 or newer, allowing it on a stable compiler built with LLVM 11 or newer seems like an improvement. The [tracking issue](rust-lang#79121) and the [issue label A-code-coverage](https://github.com/rust-lang/rust/labels/A-code-coverage) link to a few open issues related to `instrument-coverage`, but none of them seem like showstoppers. All of them seem like improvements and refinements we can make after stabilization. The original `-Z instrument-coverage` support went through a compiler-team MCP at rust-lang/compiler-team#278 . Based on that, `@pnkfelix` suggested that this needed a stabilization PR and a compiler-team FCP.
first stage of implementing LLVM code coverage 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 intrinsic `instrprof.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.](https://github.com/richkadel/rust/blob/cfa0b21d34ee64e4ebee226101bd2ef0c6757865/src/test/codegen/coverage-experiments/README-THIS-IS-TEMPORARY.md)***
What is this issue?
This is a major change proposal, which means a proposal to make a notable change to the compiler -- one that either alters the architecture of some component, affects a lot of people, or makes a small but noticeable public change (e.g., adding a compiler flag). You can read more about the MCP process on https://forge.rust-lang.org/.
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
MCP Checklist
#t-compiler/major changes
with the nameXXX compiler-team#NNN
, whereXXX
is the title of this issue andNNN
is whatever issue number gets assigned. Discuss the MCP in there, and feel free to update the proposal as needed.mcp-accepted
label and close the issue; we can link to it for future reference.TL;DR
Implement LLVM-compatible source-based code coverage for Rust.
Links and Details
Core Requirements
Instrument Rust crates by injecting additional runtime code to:
if
andelse
blocks, andmatch
arms.llvm-profdata
tool.llvm-profdata
tool is used to interpret the LLVM raw profile data from a given LLVM version.Generate a coverage map in LLVM Code Coverage Mapping Format that uniquely identifies counted coverage regions (source code spans) corresponding to the injected runtime counters.
With these requirements satisfied, LLVM coverage analysis tools, and some LLVM-supported GCC coverage analysis tools (as supported by existing compatibility features in LLVM tooling), should support coverage analysis of Rust program source code.
IMPORTANT: The LLVM coverage tooling can potentially support Profile Guided Optimization (PGO). Rust already has an option for compiling with PGO (
rustc -Cprofile-generate=/tmp/pgo-data
). This MCP is focused on source-based code coverage. Every effort will be made to accommodate future support for additional PGO extensions, potentially enabled by coverage instrumentation, but this MCP emphasizes a design optimized for source-based code coverage only.Approach and Notional Design
The following sections describe a high level design, and a stepwise approach to assess and implement LLVM code coverage for Rust. (Some of these steps are already in progress, including prototype implementation code.) This plan is open to change as a result of improved understanding of the rustc and LLVM architectures, and insights from reviewers.
Identify Rust Code Patterns for Code Regions and Counters
One of the primary use cases for source-based code coverage is to visually highlight the code regions executed by a program, separated by branch decision points. Regardless of how the code is instrumented, the final result must be verified against the source code, for all branch types supported by the Rust syntax, to ensure the coverage regions (start and end character positions in a source file) are consistent with the programmer's interpretation of the Rust code structure.
An analysis of the Rust Abstract Syntax Tree (AST) and its AST node types will help establish a baseline for validating the instrumentation. (This does not imply the instrumentation must be done in the AST.)
Item::Fn
,Expr
,Stmt
, andBlock
; defined in src/librustc_ast/ast.rs) and create sample Rust programs with contrived examples of Rust language patterns that create conditional branching. Here is a snippet from one such analysis. The comments on the left roughly sketch a graphical representation of the branching. The colors were added only to this snippet, to further illustrate the separate coverage regions.__incr_cov()
below) to validate an approach for each syntax test case. Note that counts for some coverage regions can be computed, using LLVM's Counter Expressions.Identify Coverage Regions, and Inject Placeholder Counters
Inject calls to increment coverage counters by injecting a call to
llvm-instrprof-increment
. There are differing opinions as to where coverage regions should be identified, and where to inject the counters (as discussed in the original Issue, the initial Pull Request, and the Zulip thread associated with this MCP).rustc_ast::mut_visit::MutVisitor
after AST expansion (beforeresolver.resolve_crate()
) to walk the AST and inject the counter statements (this has already been implemented in a functional, but limited prototype), (b) injecting additional instrumentation nodes while lowering the AST to HIR (some prototyping has been done here, and the existing pattern withexpr_drop_temps()
for injecting a placeholder, to be converted to generated IR code at a latter stage, is worth considering in this case); (c) or injecting coverage during "HIR->MIR" conversion (discussed but not yet attempted).Save a map from each injected counter to the source code start and end character representing the coverage region (represented by the existing
rustc
type,Span
).Implement an experimental
rustc
command line option to enable code coverage by crate.Add
llvm-instrprof-increment
Support to Existing Rust Compiler RuntimeImplement the changes required to introduce the
llvm-instrprof-increment
call for coverage counters. (It may be possible to inject the intrinsic in the MIR without explicitly defining as anextern
function.) If required:pub fn instrprof_increment
to theextern “rust-intrinsic”
section in libcore.instrprof_increment
to codegen_intrinsic_call() in librustc_codegen_llvm/intrinsic.rs.Update any other required build configuration dependencies, flags, documentation, and tests, as demonstrated by similar examples.
Update
llvm-instrprof-increment
temporary argumentsLocate the best stage for replacing all temporary arguments to llvm-instrprof-increment with the corrected values.
Identify and/or insert each instrumented function's mangled function name by global/static pointer. Use the
librustc_symbol_mangling
library to compute the mangled function name, as needed). This process must take place after monomorphization of generic types, so the mangled function name can be generated for each monomorphized version of the function. (Note that, by taking this proposed approach, coverage will be counted separately for each reified permutation of type parameters, even though the end result may be the sum of these counts. This seems to align well with the existing “v0” implementation of function name mangling, and instrumenting each type variant separately may have other benefits for source code coverage analysis and profiling.)Update the
num_counters
argument with the total number of injected counters per function.Generate the
hash
argument (from the MIR, HIR, or AST, to be determined) that identifies whether a function has changed enough to invalidate a past coverage analysis. Also called the "function's structural hash", this is a hash value that can be used by the consumer of the profile data to detect changes to the instrumented source. (Comments and whitespace should be excluded of course, but other criteria can be included or excluded. Clang, for instance, bases its hash on the overall control flow.)Generate the Coverage Map
Review the LLVM Code Coverage Mapping Format documentation and example implementations, such as from Clang](https://clang.llvm.org/doxygen/CoverageMappingGen_8cpp_source.html) and Swift.
Using the mapping from injected counters to coverage spans, and the additional details for each counter (mangled function name, function hash, num_counters), embed the coverage mapping into the LLVM IR.
Unless there are major objections, leverage the LLVM CoverageMappingWriter (C++) to generate and emit the coverage map.
Tests and Documentation
Implement Unit and End-to-End Integration Tests, following existing examples.
Update user and developer documentation as needed.
Optimization
Explore opportunities for optimizing the initial implementation of code coverage.
GitHub Artifacts
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
Experimental prototype PR and discussion: #70680 - WIP toward LLVM Code Coverage for Rust
LLVM Source-based Code Coverage
llvm.instrprof.increment
intrinsic - Increments code counters at runtimellvm-profdata
command - Profile data toolllvm-cov
command - Emit coverage informationMentors or Reviewers
The text was updated successfully, but these errors were encountered: