Commit Graph

1275 Commits

Author SHA1 Message Date
bors
d627cf07ce Auto merge of #113915 - cjgillot:ssa-call, r=tmiasko
Also consider call and yield as MIR SSA.

The SSA analysis on MIR only considered `Assign` statements as defining a SSA local.
This PR adds assignments as part of a `Call` or `Yield` terminator in that category.

This mainly allows to perform CopyProp on a call return place.

The only subtlety is in the dominance property: the assignment is only complete at the beginning of the target block.
2023-10-10 20:37:55 +00:00
Matthias Krüger
de4980cf44
Rollup merge of #116595 - RalfJung:mir-enable-passes, r=oli-obk
-Zmir-enable-passes: document that this may enable unsound passes

also add some comments explaining why MIR opts are marked as unsound
2023-10-10 14:07:48 +02:00
Matthias Krüger
f4de82c2b3
Rollup merge of #116589 - Zalathar:successors, r=oli-obk
coverage: Unbox and simplify `bcb_filtered_successors`

This is a small cleanup in the coverage instrumentor's graph-building code.

---
This function already has access to the MIR body, so instead of taking a reference to a terminator, it's simpler and easier to pass in a basic block index.

There is no need to box the returned iterator if we instead add appropriate lifetime captures, and make `short_circuit_preorder` generic over the type of iterator it expects.

We can also greatly simplify the function's implementation by observing that the only difference between its two cases is whether we take all of a BB's successors, or just the first one.

---

`@rustbot` label +A-code-coverage
2023-10-10 14:07:47 +02:00
Ralf Jung
d805b265db add some comments explaining why MIR opts are marked as unsound 2023-10-10 11:17:27 +02:00
Zalathar
5d629457fd coverage: Unbox and simplify bcb_filtered_successors
This function already has access to the MIR body, so instead of taking a
reference to a terminator, it's simpler and easier to pass in a basic block
index.

There is no need to box the returned iterator if we instead add appropriate
lifetime captures, since `short_circuit_preorder` is now generic over the type
of iterator it expects.

We can also greatly simplify the function's implementation by observing that
the only difference between its two cases is whether we take all of a BB's
successors, or just the first one.
2023-10-10 18:45:29 +11:00
Zalathar
f214497d22 coverage: Replace ShortCircuitPreorder with a single function
Instead of defining a named struct, we can use `std::iter::from_fn` and store
intermediate state in a closure.
2023-10-10 18:44:16 +11:00
Zalathar
6c44425e98 coverage: Remove enum CoverageStatement
This enum was mainly needed to track the precise origin of a span in MIR, for
debug printing purposes. Since the old debug code was removed in #115962, we
can replace it with just the span itself.
2023-10-10 13:39:23 +11:00
Zalathar
4b471df25d coverage: Disconnect span extraction from CoverageSpansGenerator
By performal initial span extraction in a separate free function, we can remove
some accidental complexity from the main generator code.
2023-10-10 13:39:23 +11:00
Zalathar
972ab8863d coverage: Move initial MIR span extraction into a submodule 2023-10-10 13:39:23 +11:00
Matthias Krüger
148f5c1bdf
Rollup merge of #116549 - DaniPopes:miropts-let-chains, r=oli-obk
Simplify some mir passes by using let chains
2023-10-09 16:26:02 +02:00
bors
093b9d5b29 Auto merge of #116533 - cjgillot:skip-trivial-mir, r=oli-obk
Do not run optimizations on trivial MIR.

Fixes https://github.com/rust-lang/rust/issues/116513

The bug was introduced in https://github.com/rust-lang/rust/pull/110728, which put the check too early in the query chain.

cc `@oli-obk` `@ouz-a`
2023-10-09 06:00:23 +00:00
DaniPopes
47ebffabb8
Simplify some mir passes by using let chains 2023-10-09 05:22:31 +02:00
Camille GILLOT
37f080edbc Also consider call and yield as MIR SSA. 2023-10-08 16:05:26 +00:00
bors
4f4a413fe6 Auto merge of #116454 - tmiasko:small-dominators, r=cjgillot
Generalize small dominators optimization

* Use small dominators optimization from 640ede7b0a more generally.
* Merge `DefLocation` and `LocationExtended` since they serve the same purpose.
2023-10-08 12:38:14 +00:00
Camille GILLOT
005ec2e51c Do not run optimizations on trivial MIR. 2023-10-08 12:09:06 +00:00
Camille GILLOT
27d6a57e58 Preserve DebugInfo in DeadStoreElimination. 2023-10-06 15:46:11 +00:00
Tomasz Miąsko
eaafb256f8 Replace LocationExtended with DefLocation in SsaLocals 2023-10-05 23:45:59 +02:00
Tomasz Miąsko
6c348b77fe Remove small dominators optimization from SsaLocals
The optimization is now part of the general implementation.
2023-10-05 23:45:59 +02:00
ouz-a
3088c4b046 move subtyper change reveal_all 2023-10-05 18:56:30 +03:00
Camille GILLOT
e63d19c4dd Remove mir::LocalDecl::internal. 2023-10-04 17:55:15 +00:00
bors
36aab8df0a Auto merge of #115301 - Zalathar:regions-vec, r=davidtwco
coverage: Allow each coverage statement to have multiple code regions

The original implementation of coverage instrumentation was built around the assumption that a coverage counter/expression would be associated with *up to one* code region. When it was discovered that *multiple* regions would sometimes need to share a counter, a workaround was found: for the remaining regions, the instrumentor would create a fresh expression that adds zero  to the existing counter/expression.

That got the job done, but resulted in some awkward code, and produces unnecessarily complicated coverage maps in the final binary.

---

This PR removes that tension by changing `StatementKind::Coverage`'s code region field from `Option<CodeRegion>` to `Vec<CodeRegion>`.

The changes on the codegen side are fairly straightforward. As long as each `CoverageKind::Counter` only injects one `llvm.instrprof.increment`, the rest of coverage codegen is happy to handle multiple regions mapped to the same counter/expression, with only minor option-to-vec adjustments.

On the instrumentor/mir-transform side, we can get rid of the code that creates extra (x + 0) expressions. Instead we gather all of the code regions associated with a single BCB, and inject them all into one coverage statement.

---

There are several patches here but they can be divided in to three phases:
- Preparatory work
- Actually switching over to multiple regions per coverage statement
- Cleaning up

So viewing the patches individually may be easier.
2023-10-03 18:36:21 +00:00
Zalathar
053c4f94a0 coverage: Remove next_id methods from counter/expression IDs
When these methods were originally written, I wasn't aware that
`newtype_index!` already supports addition with ordinary numbers, without
needing to unwrap and re-wrap.
2023-10-03 13:03:40 +11:00
Zalathar
b1cf0c8f1b coverage: Remove code for making expression copies of BCB counters
Now that coverage statements can have multiple code regions attached to them,
this code is never used.
2023-10-03 13:03:39 +11:00
Zalathar
86a66c8171 coverage: Store each BCB's code regions in one coverage statement
If a BCB has more than one code region, those extra regions can now all be
stored in the same coverage statement, instead of being stored in additional
statements.
2023-10-03 13:03:39 +11:00
Zalathar
ee9d00f6b8 coverage: Let each coverage statement hold a vector of code regions
This makes it possible for a `StatementKind::Coverage` to hold more than one
code region, but that capability is not yet used.
2023-10-03 13:03:39 +11:00
Zalathar
1355e1fc74 coverage: Update comments/logs that referred to CoverageSpan
The concrete type `CoverageSpan` is no longer used outside of the `spans`
module.

This is a separate patch to avoid noise in the preceding patch that actually
encapsulates coverage spans.
2023-10-03 13:03:39 +11:00
Zalathar
e29db47176 coverage: Encapsulate coverage spans
By encapsulating the coverage spans in a struct, we can change the internal
representation without disturbing existing call sites. This will be useful for
grouping coverage spans by BCB.

This patch includes some changes that were originally in #115912, which avoid
the need for a particular test to deal with coverage spans at all.

(Comments/logs referring to `CoverageSpan` are updated in a subsequent patch.)
2023-10-03 13:03:39 +11:00
ouz-a
5d753abb30 have better explanation for relate_types 2023-10-02 23:39:45 +03:00
ouz-a
6f0c5ee2d4 change is_subtype to relate_types 2023-10-02 23:39:45 +03:00
ouz-a
cd7f471931 Add docs, remove code, change subtyper code 2023-10-02 23:39:44 +03:00
ouz-a
3148e6a993 subtyping_projections 2023-10-02 23:37:49 +03:00
bors
c5450191f3 Auto merge of #115759 - oli-obk:open_drop_from_non-ADT, r=lcnr
Reveal opaque types before drop elaboration

fixes https://github.com/rust-lang/rust/issues/113594

r? `@cjgillot`

cc `@JakobDegen`

This pass was introduced in https://github.com/rust-lang/rust/pull/110714

I moved it before drop elaboration (which only cares about the hidden types of things, not the opaque TAIT or RPIT type) and set it to run unconditionally (instead of depending on the optimization level and whether the inliner is active)
2023-09-29 11:59:51 +00:00
Camille GILLOT
3816c15b88 Only visit reachable nodes in SsaLocals. 2023-09-28 17:08:54 +00:00
Oli Scherer
2d4201f7c6 Skip reinterning if nothing changed 2023-09-28 16:13:38 +00:00
Oli Scherer
6ea2db7c2d Strip OpaqueCast during RevealAll. 2023-09-28 16:13:38 +00:00
Oli Scherer
9a40f1aa13 Remove unnecessary generator-check, which also fixes the issue within async functions 2023-09-28 16:13:38 +00:00
Oli Scherer
f5df26dbec Unconditionally run RevealAll pass and run it earlier 2023-09-28 16:13:38 +00:00
Oli Scherer
ec6f554536 Some tracing cleanups 2023-09-28 16:13:37 +00:00
Matthias Krüger
fa5b2fe2f5
Rollup merge of #116211 - matthiaskrgr:clippy3, r=compiler-errors
more clippy complextity fixes

redundant_guards, useless_format, clone_on_copy
2023-09-28 09:14:06 +02:00
Matthias Krüger
fd95627134 fix clippy::{redundant_guards, useless_format} 2023-09-27 23:49:15 +02:00
bors
e7c502d930 Auto merge of #109597 - cjgillot:gvn, r=oli-obk
Implement a global value numbering MIR optimization

The aim of this pass is to avoid repeated computations by reusing past assignments. It is based on an analysis of SSA locals, in order to perform a restricted form of common subexpression elimination.

By opportunity, this pass allows for some simplifications by combining assignments. For instance, this pass could be able to see through projections of aggregates to directly reuse the aggregate field (not in this PR).

We handle references by assigning a different "provenance" index to each `Ref`/`AddressOf` rvalue. This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we consider all the derefs of an immutable reference to a freeze type to give the same value:
```rust
_a = *_b // _b is &Freeze
_c = *_b // replaced by _c = _a
```
2023-09-27 21:06:30 +00:00
bors
376f3f0590 Auto merge of #116166 - Zalathar:unreachable, r=cjgillot
Skip MIR pass `UnreachablePropagation` when coverage is enabled

When coverage instrumentation and MIR opts are both enabled, coverage relies on two assumptions:

- MIR opts that would delete `StatementKind::Coverage` statements instead move them into bb0 and change them to `CoverageKind::Unreachable`.

- MIR opts won't delete all `CoverageKind::Counter` statements from an instrumented function.

Most MIR opts naturally satisfy the second assumption, because they won't remove coverage statements from bb0, but `UnreachablePropagation` can do so if it finds that bb0 is unreachable. If this happens, LLVM thinks the function isn't instrumented, and it vanishes from coverage reports.

A proper solution won't be possible until after per-function coverage info lands in #116046, but for now we can avoid the problem by turning off this particular pass when coverage instrumentation is enabled.

---

cc `@cjgillot` since I found this while investigating coverage problems encountered by #113970
`@rustbot` label +A-code-coverage +A-mir-opt
2023-09-27 05:31:15 +00:00
bors
5ae769f06b Auto merge of #116144 - lcnr:subst-less, r=oli-obk
subst -> instantiate

continues #110793, there are still quite a few uses of `subst` and `substitute`, but changing them all in the same PR was a bit too much, so I've stopped here for now.
2023-09-26 21:32:44 +00:00
Camille GILLOT
901be42bc0 Explicit simplify_place. 2023-09-26 16:41:40 +00:00
Zalathar
64df5a851e Skip MIR pass UnreachablePropagation when coverage is enabled
When coverage instrumentation and MIR opts are both enabled, coverage relies on
two assumptions:

- MIR opts that would delete `StatementKind::Coverage` statements instead move
  them into bb0 and change them to `CoverageKind::Unreachable`.

- MIR opts won't delete all `CoverageKind::Counter` statements from an
  instrumented function.

Most MIR opts naturally satisfy the second assumption, because they won't
remove coverage statements from bb0, but `UnreachablePropagation` can do so if
it finds that bb0 is unreachable. If this happens, LLVM thinks the function
isn't instrumented, and it vanishes from coverage reports.

A proper solution won't be possible until after per-function coverage info
lands in #116046, but for now we can avoid the problem by turning off this
particular pass when coverage instrumentation is enabled.
2023-09-26 20:18:43 +10:00
lcnr
3c52a3e280 subst -> instantiate 2023-09-26 09:37:55 +02:00
Camille GILLOT
1092849967 Use Vec::retain in remove_dead_blocks. 2023-09-25 17:08:40 +00:00
Camille GILLOT
b2ff77cb78 Do not clone valtree and slice constants. 2023-09-24 09:09:05 +00:00
Camille GILLOT
5f9d64d72f Embed simplification into VnState. 2023-09-24 09:09:04 +00:00
Camille GILLOT
3311536740 Workaround issue 112651. 2023-09-24 09:09:04 +00:00