Commit Graph

66 Commits

Author SHA1 Message Date
bors
d2d24e395a Auto merge of #123602 - cjgillot:gvn-borrowed, r=oli-obk
Account for immutably borrowed locals in MIR copy-prop and GVN

For the most part, we consider that immutably borrowed `Freeze` locals still fulfill SSA conditions. As the borrow is immutable, any use of the local will have the value given by the single assignment, and there can be no surprise.

This allows copy-prop to merge a non-borrowed local with a borrowed local. We chose to keep copy-classes heads unborrowed, as those may be easier to optimize in later passes.

This also allows to GVN the value behind an immutable borrow. If a SSA local is borrowed, dereferencing that borrow is equivalent to copying the local's value: re-executing the assignment between the borrow and the dereference would be UB.

r? `@ghost` for perf
2024-05-03 21:50:13 +00:00
bors
7a58674259 Auto merge of #124255 - RenjiSann:renji/mcdc-nested-expressions, r=Zalathar
MCDC coverage: support nested decision coverage

#123409 provided the initial MCDC coverage implementation.

As referenced in #124144, it does not currently support "nested" decisions, like the following example :

```rust
fn nested_if_in_condition(a: bool, b: bool, c: bool) {
    if a && if b || c { true } else { false } {
        say("yes");
    } else {
        say("no");
    }
}
```

Note that there is an if-expression (`if b || c ...`) embedded inside a boolean expression in the decision of an outer if-expression.

This PR proposes a workaround for this cases, by introducing a Decision context stack, and by handing several `temporary condition bitmaps` instead of just one.
When instrumenting boolean expressions, if the current node is a leaf condition (i.e. not a `||`/`&&` logical operator nor a `!` not operator), we insert a new decision context, such that if there are more boolean expressions inside the condition, they are handled as separate expressions.

On the codegen LLVM side, we allocate as many `temp_cond_bitmap`s as necessary to handle the maximum encountered decision depth.
2024-04-29 11:54:49 +00:00
Dorian Péron
eb422d5c7e tests(mcdc-coverage): Add tests for nested decision structures in mcdc_nested_if.rs 2024-04-29 09:13:41 +00:00
Oli Scherer
aef0f4024a Error on using yield without also using #[coroutine] on the closure
And suggest adding the `#[coroutine]` to the closure
2024-04-24 08:05:29 +00:00
Zalathar
3de87feba2 coverage: Branch coverage tests for match arms 2024-04-22 21:55:33 +10:00
Zalathar
7f432dfb23 coverage: Branch coverage test for if-let and let-chains 2024-04-22 21:55:33 +10:00
Zalathar
4f7a47798e coverage: Branch coverage test for let-else 2024-04-22 21:55:33 +10:00
许杰友 Jieyou Xu (Joe)
f13cd0c8d0
Rollup merge of #124053 - Zalathar:lazy-boolean, r=Mark-Simulacrum
coverage: Branch coverage tests for lazy boolean operators

The current branch coverage implementation already supports the `&&` and `||` operators (even outside of an `if` condition), as a natural consequence of how they are desugared/lowered, but we didn't have any specific tests for them. This PR adds some appropriate tests.

I've also moved the existing branch coverage tests into a `coverage/branch` subdirectory, so that they don't become unwieldy as I add more branch coverage tests.

``@rustbot`` label +A-code-coverage
2024-04-20 21:45:36 +01:00
Camille GILLOT
9b846d4637 Dereference immutable borrows in GVN. 2024-04-20 19:22:13 +00:00
zhuyunxing
402dc38d99 coverage. Add basic tests for MC/DC 2024-04-20 00:34:40 +08:00
Zalathar
25b9f84413 coverage: Branch coverage tests for lazy boolean operators 2024-04-17 12:32:30 +10:00
Zalathar
40cfc2de77 coverage: Move branch coverage tests into a subdirectory 2024-04-17 11:41:40 +10:00
DianQK
47ed73a7b5
Eliminate UbCheck for non-standard libraries 2024-03-27 21:02:40 +08:00
Zalathar
1cca2529d1 coverage: Re-enable UnreachablePropagation for coverage builds 2024-03-26 11:46:04 +11:00
Zalathar
85bec7a50c coverage: Remove incorrect assertions from counter allocation
These assertions detect situations where a BCB node would have both a physical
counter and one or more in-edge counters/expressions.

For most BCBs that situation would indicate an implementation bug. However,
it's perfectly fine in the case of a BCB having an edge that loops back to
itself.

Given the complexity and risk involved in fixing the assertions, and the fact
that nothing relies on them actually being true, this patch just removes them
instead.
2024-03-20 18:22:15 +11:00
Zalathar
70206f06ca coverage: Regression test for ICE triggered by self-loops 2024-03-20 18:14:35 +11:00
Zalathar
5fb1f61a77 coverage: Enable branch coverage in the branch coverage tests 2024-03-14 17:19:06 +11:00
Zalathar
89fab06a77 coverage: Add branch coverage tests (with branch coverage disabled) 2024-03-13 20:43:35 +11:00
Zalathar
1f544ce305 coverage: Remove all unstable values of -Cinstrument-coverage 2024-03-13 11:14:09 +11:00
许杰友 Jieyou Xu (Joe)
6e48b96692
[AUTO_GENERATED] Migrate compiletest to use ui_test-style //@ directives 2024-02-22 16:04:04 +00:00
Zalathar
ec91209f96 coverage: Eagerly deduplicate covspans with the same span 2024-02-21 21:25:35 +11:00
Vadim Petrochenkov
12d7bac2a4 Update coverage-run tests 2024-02-18 20:51:45 +03:00
Vadim Petrochenkov
9f8d05f29f macro_rules: Preserve all metavariable spans in a global side table 2024-02-18 11:19:24 +03:00
Zalathar
cd9021e8cb coverage: Discard spans that fill the entire function body
When we try to extract coverage-relevant spans from MIR, sometimes we see MIR
statements/terminators whose spans cover the entire function body. Those spans
tend to be unhelpful for coverage purposes, because they often represent
compiler-inserted code, e.g. the implicit return value of `()`.
2024-02-16 10:57:03 +11:00
Zalathar
75af3c58f9 coverage: Regression test for a span extraction inconsistency 2024-02-16 10:57:03 +11:00
Camille GILLOT
e132cac3c4 Enable by default. 2024-02-09 21:13:51 +00:00
Zalathar
dd6d7f27e4 coverage: Make unexpansion of closure bodies more precise
This improves the coverage instrumentation of closures declared in macros, as
seen in `closure_macro.rs` and `closure_macro_async.rs`.
2024-02-05 10:09:46 +11:00
Zalathar
8dd2b37462 coverage: Add a test for #[coverage(..)] on closures 2024-02-05 10:07:19 +11:00
Zalathar
fe420dc46e coverage: Test for closure body that is a single bang-macro 2024-02-05 10:07:18 +11:00
Zalathar
c9c049b2b4 coverage: Use normal edition: headers in coverage tests
Some of these tests were originally written as part of a custom `run-make`
test, so at that time they weren't able to use the normal compiletest header
directive parser.

Now that they're properly integrated, there's no need for them to use
`compile-flags` to specify the edition, since they can use `edition` instead.
2024-02-02 11:17:05 +11:00
León Orell Valerian Liehr
8bd126cb18
Rollup merge of #120185 - Zalathar:auto-derived, r=wesleywiser
coverage: Don't instrument `#[automatically_derived]` functions

This PR makes the coverage instrumentor detect and skip functions that have [`#[automatically_derived]`](https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute) on their enclosing impl block.

Most notably, this means that methods generated by built-in derives (e.g. `Clone`, `Debug`, `PartialEq`) are now ignored by coverage instrumentation, and won't appear as executed or not-executed in coverage reports.

This is a noticeable change in user-visible behaviour, but overall I think it's a net improvement. For example, we've had a few user requests for this sort of change (e.g. #105055, https://github.com/rust-lang/rust/issues/84605#issuecomment-1902069040), and I believe it's the behaviour that most users will expect/prefer by default.

It's possible to imagine situations where users would want to instrument these derived implementations, but I think it's OK to treat that as an opportunity to consider adding more fine-grained option flags to control the details of coverage instrumentation, while leaving this new behaviour as the default.

(Also note that while `-Cinstrument-coverage` is a stable feature, the exact details of coverage instrumentation are allowed to change. So we *can* make this change; the main question is whether we *should*.)

Fixes #105055.
2024-01-24 15:43:12 +01:00
Zalathar
41dcba805d coverage: Don't instrument #[automatically_derived] functions 2024-01-22 12:18:57 +11:00
Zalathar
6d7e80c5bc Add #[coverage(off)] to closures introduced by #[test]/#[bench] 2024-01-21 23:17:00 +11:00
Zalathar
bdfc64ac98 coverage: Add a test that uses #[bench] 2024-01-21 23:17:00 +11:00
Nadrieril
e8678b1030
Rollup merge of #120015 - Zalathar:format, r=dtolnay
coverage: Format all coverage tests with `rustfmt`

As suggested by <https://github.com/rust-lang/rust/pull/119984#discussion_r1452856806>.

Test files in `tests/` are normally ignored by `x fmt`, but sometimes those files end up being run through `rustfmt` anyway, either by `rust-analyzer` or by hand.

When that happens, it's annoying to have to manually revert formatting changes that are unrelated to the actual changes being made. So it's helpful for the tests in the repository to already have standard formatting beforehand.

However, there are several coverage tests that deliberately use non-standard formatting, so that line counts reveal more information about where code regions begin and end. In those cases, we can use `#[rustfmt::skip]` to prevent that code from being disturbed.

``@rustbot`` label +A-code-coverage
2024-01-21 06:38:37 +01:00
Zalathar
99797bbd9f coverage: Format all remaining tests
These tests can simply be reformatted as normal, because the resulting changes
are unimportant.
2024-01-18 10:42:37 +11:00
Kevin Reid
c48cdfe8ee Remove unnecessary lets and borrowing from Waker::noop() usage.
`Waker::noop()` now returns a `&'static Waker` reference, so it can be
passed directly to `Context` creation with no temporary lifetime issue.
2024-01-17 12:00:27 -08:00
Zalathar
1f9353ae2c coverage: Tweak individual tests to be unaffected by rustfmt
Some of these tests use non-standard formatting that we can simulate by
strategically adding `//` line comments.

One contains `where` clauses that would be split across multiple lines, which
we can keep on one line by moving the bounds to the generic type instead.
2024-01-16 16:14:27 +11:00
Zalathar
f1494425bb coverage: Add #[rustfmt::skip] to tests with non-standard formatting
These tests deliberately use non-standard formatting, so that the line
execution counts reported by `llvm-cov` reveal additional information about
where code regions begin and end.
2024-01-16 15:56:37 +11:00
Zalathar
6971e9332d coverage: llvm-cov expects column numbers to be bytes, not code points 2024-01-08 21:58:46 +11:00
Zalathar
585a285619 coverage: Test for column numbers involving non-ASCII characters 2024-01-08 21:43:22 +11:00
Michael Goulet
bacddd3e5d
Rollup merge of #119208 - Zalathar:hoist, r=WaffleLapkin,Swatinem
coverage: Hoist some complex code out of the main span refinement loop

The span refinement loop in `spans.rs` takes the spans that have been extracted from MIR, and modifies them to produce more helpful output in coverage reports.

It is also one of the most complicated pieces of code in the coverage instrumentor. It has an abundance of moving pieces that make it difficult to understand, and most attempts to modify it end up accidentally changing its behaviour in unacceptable ways.

This PR nevertheless tries to make a dent in it by hoisting two pieces of special-case logic out of the main loop, and into separate preprocessing passes. Coverage tests show that the resulting mappings are *almost* identical, with all known differences being unimportant.

This should hopefully unlock further simplifications to the refinement loop, since it now has fewer edge cases to worry about.
2024-01-05 23:41:41 -05:00
Zalathar
731ba80a6b Allow coverage tests to enable llvm-cov --use-color 2024-01-05 13:42:54 +11:00
Zalathar
aa4bf0bbf0 Allow tests to ignore individual test modes
Normally, each test in `tests/coverage` is automatically run in both
`coverage-map` mode and `coverage-run` mode.

This new family of directives allows an individual test to specify that it
should not be run in a particular mode.
2024-01-05 13:42:54 +11:00
Zalathar
d4d2f1428c coverage: Hoist the splitting of visible macro invocations 2024-01-05 12:53:23 +11:00
Zalathar
df0df5256b coverage: Overhaul how "visible macros" are determined 2024-01-05 12:53:23 +11:00
Vadim Petrochenkov
e1d12c8caf macro_rules: Less hacky heuristic for using tt metavariable spans 2024-01-04 03:53:56 +03:00
Camille GILLOT
a03c972816 Enable GVN by default. 2023-12-24 20:08:57 +00:00
Zalathar
4ae792036e coverage: Add a test for async blocks
We have coverage tests that use async functions, but none that use async
blocks.
2023-12-20 18:48:04 +11:00
Matthias Krüger
418ae3e9a0
Rollup merge of #118852 - Zalathar:no-spans, r=cjgillot
coverage: Skip instrumenting a function if no spans were extracted from MIR

The immediate symptoms of #118643 were fixed by #118666, but some users reported that their builds now encounter another coverage-related ICE:

```
error: internal compiler error: compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs:98:17: A used function should have had coverage mapping data but did not: (...)
```

I was able to reproduce at least one cause of this error: if no relevant spans could be extracted from a function, but the function contains `CoverageKind::SpanMarker` statements, then codegen still thinks the function is instrumented and complains about the fact that it has no coverage spans.

This PR prevents that from happening in two ways:
- If we didn't extract any relevant spans from MIR, skip instrumenting the entire function and don't create a `FunctionCoverateInfo` for it.
- If coverage codegen sees a `CoverageKind::SpanMarker` statement, skip it early and avoid creating `func_coverage`.

---

Fixes #118850.
2023-12-18 08:08:22 +01:00