Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9fa941c

Browse files
Rollup merge of #95649 - ouz-a:mir-opt, r=oli-obk
New mir-opt deref_separator This adds a new mir-opt that split certain derefs into this form: `let x = (*a.b).c;` to => `tmp = a.b; let x = (*tmp).c;` Huge thanks to ``@oli-obk`` for his patient mentoring.
2 parents 76cd8f8 + 1cf6d69 commit 9fa941c

16 files changed

+193
-4
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use crate::MirPass;
2+
use rustc_middle::mir::patch::MirPatch;
3+
use rustc_middle::mir::*;
4+
use rustc_middle::ty::TyCtxt;
5+
pub struct Derefer;
6+
7+
pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
8+
let mut patch = MirPatch::new(body);
9+
let (basic_blocks, local_decl) = body.basic_blocks_and_local_decls_mut();
10+
for (block, data) in basic_blocks.iter_enumerated_mut() {
11+
for (i, stmt) in data.statements.iter_mut().enumerate() {
12+
match stmt.kind {
13+
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
14+
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
15+
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
16+
// The type that we are derefing.
17+
let ty = p_ref.ty(local_decl, tcx).ty;
18+
let temp = patch.new_temp(ty, stmt.source_info.span);
19+
20+
// Because we are assigning this right before original statement
21+
// we are using index i of statement.
22+
let loc = Location { block: block, statement_index: i };
23+
patch.add_statement(loc, StatementKind::StorageLive(temp));
24+
25+
// We are adding current p_ref's projections to our
26+
// temp value.
27+
let deref_place =
28+
Place::from(p_ref.local).project_deeper(p_ref.projection, tcx);
29+
patch.add_assign(
30+
loc,
31+
Place::from(temp),
32+
Rvalue::Use(Operand::Move(deref_place)),
33+
);
34+
35+
// We are creating a place by using our temp value's location
36+
// and copying derefed values which we need to create new statement.
37+
let temp_place =
38+
Place::from(temp).project_deeper(&place.projection[idx..], tcx);
39+
let new_stmt = Statement {
40+
source_info: stmt.source_info,
41+
kind: StatementKind::Assign(Box::new((
42+
og_place,
43+
Rvalue::Ref(region, borrow_knd, temp_place),
44+
))),
45+
};
46+
47+
// Replace current statement with newly created one.
48+
*stmt = new_stmt;
49+
50+
// Since our job with the temp is done it should be gone
51+
let loc = Location { block: block, statement_index: i + 1 };
52+
patch.add_statement(loc, StatementKind::StorageDead(temp));
53+
54+
// As all projections are off the base projection, if there are
55+
// multiple derefs in the middle of projection, it might cause
56+
// unsoundness, to not let that happen we break the loop.
57+
break;
58+
}
59+
}
60+
}
61+
_ => (),
62+
}
63+
}
64+
}
65+
patch.apply(body);
66+
}
67+
68+
impl<'tcx> MirPass<'tcx> for Derefer {
69+
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
70+
deref_finder(tcx, body);
71+
}
72+
}

‎compiler/rustc_mir_transform/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ mod const_prop_lint;
5353
mod coverage;
5454
mod deaggregator;
5555
mod deduplicate_blocks;
56+
mod deref_separator;
5657
mod dest_prop;
5758
pub mod dump_mir;
5859
mod early_otherwise_branch;
@@ -431,6 +432,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
431432
// `Deaggregator` is conceptually part of MIR building, some backends rely on it happening
432433
// and it can help optimizations.
433434
&deaggregator::Deaggregator,
435+
&deref_separator::Derefer,
434436
&Lint(const_prop_lint::ConstProp),
435437
];
436438

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
- // MIR for `main` before Derefer
2+
+ // MIR for `main` after Derefer
3+
4+
fn main() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/derefer_test.rs:2:11: 2:11
6+
let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test.rs:3:9: 3:14
7+
let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:4:22: 4:28
8+
+ let mut _6: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:5:13: 5:26
9+
+ let mut _7: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:6:13: 6:26
10+
scope 1 {
11+
debug a => _1; // in scope 1 at $DIR/derefer_test.rs:3:9: 3:14
12+
let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test.rs:4:9: 4:14
13+
scope 2 {
14+
debug b => _2; // in scope 2 at $DIR/derefer_test.rs:4:9: 4:14
15+
let _4: &mut i32; // in scope 2 at $DIR/derefer_test.rs:5:9: 5:10
16+
scope 3 {
17+
debug x => _4; // in scope 3 at $DIR/derefer_test.rs:5:9: 5:10
18+
let _5: &mut i32; // in scope 3 at $DIR/derefer_test.rs:6:9: 6:10
19+
scope 4 {
20+
debug y => _5; // in scope 4 at $DIR/derefer_test.rs:6:9: 6:10
21+
}
22+
}
23+
}
24+
}
25+
26+
bb0: {
27+
StorageLive(_1); // scope 0 at $DIR/derefer_test.rs:3:9: 3:14
28+
(_1.0: i32) = const 42_i32; // scope 0 at $DIR/derefer_test.rs:3:17: 3:24
29+
(_1.1: i32) = const 43_i32; // scope 0 at $DIR/derefer_test.rs:3:17: 3:24
30+
StorageLive(_2); // scope 1 at $DIR/derefer_test.rs:4:9: 4:14
31+
StorageLive(_3); // scope 1 at $DIR/derefer_test.rs:4:22: 4:28
32+
_3 = &mut _1; // scope 1 at $DIR/derefer_test.rs:4:22: 4:28
33+
(_2.0: i32) = const 99_i32; // scope 1 at $DIR/derefer_test.rs:4:17: 4:29
34+
(_2.1: &mut (i32, i32)) = move _3; // scope 1 at $DIR/derefer_test.rs:4:17: 4:29
35+
StorageDead(_3); // scope 1 at $DIR/derefer_test.rs:4:28: 4:29
36+
StorageLive(_4); // scope 2 at $DIR/derefer_test.rs:5:9: 5:10
37+
- _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
38+
+ StorageLive(_6); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
39+
+ _6 = move (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
40+
+ _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
41+
+ StorageDead(_6); // scope 3 at $DIR/derefer_test.rs:6:9: 6:10
42+
StorageLive(_5); // scope 3 at $DIR/derefer_test.rs:6:9: 6:10
43+
- _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
44+
+ StorageLive(_7); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
45+
+ _7 = move (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
46+
+ _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
47+
+ StorageDead(_7); // scope 0 at $DIR/derefer_test.rs:2:11: 7:2
48+
_0 = const (); // scope 0 at $DIR/derefer_test.rs:2:11: 7:2
49+
StorageDead(_5); // scope 3 at $DIR/derefer_test.rs:7:1: 7:2
50+
StorageDead(_4); // scope 2 at $DIR/derefer_test.rs:7:1: 7:2
51+
StorageDead(_2); // scope 1 at $DIR/derefer_test.rs:7:1: 7:2
52+
StorageDead(_1); // scope 0 at $DIR/derefer_test.rs:7:1: 7:2
53+
return; // scope 0 at $DIR/derefer_test.rs:7:2: 7:2
54+
+ }
55+
+
56+
+ bb1 (cleanup): {
57+
+ resume; // scope 0 at $DIR/derefer_test.rs:2:1: 7:2
58+
}
59+
}
60+

‎src/test/mir-opt/derefer_test.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// EMIT_MIR derefer_test.main.Derefer.diff
2+
fn main() {
3+
let mut a = (42,43);
4+
let mut b = (99, &mut a);
5+
let x = &mut (*b.1).0;
6+
let y = &mut (*b.1).1;
7+
}

‎src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ fn b(_1: &mut Box<T>) -> &mut T {
1010
debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1111
let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1212
let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
13+
let mut _7: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1314
}
1415

1516
bb0: {
@@ -19,7 +20,10 @@ fn b(_1: &mut Box<T>) -> &mut T {
1920
_4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
2021
StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2122
StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
22-
_6 = &mut (*(*_4)); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
23+
StorageLive(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
24+
_7 = move (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
25+
_6 = &mut (*_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
26+
StorageDead(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2327
_5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2428
_3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2529
StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL

‎src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ fn d(_1: &Box<T>) -> &T {
77
let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
88
scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
99
debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
10+
let mut _4: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1011
}
1112

1213
bb0: {
1314
StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
1415
StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
1516
_3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
16-
_2 = &(*(*_3)); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
17+
StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
18+
_4 = move (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
19+
_2 = &(*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
20+
StorageDead(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1721
_0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
1822
StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:14: 18:15
1923
StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:1: 19:2

‎src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,9 @@
6464
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:11:5: 11:6
6565
return; // scope 0 at $DIR/lower_array_len.rs:12:2: 12:2
6666
}
67+
68+
bb6 (cleanup): {
69+
resume; // scope 0 at $DIR/lower_array_len.rs:6:1: 12:2
70+
}
6771
}
6872

‎src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,9 @@
7777
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:24:5: 24:6
7878
return; // scope 0 at $DIR/lower_array_len.rs:25:2: 25:2
7979
}
80+
81+
bb7 (cleanup): {
82+
resume; // scope 0 at $DIR/lower_array_len.rs:17:1: 25:2
83+
}
8084
}
8185

‎src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,9 @@
2626
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:31:13: 31:14
2727
return; // scope 0 at $DIR/lower_array_len.rs:32:2: 32:2
2828
}
29+
30+
bb2 (cleanup): {
31+
resume; // scope 0 at $DIR/lower_array_len.rs:30:1: 32:2
32+
}
2933
}
3034

‎src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,9 @@
2626
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:38:13: 38:14
2727
return; // scope 0 at $DIR/lower_array_len.rs:39:2: 39:2
2828
}
29+
30+
bb2 (cleanup): {
31+
resume; // scope 0 at $DIR/lower_array_len.rs:37:1: 39:2
32+
}
2933
}
3034

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /