rust/compiler
bors 50dff955a9 Auto merge of #106285 - cjgillot:refprop-ssa, r=JakobDegen
Implement SSA-based reference propagation

Rust has a tendency to create a lot of short-lived borrows, in particular for method calls. This PR aims to remove those short-lived borrows with a const-propagation dedicated to pointers to local places.

This pass aims to transform the following pattern:
```
  _1 = &raw? mut? PLACE;
  _3 = *_1;
  _4 = &raw? mut? *_1;
```

Into
```
  _1 = &raw? mut? PLACE;
  _3 = PLACE;
  _4 = &raw? mut? PLACE;
```

where `PLACE` is a direct or an indirect place expression.

By removing indirection, this pass should help both dest-prop and const-prop to handle more cases.
This optimization is distinct from const-prop and dataflow const-prop since the borrow-reborrow patterns needs to preserve borrowck invariants, especially the uniqueness property of mutable references.

The pointed-to places are computed using a SSA analysis. We suppose that removable borrows are typically temporaries from autoref, so they are by construction assigned only once, and a SSA analysis is enough to catch them. For each local, we store both where and how it is used, in order to efficiently compute the all-or-nothing property. Thanks to `Derefer`, we only have to track locals, not places in general.

---

There are 3 properties that need to be upheld for this transformation to be legal:
- place constness: `PLACE` must refer to the same memory wherever it appears;
- pointer liveness: we must not introduce dereferences of dangling pointers;
- `&mut` borrow uniqueness.

## Constness

If `PLACE` is an indirect projection, if its of the form `(*LOCAL).PROJECTIONS` where:
- `LOCAL` is SSA;
- all projections in `PROJECTIONS` are constant (no dereference and no indexing).

If `PLACE` is a direct projection of a local, we consider it as constant if:
- the local is always live, or it has a single `StorageLive` that dominates all uses;
- all projections are constant.

# Liveness

When performing a substitution, we must take care not to introduce uses of dangling locals.

Using a dangling borrow is UB. Therefore, we assume that for any use of `*x`, where `x` is a borrow, the pointed-to memory is live.

Limitations:
- occurrences of `*x` in an `&raw mut? *x` are accepted;
- raw pointers are allowed to be dangling.

In those 2 case, we do not substitute anything, to be on the safe side.

**Open question:** we do not differentiate borrows of ZST and non-ZST. The UB rules may be
different depending on the layout. Having a different treatment would effectively prevent this
pass from running on polymorphic MIR, which defeats the purpose of MIR opts.

## Uniqueness

For `&mut` borrows, we also need to preserve the uniqueness property:
we must avoid creating a state where we interleave uses of `*_1` and `_2`.
To do it, we only perform full substitution of mutable borrows:
we replace either all or none of the occurrences of `*_1`.

Some care has to be taken when `_1` is copied in other locals.
```
   _1 = &raw? mut? _2;
   _3 = *_1;
   _4 = _1
   _5 = *_4
```
In such cases, fully substituting `_1` means fully substituting all of the copies.

For immutable borrows, we do not need to preserve such uniqueness property,
so we perform all the possible substitutions without removing the `_1 = &_2` statement.
2023-05-09 21:54:34 +00:00
..
rustc
rustc_abi Reorder to keep duplicate checks in sync. 2023-05-05 16:30:32 -07:00
rustc_apfloat
rustc_arena Deny the unsafe_op_in_unsafe_fn lint in 2023-04-28 21:00:54 -07:00
rustc_ast Rollup merge of #111215 - BoxyUwU:resolve_anon_consts_differently, r=cjgillot 2023-05-09 20:49:32 +02:00
rustc_ast_lowering Rollup merge of #111215 - BoxyUwU:resolve_anon_consts_differently, r=cjgillot 2023-05-09 20:49:32 +02:00
rustc_ast_passes Add feature gate 2023-05-05 21:44:48 +02:00
rustc_ast_pretty Migrate offset_of from a macro to builtin # syntax 2023-05-05 21:44:13 +02:00
rustc_attr Improve check-cfg diagnostics (part 2) 2023-05-05 13:06:48 +02:00
rustc_baked_icu_data Regen baked data 2023-05-02 10:45:16 -07:00
rustc_borrowck Rollup merge of #110583 - Ezrashaw:tweak-make-mut-spans, r=estebank 2023-05-09 12:33:45 +05:30
rustc_builtin_macros Rollup merge of #110694 - est31:builtin, r=petrochenkov 2023-05-09 12:33:45 +05:30
rustc_codegen_cranelift use EarlyBinder in tcx.(try_)subst_mir_and_normalize_erasing_regions 2023-05-06 22:32:39 -06:00
rustc_codegen_gcc Add todo for filter landing pad 2023-05-07 12:38:47 +01:00
rustc_codegen_llvm Rollup merge of #104070 - nbdd0121:unwind, r=Amanieu 2023-05-08 09:30:21 -07:00
rustc_codegen_ssa Rollup merge of #110304 - cchiw:master, r=davidtwco 2023-05-09 12:33:44 +05:30
rustc_const_eval use EarlyBinder in tcx.(try_)subst_mir_and_normalize_erasing_regions 2023-05-06 22:32:39 -06:00
rustc_data_structures Rollup merge of #111252 - matthewjasper:min-spec-improvements, r=compiler-errors 2023-05-09 12:33:46 +05:30
rustc_driver
rustc_driver_impl Rollup merge of #111004 - clubby789:migrate-mir-transform, r=oli-obk 2023-05-08 09:30:22 -07:00
rustc_error_codes Rollup merge of #111215 - BoxyUwU:resolve_anon_consts_differently, r=cjgillot 2023-05-09 20:49:32 +02:00
rustc_error_messages Rollup merge of #111104 - Manishearth:icuup, r=compiler-errors 2023-05-03 16:42:50 -07:00
rustc_errors Rollup merge of #111004 - clubby789:migrate-mir-transform, r=oli-obk 2023-05-08 09:30:22 -07:00
rustc_expand Rollup merge of #108801 - fee1-dead-contrib:c-str, r=compiler-errors 2023-05-05 18:40:33 +05:30
rustc_feature Rollup merge of #110694 - est31:builtin, r=petrochenkov 2023-05-09 12:33:45 +05:30
rustc_fluent_macro Remove unused synstructure dep 2023-04-22 22:03:33 +01:00
rustc_fs_util
rustc_graphviz enable rust_2018_idioms for doctests 2023-05-07 00:12:29 +03:00
rustc_hir Rollup merge of #108801 - fee1-dead-contrib:c-str, r=compiler-errors 2023-05-05 18:40:33 +05:30
rustc_hir_analysis Rollup merge of #111215 - BoxyUwU:resolve_anon_consts_differently, r=cjgillot 2023-05-09 20:49:32 +02:00
rustc_hir_pretty Rip it out 2023-05-01 16:15:13 +08:00
rustc_hir_typeck Rollup merge of #110504 - compiler-errors:tweak-borrow-sugg, r=cjgillot 2023-05-09 12:33:44 +05:30
rustc_incremental Rollup merge of #111024 - saethlin:stringify-full-svh, r=oli-obk 2023-05-04 08:09:04 +02:00
rustc_index Decorative changes to IndexVec 2023-04-24 13:53:37 +00:00
rustc_infer Rollup merge of #109410 - fmease:iat-alias-kind-inherent, r=compiler-errors 2023-05-08 09:30:21 -07:00
rustc_interface Auto merge of #109421 - mhammerly:extern-force-option, r=petrochenkov 2023-05-06 11:24:37 +00:00
rustc_lexer address comments 2023-05-02 10:32:07 +00:00
rustc_lint Rollup merge of #109410 - fmease:iat-alias-kind-inherent, r=compiler-errors 2023-05-08 09:30:21 -07:00
rustc_lint_defs Auto merge of #106621 - ozkanonur:enable-elided-lifetimes-for-doctests, r=Mark-Simulacrum 2023-05-08 04:50:28 +00:00
rustc_llvm Rollup merge of #111274 - cuviper:print-target-cpus, r=Mark-Simulacrum 2023-05-06 23:32:03 +02:00
rustc_log Stabilize IsTerminal 2023-04-10 17:24:23 +09:00
rustc_macros Rollup merge of #111120 - chenyukang:yukang-suggest-let, r=Nilstrieb 2023-05-09 12:33:46 +05:30
rustc_metadata Auto merge of #109421 - mhammerly:extern-force-option, r=petrochenkov 2023-05-06 11:24:37 +00:00
rustc_middle Auto merge of #106285 - cjgillot:refprop-ssa, r=JakobDegen 2023-05-09 21:54:34 +00:00
rustc_mir_build Rollup merge of #108801 - fee1-dead-contrib:c-str, r=compiler-errors 2023-05-05 18:40:33 +05:30
rustc_mir_dataflow Explicitly skip arguments. 2023-05-09 17:59:35 +00:00
rustc_mir_transform Correct StorageLive comment. 2023-05-09 17:59:35 +00:00
rustc_monomorphize use EarlyBinder in tcx.(try_)subst_mir_and_normalize_erasing_regions 2023-05-06 22:32:39 -06:00
rustc_parse Rollup merge of #111120 - chenyukang:yukang-suggest-let, r=Nilstrieb 2023-05-09 12:33:46 +05:30
rustc_parse_format Fix typos in compiler 2023-04-10 22:02:52 +02:00
rustc_passes Auto merge of #111014 - klensy:no-rc, r=WaffleLapkin 2023-05-04 20:49:23 +00:00
rustc_plugin_impl Add rustc_fluent_macro to decouple fluent from rustc_macros 2023-04-18 18:56:22 +00:00
rustc_privacy Auto merge of #111371 - compiler-errors:revert-110907, r=petrochenkov 2023-05-09 15:16:17 +00:00
rustc_query_impl Remove QueryEngine trait 2023-04-26 07:46:13 +02:00
rustc_query_system Restrict From<S> for {D,Subd}iagnosticMessage. 2023-05-03 08:44:39 +10:00
rustc_resolve Revert "Populate effective visibilities in rustc_privacy" 2023-05-08 21:47:44 +00:00
rustc_serialize Factor out more repeated code in {write,read}_leb128!. 2023-05-04 13:52:14 +10:00
rustc_session Rollup merge of #105354 - BlackHoleFox:apple-deployment-printer, r=oli-obk 2023-05-08 19:41:48 +09:00
rustc_smir Add GeneratorDrop terminator to SMIR 2023-05-05 10:34:55 -03:00
rustc_span Limit lifetime of format_args!() with inlined args. 2023-05-09 16:08:40 +02:00
rustc_symbol_mangling Rollup merge of #105452 - rcvalle:rust-cfi-3, r=bjorn3 2023-05-03 16:42:48 -07:00
rustc_target Rollup merge of #111332 - loongarch-rs:inline-asm, r=Amanieu 2023-05-08 19:41:51 +09:00
rustc_trait_selection Rollup merge of #111252 - matthewjasper:min-spec-improvements, r=compiler-errors 2023-05-09 12:33:46 +05:30
rustc_traits IAT: Introduce AliasKind::Inherent 2023-05-04 16:59:10 +02:00
rustc_transmute Remove unused TypeFoldable/TypeVisitable impls. 2023-04-26 15:19:50 +10:00
rustc_ty_utils Fix miscompilation when adding default method to Future 2023-05-08 17:06:48 +02:00
rustc_type_ir IAT: Introduce AliasKind::Inherent 2023-05-04 16:59:10 +02:00