Auto merge of #142911 - mejrs:unsized, r=compiler-errors
Remove support for dynamic allocas Followup to rust-lang/rust#141811
This commit is contained in:
@@ -140,8 +140,13 @@ enum LocalRef<'tcx, V> {
|
||||
Place(PlaceRef<'tcx, V>),
|
||||
/// `UnsizedPlace(p)`: `p` itself is a thin pointer (indirect place).
|
||||
/// `*p` is the wide pointer that references the actual unsized place.
|
||||
/// Every time it is initialized, we have to reallocate the place
|
||||
/// and update the wide pointer. That's the reason why it is indirect.
|
||||
///
|
||||
/// MIR only supports unsized args, not dynamically-sized locals, so
|
||||
/// new unsized temps don't exist and we must reuse the referred-to place.
|
||||
///
|
||||
/// FIXME: Since the removal of unsized locals in <https://github.com/rust-lang/rust/pull/142911>,
|
||||
/// can we maybe use `Place` here? Or refactor it in another way? There are quite a few
|
||||
/// `UnsizedPlace => bug` branches now.
|
||||
UnsizedPlace(PlaceRef<'tcx, V>),
|
||||
/// The backend [`OperandValue`] has already been generated.
|
||||
Operand(OperandRef<'tcx, V>),
|
||||
@@ -498,7 +503,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
LocalRef::Place(PlaceRef::new_sized(llarg, arg.layout))
|
||||
}
|
||||
}
|
||||
// Unsized indirect qrguments
|
||||
// Unsized indirect arguments
|
||||
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
|
||||
// As the storage for the indirect argument lives during
|
||||
// the whole function call, we just copy the wide pointer.
|
||||
|
||||
@@ -16,9 +16,9 @@ use tracing::{debug, instrument};
|
||||
use super::place::{PlaceRef, PlaceValue};
|
||||
use super::rvalue::transmute_scalar;
|
||||
use super::{FunctionCx, LocalRef};
|
||||
use crate::MemFlags;
|
||||
use crate::common::IntPredicate;
|
||||
use crate::traits::*;
|
||||
use crate::{MemFlags, size_of_val};
|
||||
|
||||
/// The representation of a Rust value. The enum variant is in fact
|
||||
/// uniquely determined by the value's type, but is kept as a
|
||||
@@ -861,44 +861,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn store_unsized<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
self,
|
||||
bx: &mut Bx,
|
||||
indirect_dest: PlaceRef<'tcx, V>,
|
||||
) {
|
||||
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
|
||||
// `indirect_dest` must have `*mut T` type. We extract `T` out of it.
|
||||
let unsized_ty = indirect_dest
|
||||
.layout
|
||||
.ty
|
||||
.builtin_deref(true)
|
||||
.unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest));
|
||||
|
||||
let OperandValue::Ref(PlaceValue { llval: llptr, llextra: Some(llextra), .. }) = self
|
||||
else {
|
||||
bug!("store_unsized called with a sized value (or with an extern type)")
|
||||
};
|
||||
|
||||
// Allocate an appropriate region on the stack, and copy the value into it. Since alloca
|
||||
// doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
|
||||
// pointer manually.
|
||||
let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
|
||||
let one = bx.const_usize(1);
|
||||
let align_minus_1 = bx.sub(align, one);
|
||||
let size_extra = bx.add(size, align_minus_1);
|
||||
let min_align = Align::ONE;
|
||||
let alloca = bx.dynamic_alloca(size_extra, min_align);
|
||||
let address = bx.ptrtoint(alloca, bx.type_isize());
|
||||
let neg_address = bx.neg(address);
|
||||
let offset = bx.and(neg_address, align_minus_1);
|
||||
let dst = bx.inbounds_ptradd(alloca, offset);
|
||||
bx.memcpy(dst, min_align, llptr, min_align, size, MemFlags::empty());
|
||||
|
||||
// Store the allocated region and the extra to the indirect place.
|
||||
let indirect_operand = OperandValue::Pair(dst, llextra);
|
||||
indirect_operand.store(bx, indirect_dest);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
@@ -327,27 +327,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
Some(imm)
|
||||
}
|
||||
|
||||
pub(crate) fn codegen_rvalue_unsized(
|
||||
&mut self,
|
||||
bx: &mut Bx,
|
||||
indirect_dest: PlaceRef<'tcx, Bx::Value>,
|
||||
rvalue: &mir::Rvalue<'tcx>,
|
||||
) {
|
||||
debug!(
|
||||
"codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})",
|
||||
indirect_dest.val.llval, rvalue
|
||||
);
|
||||
|
||||
match *rvalue {
|
||||
mir::Rvalue::Use(ref operand) => {
|
||||
let cg_operand = self.codegen_operand(bx, operand);
|
||||
cg_operand.val.store_unsized(bx, indirect_dest);
|
||||
}
|
||||
|
||||
_ => bug!("unsized assignment other than `Rvalue::Use`"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn codegen_rvalue_operand(
|
||||
&mut self,
|
||||
bx: &mut Bx,
|
||||
|
||||
@@ -15,7 +15,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
match self.locals[index] {
|
||||
LocalRef::Place(cg_dest) => self.codegen_rvalue(bx, cg_dest, rvalue),
|
||||
LocalRef::UnsizedPlace(cg_indirect_dest) => {
|
||||
self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue)
|
||||
let ty = cg_indirect_dest.layout.ty;
|
||||
span_bug!(
|
||||
statement.source_info.span,
|
||||
"cannot reallocate from `UnsizedPlace({ty})` \
|
||||
into `{rvalue:?}`; dynamic alloca is not supported",
|
||||
);
|
||||
}
|
||||
LocalRef::PendingOperand => {
|
||||
let operand = self.codegen_rvalue_operand(bx, rvalue);
|
||||
|
||||
@@ -224,7 +224,6 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value;
|
||||
|
||||
fn alloca(&mut self, size: Size, align: Align) -> Self::Value;
|
||||
fn dynamic_alloca(&mut self, size: Self::Value, align: Align) -> Self::Value;
|
||||
|
||||
fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value;
|
||||
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value;
|
||||
|
||||
Reference in New Issue
Block a user