rust/compiler/rustc_mir_transform/src
Matthias Krüger 3ae7ab698f
Rollup merge of #115291 - cjgillot:dest-prop-save, r=JakobDegen
Save liveness results for DestinationPropagation

`DestinationPropagation` needs to verify that merge candidates do not conflict with each other. This is done by verifying that a local is not live when its counterpart is written to.

To get the liveness information, the pass runs `MaybeLiveLocals` dataflow analysis repeatedly, once for each propagation round. This is quite costly, and the main driver for the perf impact on `ucd` and `diesel`. (See https://github.com/rust-lang/rust/pull/115105#issuecomment-1689205908)

In order to mitigate this cost, this PR proposes to save the result of the analysis into a `SparseIntervalMatrix`, and mirror merges of locals into that matrix: `liveness(destination) := liveness(destination) union liveness(source)`.

<details>
<summary>Proof</summary>

We denote by `'` all the quantities of the transformed program. Let $\varphi$ be a mapping of locals, which maps `source` to `destination`, and is identity otherwise. The exact liveness set after a statement is $out'(statement)$, and the proposed liveness set is $\varphi(out(statement))$.

Consider a statement. Suppose that the output state verifies $out' \subset phi(out)$. We want to prove that $in' \subset \varphi(in)$ where $in = (out - kill) \cup gen$, and conclude by induction.

We have 2 cases: either that statement is kept with locals renumbered by $\varphi$, or it is a tautological assignment and it removed.

1. If the statement is kept: the gen-set and the kill-set of $statement' = \varphi(statement)$ are $gen' = \varphi(gen)$ and $kill' = \varphi(kill)$ exactly.
From soundness requirement 3, $\varphi(in)$ is disjoint from $\varphi(kill)$.
This implies that $\varphi(out - kill)$ is disjoint from $\varphi(kill)$, and so $\varphi(out - kill) = \varphi(out) - \varphi(kill)$. Then $\varphi(in) = (\varphi(out) - \varphi(kill)) \cup \varphi(gen) = (\varphi(out) - kill') \cup gen'$.
We can conclude that $out' \subset \varphi(out) \implies in' \subset \varphi(in)$.

2. If the statement is removed. As $\varphi(statement)$ is a tautological assignment, we know that $\varphi(gen) = \varphi(kill) = \\{ destination \\}$, while $gen' = kill' = \emptyset$. So $\varphi(in) = \varphi(out) \cup \\{ destination \\}$. Then $in' = out' \subset out \subset \varphi(in)$.

By recursion, we can conclude by that $in' \subset \varphi(in)$ everywhere.
</details>

This approximate liveness results is only suboptimal if there are locals that fully disappear from the CFG due to an assignment cycle. These cases are quite unlikely, so we do not bother with them.

This change allows to reduce the perf impact of DestinationPropagation by half on diesel and ucd (https://github.com/rust-lang/rust/pull/115105#issuecomment-1694701904).

cc ````@JakobDegen````
2024-01-17 20:21:19 +01:00
..
coverage coverage: Simplify computing successors in the BCB graph 2024-01-14 12:11:26 +11:00
inline subst -> instantiate 2023-09-26 09:37:55 +02:00
abort_unwinding_calls.rs remove redundant imports 2023-12-10 10:56:22 +08:00
add_call_guards.rs remove redundant imports 2023-12-10 10:56:22 +08:00
add_moves_for_packed_drops.rs remove redundant imports 2023-12-10 10:56:22 +08:00
add_retag.rs remove redundant imports 2023-12-10 10:56:22 +08:00
add_subtyping_projections.rs remove redundant imports 2023-12-10 10:56:22 +08:00
check_alignment.rs remove redundant imports 2023-12-10 10:56:22 +08:00
check_const_item_mutation.rs Fix clippy::needless_borrow in the compiler 2023-11-21 20:13:40 +01:00
check_packed_ref.rs Remove Session methods that duplicate DiagCtxt methods. 2023-12-24 08:05:28 +11:00
check_unsafety.rs Stabilize THIR unsafeck 2024-01-05 10:00:59 +00:00
cleanup_post_borrowck.rs rename BorrowKind::Shallow to Fake 2023-11-08 22:55:28 +01:00
const_debuginfo.rs Format all the let chains in compiler 2023-10-13 08:59:36 +00:00
const_goto.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
const_prop.rs Replace legacy ConstProp by GVN. 2023-12-24 20:08:57 +00:00
const_prop_lint.rs rustc_mir_transform: Enforce rustc::potential_query_instability lint 2024-01-06 19:09:04 +01:00
copy_prop.rs remove redundant imports 2023-12-10 10:56:22 +08:00
coroutine.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
cost_checker.rs Re-format code with new rustfmt 2023-11-15 21:45:48 -05:00
cross_crate_inline.rs Fix cases where std accidentally relied on inline(never) 2023-12-14 08:30:36 -05:00
ctfe_limit.rs Fix clippy::needless_borrow in the compiler 2023-11-21 20:13:40 +01:00
dataflow_const_prop.rs NFC don't convert types to identical types 2023-12-15 23:56:24 +01:00
dead_store_elimination.rs Auto merge of #116520 - Enselic:large-copy-into-fn, r=oli-obk 2024-01-16 19:33:14 +00:00
deduce_param_attrs.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
deduplicate_blocks.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
deref_separator.rs remove redundant imports 2023-12-10 10:56:22 +08:00
dest_prop.rs Rollup merge of #115291 - cjgillot:dest-prop-save, r=JakobDegen 2024-01-17 20:21:19 +01:00
dump_mir.rs Write to stdout if - is given as output file 2023-06-06 17:53:29 -04:00
early_otherwise_branch.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
elaborate_box_derefs.rs remove redundant imports 2023-12-10 10:56:22 +08:00
elaborate_drops.rs Remove Session methods that duplicate DiagCtxt methods. 2023-12-24 08:05:28 +11:00
errors.rs Rework how diagnostic lints are stored. 2024-01-14 14:04:25 +11:00
ffi_unwind_calls.rs s/Generator/Coroutine/ 2023-10-20 21:10:38 +00:00
function_item_references.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
gvn.rs Expand match over binops. 2024-01-16 22:34:04 +00:00
inline.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
instsimplify.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
jump_threading.rs Skip threading over no-op SetDiscriminant. 2024-01-07 00:28:20 +00:00
large_enums.rs Fix some comments 2023-12-28 12:23:14 +08:00
lib.rs Auto merge of #116520 - Enselic:large-copy-into-fn, r=oli-obk 2024-01-16 19:33:14 +00:00
lint.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
lower_intrinsics.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
lower_slice_len.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
match_branches.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
multiple_return_terminators.rs remove redundant imports 2023-12-10 10:56:22 +08:00
normalize_array_len.rs remove redundant imports 2023-12-10 10:56:22 +08:00
nrvo.rs add some comments explaining why MIR opts are marked as unsound 2023-10-10 11:17:27 +02:00
pass_manager.rs Fix validation and linting of injected MIR 2024-01-04 23:06:42 +01:00
prettify.rs remove redundant imports 2023-12-10 10:56:22 +08:00
promote_consts.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
ref_prop.rs Don't require owned data in MaybeStorageDead 2023-12-21 12:58:39 +01:00
remove_noop_landing_pads.rs remove redundant imports 2023-12-10 10:56:22 +08:00
remove_place_mention.rs remove redundant imports 2023-12-10 10:56:22 +08:00
remove_storage_markers.rs remove redundant imports 2023-12-10 10:56:22 +08:00
remove_uninit_drops.rs remove redundant imports 2023-12-10 10:56:22 +08:00
remove_unneeded_drops.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
remove_zsts.rs remove redundant imports 2023-12-10 10:56:22 +08:00
required_consts.rs rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::Const 2023-09-21 08:12:30 +02:00
reveal_all.rs remove redundant imports 2023-12-10 10:56:22 +08:00
separate_const_switch.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
shim.rs compiler: Lower fn call arg spans down to MIR 2024-01-15 19:07:11 +01:00
simplify.rs Merge dead bb pruning and unreachable bb deduplication. 2024-01-07 15:12:10 +00:00
simplify_branches.rs remove redundant imports 2023-12-10 10:56:22 +08:00
simplify_comparison_integral.rs rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::Const 2023-09-21 08:12:30 +02:00
sroa.rs remove redundant imports 2023-12-10 10:56:22 +08:00
ssa.rs Inline dominator check. 2023-12-31 00:37:45 +00:00
uninhabited_enum_branching.rs Fix clippy::needless_borrow in the compiler 2023-11-21 20:13:40 +01:00
unreachable_prop.rs rustc_mir_transform: Enforce rustc::potential_query_instability lint 2024-01-06 19:09:04 +01:00