Skip to content

Commit fb212e8

Browse files
committed
Remove an extra monomorphize and try to be smarter about tuples
1 parent 7cb89e3 commit fb212e8

File tree

3 files changed

+36
-20
lines changed

3 files changed

+36
-20
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3686,6 +3686,7 @@ name = "rustc_codegen_ssa"
36863686
version = "0.0.0"
36873687
dependencies = [
36883688
"ar_archive_writer",
3689+
"arrayvec",
36893690
"bitflags 2.5.0",
36903691
"cc",
36913692
"itertools 0.12.1",

compiler/rustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
[dependencies]
77
# tidy-alphabetical-start
88
ar_archive_writer = "0.1.5"
9+
arrayvec = { version = "0.7", default-features = false }
910
bitflags = "2.4.1"
1011
cc = "1.0.90"
1112
itertools = "0.12"

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+34-20
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
1515
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
1616
use rustc_session::config::OptLevel;
1717
use rustc_span::{Span, DUMMY_SP};
18-
use rustc_target::abi::{self, FieldIdx, FIRST_VARIANT};
18+
use rustc_target::abi::{self, FIRST_VARIANT};
19+
20+
use arrayvec::ArrayVec;
1921

2022
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2123
#[instrument(level = "trace", skip(self, bx))]
@@ -722,25 +724,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
722724
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
723725
mir::Rvalue::Repeat(..) => {
724726
// According to `rvalue_creates_operand`, only ZST
725-
// repat rvalues are allowed to be operands.
727+
// repeat rvalues are allowed to be operands.
726728
let ty = rvalue.ty(self.mir, self.cx.tcx());
727729
OperandRef::zero_sized(self.cx.layout_of(self.monomorphize(ty)))
728730
}
729731
mir::Rvalue::Aggregate(ref kind, ref fields) => {
730732
let ty = rvalue.ty(self.mir, self.cx.tcx());
731733
let ty = self.monomorphize(ty);
732-
let layout = self.cx.layout_of(self.monomorphize(ty));
734+
let layout = self.cx.layout_of(ty);
733735
match **kind {
734736
_ if layout.is_zst() => OperandRef::zero_sized(layout),
735737
mir::AggregateKind::Tuple => {
736-
debug_assert_eq!(
737-
fields.len(),
738-
2,
739-
"We should only get pairs, but got {rvalue:?}"
738+
debug_assert!(
739+
self.cx.is_backend_scalar_pair(layout),
740+
"Expected a scalar pair, but this isn't: {layout:?}",
740741
);
741-
let a = self.codegen_operand(bx, &fields[FieldIdx::ZERO]);
742-
let b = self.codegen_operand(bx, &fields[FieldIdx::from_u32(1)]);
743-
let val = OperandValue::Pair(a.immediate(), b.immediate());
742+
let mut immediates = ArrayVec::<Bx::Value, 2>::new();
743+
for (field_idx, field) in fields.iter_enumerated() {
744+
let mut push = |v| {
745+
immediates.try_push(v).unwrap_or_else(|_| {
746+
bug!("Too many immediates at {field_idx:?} in {layout:?}")
747+
})
748+
};
749+
750+
let op = self.codegen_operand(bx, field);
751+
match op.val {
752+
OperandValue::ZeroSized => {}
753+
OperandValue::Immediate(v) => push(v),
754+
OperandValue::Pair(v, w) => {
755+
push(v);
756+
push(w);
757+
}
758+
OperandValue::Ref(_) => {
759+
bug!("reference operand for field {field_idx:?} in {layout:?}")
760+
}
761+
}
762+
}
763+
let [a, b] = immediates.into_inner().unwrap();
764+
let val = OperandValue::Pair(a, b);
744765
OperandRef { val, layout }
745766
}
746767
mir::AggregateKind::Adt(..) => {
@@ -1070,23 +1091,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10701091
let layout = self.cx.spanned_layout_of(ty, span);
10711092
layout.is_zst()
10721093
}
1073-
mir::Rvalue::Aggregate(ref kind, ref fields) => {
1094+
mir::Rvalue::Aggregate(ref kind, _) => {
10741095
let ty = rvalue.ty(self.mir, self.cx.tcx());
10751096
let ty = self.monomorphize(ty);
10761097
let layout = self.cx.spanned_layout_of(ty, span);
10771098
match **kind {
10781099
// OperandValue::ZeroSized is easy
10791100
_ if layout.is_zst() => true,
1080-
// 2-Tuple of scalars is an easy scalar pair
1101+
// If a tuple is a scalar pair, we can grab the immediates from the operands
10811102
mir::AggregateKind::Tuple => {
1082-
fields.len() == 2
1083-
&& self.cx.is_backend_scalar_pair(layout)
1084-
&& fields.iter().all(|field| {
1085-
let field_ty = field.ty(self.mir, self.cx.tcx());
1086-
let field_ty = self.monomorphize(field_ty);
1087-
let field_layout = self.cx.spanned_layout_of(field_ty, span);
1088-
self.cx.is_backend_immediate(field_layout)
1089-
})
1103+
self.cx.is_backend_scalar_pair(layout)
10901104
}
10911105
// If a non-union is transparent, we can pass it along
10921106
mir::AggregateKind::Adt(_, _, _, _, None) => {

0 commit comments

Comments
 (0)