-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[Draft] Tools and tests to experimentally add more counters per function #75828
Conversation
9ef2c30
to
2da7371
Compare
☔ The latest upstream changes (presumably #74275) made this pull request unmergeable. Please resolve the merge conflicts. |
2da7371
to
1600b1e
Compare
@@ -851,6 +851,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, | |||
"in addition to `.mir` files, create graphviz `.dot` files (default: no)"), | |||
emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], | |||
"emit a section containing stack size metadata (default: no)"), | |||
experimental_coverage: bool = (false, parse_bool, [TRACKED], |
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 don't see any particular need to have another flag for this since the profiling instrumentation is already guarded by an unstable flag. Is having this second flag helpful for 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.
I feel like it's helpful to me, but it's a gut feeling to be sure. I know the function-level coverage is valid and results are clean, and though experimental, I didn't want the -Zinstrument-coverage option to regress from a "working" state to a completely useless state (which is what -Zexperimental-coverage is right now).
But other than regression testing, I will be working with -Zexperimental-coverage primarily, so if you feel I should remove the extra flag, I will.
@@ -20,6 +20,7 @@ fn main() { | |||
"InstrProfilingMergeFile.c", | |||
"InstrProfilingNameVar.c", | |||
"InstrProfilingPlatformDarwin.c", | |||
"InstrProfilingPlatformFuchsia.c", |
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.
This feels kind of out of place with the other changes. Is there anything else needed to bring up profiling support on Fuchsia or is this it?
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 only recently noticed it was missing, and since it was an obvious omission (all of the other supported platforms were there), and the fact that I'm about to start testing on Fuchsia with the nightly build, I wanted to close that gap. As far as I know, there's nothing else missing, but, no I haven't tested this yet.
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.
This is now in its own commit, #75998
/// Returns a new `Span` covering the start and end `BytePos`s of the file containing the given | ||
/// `pos`. This can be used to quickly determine if another `BytePos` or `Span` is from the same | ||
/// file. | ||
pub fn lookup_file_span(&self, pos: BytePos) -> Span { |
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.
Is this still needed? I couldn't find any uses at a glance.
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.
It's a good question. I know the function is not being called by the code in what I ended up committing in this PR; but I did use it, while experimenting prior to staging my commit. Before I checked in this version of the code, I stripped out some of my experimental stuff, to keep the committed code a little cleaner.
I suspect I will need this and I didn't want to lose it. I think it's helpful, and (to me) not entirely obvious, otherwise, that someone could confirm if two Spans come from the same file without having to lookup the actual file name of both.
If you want it removed, I'll remove it. Just let me know.
Thanks for the review @wesleywiser ! I think all of your comments were questions, asking my reasoning for including certain changes, so I replied to those. Let me know if, after reading my response, you want me to change any or all of these. Thanks! |
Also, FYI, I think @tmandry also plans to review in the next day or two, so we should not submit to bors just yet. And I'm testing my |
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). Adds `--bless` support to `test/run-make-fulldeps` so expected coverage output can be quickly regenerated. Adds a new `-Zexperimental-coverage` option that implies `-Zinstrument-coverage`, but can be used to enable experimental coverage counter injection. 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. Also, learned that `-C link-dead-code` (which was enabled automatically under `-Z instrument-coverage`) was causing the linking error that resulted in segmentation faults in coverage instrumented binaries. Link dead code is now disabled under MSVC, allowing `-Zinstrument-coverage` to be enabled under MSVC for the first time. Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: rust-lang#34701 - Implement support for LLVMs code coverage instrumentation
LOL, I'm an idiot. Half the tests are ignored on Windows (under MSVC) because they are set to This is WAI. The tests with So no change required for that; but while investigating, I did notice there's a way to ignore test directories, by including a file named I verified this works on both Linux and Windows, so I'll upload that change now. FYI, all of the instrument_coverage tests can still be tested with one test target, by:
This runs 6 tests on Linux and Mac, but on Windows it runs 3 tests and ignores 3 tests (as intended). |
1600b1e
to
5d13cbc
Compare
Can we split this PR up? It would be much easier to review one logical change at a time. |
Will do. |
I'm converting this PR to "Draft" while I submit separate PRs broken out from this one. |
The ability to "bless" output for some of these tests is critical to making it practical to adapt tests to unrelated changes. This is needed for new coverage tests, as shown in PR rust-lang#75828 (or its derivative).
Done |
Found that -C link-dead-code (which was enabled automatically under -Z instrument-coverage) was causing the linking error that resulted in segmentation faults in coverage instrumented binaries. Link dead code is now disabled under MSVC, allowing `-Z instrument-coverage` to be enabled under MSVC for the first time. More details are included in Issue rust-lang#76038. (This PR was broken out from PR rust-lang#75828)
…3, r=tmandry Fix `-Z instrument-coverage` on MSVC Found that `-C link-dead-code` (which was enabled automatically under `-Z instrument-coverage`) was causing the linking error that resulted in segmentation faults in coverage instrumented binaries. Link dead code is now disabled under MSVC, allowing `-Z instrument-coverage` to be enabled under MSVC for the first time. More details are included in Issue rust-lang#76038 . Note this PR makes it possible to support `Z instrument-coverage` but does not enable instrument coverage for MSVC in existing tests. It will be enabled in another PR to follow this one (both PRs coming from original PR rust-lang#75828). r? @tmandry FYI: @wesleywiser
…4, r=wesleywiser Adds two source span utility functions used in source-based coverage `span.is_empty()` - returns true if `lo()` and `hi()` are equal. This is not only a convenience, but makes it clear that a `Span` can be empty (that is, retrieving the source for an empty `Span` will return an empty string), and codifies the (otherwise undocumented--in the rustc_span package, at least) fact that `Span` is a half-open interval (where `hi()` is the open end). `source_map.lookup_file_span()` - returns an enclosing `Span` representing the start and end positions of the file enclosing the given `BytePos`. This gives developers a clear way to quickly determine if any any other `BytePos` or `Span` is also from the same file (for example, by simply calling `file_span.contains(span)`). This results in much simpler code and is much more runtime efficient compared with the obvious alternative: calling `source_map.lookup_line()` for any two `Span`'s byte positions, handle both arms of the `Result` (both contain the file), and then compare files. It is also more efficient than the non-public method `lookup_source_file_idx()` for each `BytePos`, because, while comparing the internal source file indexes would be efficient, looking up the source file index for every `BytePos` or `Span` to be compared requires a binary search (worst case performance being O(log n) for every lookup). `source_map.lookup_file_span()` performs the binary search only once, to get the `file_span` result that can be used to compare to any number of other `BytePos` or `Span` values and those comparisons are always O(1). This PR was split out from PR rust-lang#75828 . 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
Note: This PR has been replaced by multiple PRs, as noted in the references on Aug 27, 2020.
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:
Adds
--bless
support totest/run-make-fulldeps
so expected coverageoutput can be quickly regenerated.
Adds a new
-Zexperimental-coverage
option that implies-Zinstrument-coverage
, but can be used to enable experimental coveragecounter injection.
Includes a basic, MIR-block-based implementation of coverage injection,
available via
-Zexperimental-coverage
. This implementation has knownflaws and omissions, but is simple enough to validate the new tools and
tests.
The existing
-Zinstrument-coverage
option currently enablesfunction-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.Also, learned that
-C link-dead-code
(which was enabled automaticallyunder
-Z instrument-coverage
) was causing the linking error thatresulted in segmentation faults in coverage instrumented binaries. Link
dead code is now disabled under MSVC, allowing
-Zinstrument-coverage
to be enabled under MSVC for the first time.
Rust compiler MCP rust-lang/compiler-team#278
Relevant issue: #34701 - Implement support for LLVMs code coverage
instrumentation
r? @tmandry
FYI: @wesleywiser