replace box_new in Box::new with write_via_move
requires lowering write_via_move during MIR building to make it just like an assignment
This commit is contained in:
parent
139651428d
commit
93d45480aa
12 changed files with 159 additions and 114 deletions
|
|
@ -0,0 +1,76 @@
|
|||
// MIR for `box_new` after CleanupPostBorrowck
|
||||
|
||||
fn box_new(_1: T) -> Box<[T; 1024]> {
|
||||
debug x => _1;
|
||||
let mut _0: std::boxed::Box<[T; 1024]>;
|
||||
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
let mut _4: &mut std::mem::MaybeUninit<[T; 1024]>;
|
||||
let mut _5: &mut std::mem::MaybeUninit<[T; 1024]>;
|
||||
let _6: ();
|
||||
let mut _7: *mut [T; 1024];
|
||||
let mut _8: T;
|
||||
let mut _9: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
scope 1 {
|
||||
debug b => _2;
|
||||
let _3: *mut [T; 1024];
|
||||
scope 2 {
|
||||
debug ptr => _3;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb7];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
nop;
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = &mut (*_2);
|
||||
_4 = &mut (*_5);
|
||||
_3 = MaybeUninit::<[T; 1024]>::as_mut_ptr(move _4) -> [return: bb2, unwind: bb6];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_4);
|
||||
nop;
|
||||
StorageDead(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = copy _3;
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
(*_7) = [move _8; 1024];
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageLive(_9);
|
||||
_9 = move _2;
|
||||
_0 = Box::<MaybeUninit<[T; 1024]>>::assume_init(move _9) -> [return: bb3, unwind: bb5];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_3);
|
||||
drop(_2) -> [return: bb4, unwind: bb7];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
drop(_9) -> [return: bb6, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb6 (cleanup): {
|
||||
drop(_2) -> [return: bb7, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
23
tests/mir-opt/building/write_via_move.rs
Normal file
23
tests/mir-opt/building/write_via_move.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//! Ensure we don't generate unnecessary copys for `write_via_move`.
|
||||
//@ compile-flags: -Zmir-opt-level=0
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
// Can't emit `built.after` here as that contains user type annotations which contain DefId that
|
||||
// change all the time.
|
||||
// EMIT_MIR write_via_move.box_new.CleanupPostBorrowck.after.mir
|
||||
// CHECK-LABEL: fn box_new
|
||||
#[inline(never)]
|
||||
fn box_new<T: Copy>(x: T) -> Box<[T; 1024]> {
|
||||
let mut b = Box::new_uninit();
|
||||
let ptr = mem::MaybeUninit::as_mut_ptr(&mut *b);
|
||||
// Ensure the array gets constructed directly into the deref'd pointer.
|
||||
// CHECK: (*[[TEMP1:_.+]]) = [{{(move|copy) _.+}}; 1024];
|
||||
unsafe { std::intrinsics::write_via_move(ptr, [x; 1024]) };
|
||||
unsafe { b.assume_init() }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
box_new(0);
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@
|
|||
+ StorageLive(_42);
|
||||
+ _42 = Option::<()>::None;
|
||||
+ _35 = copy ((*_37).0: std::option::Option<()>);
|
||||
+ ((*_37).0: std::option::Option<()>) = copy _42;
|
||||
+ ((*_37).0: std::option::Option<()>) = move _42;
|
||||
+ StorageDead(_42);
|
||||
+ StorageLive(_43);
|
||||
+ _43 = discriminant(_35);
|
||||
|
|
|
|||
|
|
@ -197,17 +197,6 @@ pub fn read_via_copy_uninhabited(r: &Never) -> Never {
|
|||
unsafe { core::intrinsics::read_via_copy(r) }
|
||||
}
|
||||
|
||||
// EMIT_MIR lower_intrinsics.write_via_move_string.LowerIntrinsics.diff
|
||||
pub fn write_via_move_string(r: &mut String, v: String) {
|
||||
// CHECK-LABEL: fn write_via_move_string(
|
||||
// CHECK: [[ptr:_.*]] = &raw mut (*_1);
|
||||
// CHECK: [[tmp:_.*]] = move _2;
|
||||
// CHECK: (*[[ptr]]) = move [[tmp]];
|
||||
// CHECK: return;
|
||||
|
||||
unsafe { core::intrinsics::write_via_move(r, v) }
|
||||
}
|
||||
|
||||
pub enum Never {}
|
||||
|
||||
// EMIT_MIR lower_intrinsics.ptr_offset.LowerIntrinsics.diff
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
- // MIR for `write_via_move_string` before LowerIntrinsics
|
||||
+ // MIR for `write_via_move_string` after LowerIntrinsics
|
||||
|
||||
fn write_via_move_string(_1: &mut String, _2: String) -> () {
|
||||
debug r => _1;
|
||||
debug v => _2;
|
||||
let mut _0: ();
|
||||
let mut _3: *mut std::string::String;
|
||||
let mut _4: std::string::String;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
_3 = &raw mut (*_1);
|
||||
StorageLive(_4);
|
||||
_4 = move _2;
|
||||
- _0 = write_via_move::<String>(move _3, move _4) -> [return: bb1, unwind unreachable];
|
||||
+ (*_3) = move _4;
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
- // MIR for `write_via_move_string` before LowerIntrinsics
|
||||
+ // MIR for `write_via_move_string` after LowerIntrinsics
|
||||
|
||||
fn write_via_move_string(_1: &mut String, _2: String) -> () {
|
||||
debug r => _1;
|
||||
debug v => _2;
|
||||
let mut _0: ();
|
||||
let mut _3: *mut std::string::String;
|
||||
let mut _4: std::string::String;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
_3 = &raw mut (*_1);
|
||||
StorageLive(_4);
|
||||
_4 = move _2;
|
||||
- _0 = write_via_move::<String>(move _3, move _4) -> [return: bb1, unwind unreachable];
|
||||
+ (*_3) = move _4;
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,19 +1,24 @@
|
|||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||
|
|
||||
= note: evaluation of `<std::mem::MaybeUninit<[&usize; usize::MAX]> as std::mem::SizedTypeProperties>::SIZE` failed here
|
||||
|
||||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||
|
|
||||
= note: evaluation of `<std::mem::MaybeUninit<[&usize; usize::MAX]> as std::mem::SizedTypeProperties>::ALIGN` failed here
|
||||
|
||||
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new_uninit_in`
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
|
||||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||
|
|
||||
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here
|
||||
|
||||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||
|
|
||||
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here
|
||||
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::try_new_uninit_in`
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
|
||||
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new`
|
||||
--> $DIR/issue-17913.rs:16:21
|
||||
|
|
||||
LL | let a: Box<_> = Box::new([&n; SIZE]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue