Skip to content

Commit 6be7b0c

Browse files
committed
Auto merge of #124999 - scottmcm:unify-aggregate, r=nnethercote
Unify `Rvalue::Aggregate` paths in cg_ssa In #123840 and #123886 I added two different codepaths for `Rvalue::Aggregate` in `cg_ssa`. This merges them into one, since raw pointers are also immediates that can be built from the immediates of their "fields".
2 parents 982c9c1 + 99213ae commit 6be7b0c

File tree

4 files changed

+26
-22
lines changed

4 files changed

+26
-22
lines changed

compiler/rustc_abi/src/lib.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ impl<FieldIdx: Idx> FieldsShape<FieldIdx> {
12551255

12561256
/// Gets source indices of the fields by increasing offsets.
12571257
#[inline]
1258-
pub fn index_by_increasing_offset(&self) -> impl Iterator<Item = usize> + '_ {
1258+
pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator<Item = usize> + '_ {
12591259
let mut inverse_small = [0u8; 64];
12601260
let mut inverse_big = IndexVec::new();
12611261
let use_small = self.count() <= inverse_small.len();
@@ -1271,7 +1271,12 @@ impl<FieldIdx: Idx> FieldsShape<FieldIdx> {
12711271
}
12721272
}
12731273

1274-
(0..self.count()).map(move |i| match *self {
1274+
// Primitives don't really have fields in the way that structs do,
1275+
// but having this return an empty iterator for them is unhelpful
1276+
// since that makes them look kinda like ZSTs, which they're not.
1277+
let pseudofield_count = if let FieldsShape::Primitive = self { 1 } else { self.count() };
1278+
1279+
(0..pseudofield_count).map(move |i| match *self {
12751280
FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
12761281
FieldsShape::Arbitrary { .. } => {
12771282
if use_small {

compiler/rustc_codegen_ssa/src/mir/operand.rs

+13
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ impl<V: CodegenObject> OperandValue<V> {
110110
let (llval, llextra) = self.pointer_parts();
111111
PlaceValue { llval, llextra, align }
112112
}
113+
114+
pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeMethods<'tcx>>(
115+
&self,
116+
cx: &Cx,
117+
ty: TyAndLayout<'tcx>,
118+
) -> bool {
119+
match self {
120+
OperandValue::ZeroSized => ty.is_zst(),
121+
OperandValue::Immediate(_) => cx.is_backend_immediate(ty),
122+
OperandValue::Pair(_, _) => cx.is_backend_scalar_pair(ty),
123+
OperandValue::Ref(_) => cx.is_backend_ref(ty),
124+
}
125+
}
113126
}
114127

115128
/// An `OperandRef` is an "SSA" reference to a Rust value, along with

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -696,24 +696,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
696696
OperandRef { val: OperandValue::Immediate(static_), layout }
697697
}
698698
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
699-
mir::Rvalue::Aggregate(box mir::AggregateKind::RawPtr(..), ref fields) => {
700-
let ty = rvalue.ty(self.mir, self.cx.tcx());
701-
let layout = self.cx.layout_of(self.monomorphize(ty));
702-
let [data, meta] = &*fields.raw else {
703-
bug!("RawPtr fields: {fields:?}");
704-
};
705-
let data = self.codegen_operand(bx, data);
706-
let meta = self.codegen_operand(bx, meta);
707-
match (data.val, meta.val) {
708-
(p @ OperandValue::Immediate(_), OperandValue::ZeroSized) => {
709-
OperandRef { val: p, layout }
710-
}
711-
(OperandValue::Immediate(p), OperandValue::Immediate(m)) => {
712-
OperandRef { val: OperandValue::Pair(p, m), layout }
713-
}
714-
_ => bug!("RawPtr operands {data:?} {meta:?}"),
715-
}
716-
}
717699
mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"),
718700
mir::Rvalue::Aggregate(_, ref fields) => {
719701
let ty = rvalue.ty(self.mir, self.cx.tcx());
@@ -748,6 +730,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
748730
);
749731

750732
let val = OperandValue::from_immediates(inputs);
733+
debug_assert!(
734+
val.is_expected_variant_for_type(self.cx, layout),
735+
"Made wrong variant {val:?} for type {layout:?}",
736+
);
751737
OperandRef { val, layout }
752738
}
753739
mir::Rvalue::ShallowInitBox(ref operand, content_ty) => {
@@ -792,7 +778,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
792778
debug_assert!(
793779
if bx.cx().type_has_metadata(ty) {
794780
matches!(val, OperandValue::Pair(..))
795-
} else {
781+
} else {
796782
matches!(val, OperandValue::Immediate(..))
797783
},
798784
"Address of place was unexpectedly {val:?} for pointee type {ty:?}",

tests/codegen/mir-aggregate-no-alloca.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub fn make_cell_of_bool(b: bool) -> std::cell::Cell<bool> {
5555
std::cell::Cell::new(b)
5656
}
5757

58-
// CHECK-LABLE: { i8, i16 } @make_cell_of_bool_and_short(i1 noundef zeroext %b, i16 noundef %s)
58+
// CHECK-LABEL: { i8, i16 } @make_cell_of_bool_and_short(i1 noundef zeroext %b, i16 noundef %s)
5959
#[no_mangle]
6060
pub fn make_cell_of_bool_and_short(b: bool, s: u16) -> std::cell::Cell<(bool, u16)> {
6161
// CHECK-NOT: alloca

0 commit comments

Comments
 (0)