Auto merge of #89030 - nbdd0121:box2, r=jonas-schievink
Introduce `Rvalue::ShallowInitBox` Polished version of #88700. Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward. In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP. `NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient. Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
This commit is contained in:
commit
e9f29a8519
31 changed files with 478 additions and 237 deletions
|
@ -2200,6 +2200,12 @@ pub enum Rvalue<'tcx> {
|
|||
/// that `Foo` has a destructor. These rvalues can be optimized
|
||||
/// away after type-checking and before lowering.
|
||||
Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
|
||||
|
||||
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
|
||||
///
|
||||
/// This is different a normal transmute because dataflow analysis will treat the box
|
||||
/// as initialized but its content as uninitialized.
|
||||
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
|
@ -2450,6 +2456,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
}),
|
||||
}
|
||||
}
|
||||
|
||||
ShallowInitBox(ref place, ref ty) => {
|
||||
write!(fmt, "ShallowInitBox({:?}, {:?})", place, ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
tcx.mk_generator(did, substs, movability)
|
||||
}
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +215,9 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
/// whether its only shallowly initialized (`Rvalue::Box`).
|
||||
pub fn initialization_state(&self) -> RvalueInitializationState {
|
||||
match *self {
|
||||
Rvalue::NullaryOp(NullOp::Box, _) => RvalueInitializationState::Shallow,
|
||||
Rvalue::NullaryOp(NullOp::Box, _) | Rvalue::ShallowInitBox(_, _) => {
|
||||
RvalueInitializationState::Shallow
|
||||
}
|
||||
_ => RvalueInitializationState::Deep,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,6 +210,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
|||
});
|
||||
Aggregate(kind, fields.fold_with(folder))
|
||||
}
|
||||
ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder), ty.fold_with(folder)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,6 +256,10 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
|||
}
|
||||
fields.visit_with(visitor)
|
||||
}
|
||||
ShallowInitBox(ref op, ty) => {
|
||||
op.visit_with(visitor)?;
|
||||
ty.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -753,6 +753,11 @@ macro_rules! make_mir_visitor {
|
|||
self.visit_operand(operand, location);
|
||||
}
|
||||
}
|
||||
|
||||
Rvalue::ShallowInitBox(operand, ty) => {
|
||||
self.visit_operand(operand, location);
|
||||
self.visit_ty(ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue