Skip to content

Commit b63f8b6

Browse files
committed
Put PlaceValue into OperandValue::Ref, rather than 3 tuple fields
1 parent 4431fc4 commit b63f8b6

File tree

8 files changed

+76
-63
lines changed

8 files changed

+76
-63
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -999,8 +999,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
999999
}
10001000
}
10011001

1002-
let val = if let Some(llextra) = place.val.llextra {
1003-
OperandValue::Ref(place.val.llval, Some(llextra), place.val.align)
1002+
let val = if let Some(_) = place.val.llextra {
1003+
// FIXME: Merge with the `else` below?
1004+
OperandValue::Ref(place.val)
10041005
} else if place.layout.is_gcc_immediate() {
10051006
let load = self.load(place.layout.gcc_type(self), place.val.llval, place.val.align);
10061007
if let abi::Abi::Scalar(ref scalar) = place.layout.abi {
@@ -1031,7 +1032,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
10311032
load(1, b, place.val.align.restrict_for_offset(b_offset)),
10321033
)
10331034
} else {
1034-
OperandValue::Ref(place.val.llval, None, place.val.align)
1035+
OperandValue::Ref(place.val)
10351036
};
10361037

10371038
OperandRef { val, layout: place.layout }

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_codegen_ssa::base::wants_msvc_seh;
1111
use rustc_codegen_ssa::common::IntPredicate;
1212
use rustc_codegen_ssa::errors::InvalidMonomorphization;
1313
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
14-
use rustc_codegen_ssa::mir::place::PlaceRef;
14+
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
1515
use rustc_codegen_ssa::traits::{
1616
ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods,
1717
};
@@ -502,7 +502,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
502502
return;
503503
}
504504
if self.is_sized_indirect() {
505-
OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst)
505+
OperandValue::Ref(PlaceValue::new_sized(val, self.layout.align.abi)).store(bx, dst)
506506
} else if self.is_unsized_indirect() {
507507
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
508508
} else if let PassMode::Cast { ref cast, .. } = self.mode {
@@ -571,7 +571,12 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
571571
OperandValue::Pair(next(), next()).store(bx, dst);
572572
}
573573
PassMode::Indirect { meta_attrs: Some(_), .. } => {
574-
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
574+
let place_val = PlaceValue {
575+
llval: next(),
576+
llextra: Some(next()),
577+
align: self.layout.align.abi,
578+
};
579+
OperandValue::Ref(place_val).store(bx, dst);
575580
}
576581
PassMode::Direct(_)
577582
| PassMode::Indirect { meta_attrs: None, .. }

compiler/rustc_codegen_llvm/src/abi.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::type_of::LayoutLlvmExt;
77
use crate::value::Value;
88

99
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
10-
use rustc_codegen_ssa::mir::place::PlaceRef;
10+
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
1111
use rustc_codegen_ssa::traits::*;
1212
use rustc_codegen_ssa::MemFlags;
1313
use rustc_middle::bug;
@@ -207,7 +207,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
207207
// Sized indirect arguments
208208
PassMode::Indirect { attrs, meta_attrs: None, on_stack: _ } => {
209209
let align = attrs.pointee_align.unwrap_or(self.layout.align.abi);
210-
OperandValue::Ref(val, None, align).store(bx, dst);
210+
OperandValue::Ref(PlaceValue::new_sized(val, align)).store(bx, dst);
211211
}
212212
// Unsized indirect qrguments
213213
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
@@ -265,7 +265,12 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
265265
OperandValue::Pair(next(), next()).store(bx, dst);
266266
}
267267
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
268-
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
268+
let place_val = PlaceValue {
269+
llval: next(),
270+
llextra: Some(next()),
271+
align: self.layout.align.abi,
272+
};
273+
OperandValue::Ref(place_val).store(bx, dst);
269274
}
270275
PassMode::Direct(_)
271276
| PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ }

compiler/rustc_codegen_llvm/src/builder.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
579579
}
580580
}
581581

582-
let val = if let Some(llextra) = place.val.llextra {
583-
OperandValue::Ref(place.val.llval, Some(llextra), place.val.align)
582+
let val = if let Some(_) = place.val.llextra {
583+
// FIXME: Merge with the `else` below?
584+
OperandValue::Ref(place.val)
584585
} else if place.layout.is_llvm_immediate() {
585586
let mut const_llval = None;
586587
let llty = place.layout.llvm_type(self);
@@ -623,7 +624,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
623624
load(1, b, place.layout, place.val.align.restrict_for_offset(b_offset), b_offset),
624625
)
625626
} else {
626-
OperandValue::Ref(place.val.llval, None, place.val.align)
627+
OperandValue::Ref(place.val)
627628
};
628629

629630
OperandRef { val, layout: place.layout }

compiler/rustc_codegen_ssa/src/mir/block.rs

+26-26
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
455455

456456
PassMode::Direct(_) | PassMode::Pair(..) => {
457457
let op = self.codegen_consume(bx, mir::Place::return_place().as_ref());
458-
if let Ref(llval, _, align) = op.val {
459-
bx.load(bx.backend_type(op.layout), llval, align)
458+
if let Ref(place_val) = op.val {
459+
bx.load(bx.backend_type(op.layout), place_val.llval, place_val.align)
460460
} else {
461461
op.immediate_or_packed_pair(bx)
462462
}
@@ -466,10 +466,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
466466
let op = match self.locals[mir::RETURN_PLACE] {
467467
LocalRef::Operand(op) => op,
468468
LocalRef::PendingOperand => bug!("use of return before def"),
469-
LocalRef::Place(cg_place) => OperandRef {
470-
val: Ref(cg_place.val.llval, None, cg_place.val.align),
471-
layout: cg_place.layout,
472-
},
469+
LocalRef::Place(cg_place) => {
470+
OperandRef { val: Ref(cg_place.val), layout: cg_place.layout }
471+
}
473472
LocalRef::UnsizedPlace(_) => bug!("return type must be sized"),
474473
};
475474
let llslot = match op.val {
@@ -478,9 +477,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
478477
op.val.store(bx, scratch);
479478
scratch.val.llval
480479
}
481-
Ref(llval, _, align) => {
482-
assert_eq!(align, op.layout.align.abi, "return place is unaligned!");
483-
llval
480+
Ref(place_val) => {
481+
assert_eq!(
482+
place_val.align, op.layout.align.abi,
483+
"return place is unaligned!"
484+
);
485+
place_val.llval
484486
}
485487
ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"),
486488
};
@@ -1032,7 +1034,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10321034
llargs.push(data_ptr);
10331035
continue 'make_args;
10341036
}
1035-
Ref(data_ptr, Some(meta), _) => {
1037+
Ref(PlaceValue { llval: data_ptr, llextra: Some(meta), .. }) => {
10361038
// by-value dynamic dispatch
10371039
llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
10381040
bx,
@@ -1079,12 +1081,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10791081
// The callee needs to own the argument memory if we pass it
10801082
// by-ref, so make a local copy of non-immediate constants.
10811083
match (&arg.node, op.val) {
1082-
(&mir::Operand::Copy(_), Ref(_, None, _))
1083-
| (&mir::Operand::Constant(_), Ref(_, None, _)) => {
1084+
(&mir::Operand::Copy(_), Ref(PlaceValue { llextra: None, .. }))
1085+
| (&mir::Operand::Constant(_), Ref(PlaceValue { llextra: None, .. })) => {
10841086
let tmp = PlaceRef::alloca(bx, op.layout);
10851087
bx.lifetime_start(tmp.val.llval, tmp.layout.size);
10861088
op.val.store(bx, tmp);
1087-
op.val = Ref(tmp.val.llval, None, tmp.val.align);
1089+
op.val = Ref(tmp.val);
10881090
copied_constant_arguments.push(tmp);
10891091
}
10901092
_ => {}
@@ -1428,7 +1430,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14281430
_ => bug!("codegen_argument: {:?} invalid for pair argument", op),
14291431
},
14301432
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => match op.val {
1431-
Ref(a, Some(b), _) => {
1433+
Ref(PlaceValue { llval: a, llextra: Some(b), .. }) => {
14321434
llargs.push(a);
14331435
llargs.push(b);
14341436
return;
@@ -1459,28 +1461,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14591461
}
14601462
_ => (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false),
14611463
},
1462-
Ref(llval, llextra, align) => match arg.mode {
1464+
Ref(op_place_val) => match arg.mode {
14631465
PassMode::Indirect { attrs, .. } => {
14641466
let required_align = match attrs.pointee_align {
14651467
Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi),
14661468
None => arg.layout.align.abi,
14671469
};
1468-
if align < required_align {
1470+
if op_place_val.align < required_align {
14691471
// For `foo(packed.large_field)`, and types with <4 byte alignment on x86,
14701472
// alignment requirements may be higher than the type's alignment, so copy
14711473
// to a higher-aligned alloca.
14721474
let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align);
1473-
let op_place = PlaceRef {
1474-
val: PlaceValue { llval, llextra, align },
1475-
layout: op.layout,
1476-
};
1475+
let op_place = PlaceRef { val: op_place_val, layout: op.layout };
14771476
bx.typed_place_copy(scratch, op_place);
14781477
(scratch.val.llval, scratch.val.align, true)
14791478
} else {
1480-
(llval, align, true)
1479+
(op_place_val.llval, op_place_val.align, true)
14811480
}
14821481
}
1483-
_ => (llval, align, true),
1482+
_ => (op_place_val.llval, op_place_val.align, true),
14841483
},
14851484
ZeroSized => match arg.mode {
14861485
PassMode::Indirect { on_stack, .. } => {
@@ -1560,15 +1559,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
15601559
let tuple = self.codegen_operand(bx, operand);
15611560

15621561
// Handle both by-ref and immediate tuples.
1563-
if let Ref(llval, None, align) = tuple.val {
1564-
let tuple_ptr = PlaceRef::new_sized_aligned(llval, tuple.layout, align);
1562+
if let Ref(place_val) = tuple.val {
1563+
if place_val.llextra.is_some() {
1564+
bug!("closure arguments must be sized");
1565+
}
1566+
let tuple_ptr = PlaceRef { val: place_val, layout: tuple.layout };
15651567
for i in 0..tuple.layout.fields.count() {
15661568
let field_ptr = tuple_ptr.project_field(bx, i);
15671569
let field = bx.load_operand(field_ptr);
15681570
self.codegen_argument(bx, field, llargs, &args[i]);
15691571
}
1570-
} else if let Ref(_, Some(_), _) = tuple.val {
1571-
bug!("closure arguments must be sized")
15721572
} else {
15731573
// If the tuple is immediate, the elements are as well.
15741574
for i in 0..tuple.layout.fields.count() {

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_span::{BytePos, Span};
1414
use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx};
1515

1616
use super::operand::{OperandRef, OperandValue};
17-
use super::place::PlaceRef;
17+
use super::place::{PlaceRef, PlaceValue};
1818
use super::{FunctionCx, LocalRef};
1919

2020
use std::ops::Range;
@@ -334,7 +334,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
334334
bx.set_var_name(place.val.llval, name);
335335
}
336336
LocalRef::Operand(operand) => match operand.val {
337-
OperandValue::Ref(x, ..) | OperandValue::Immediate(x) => {
337+
OperandValue::Ref(PlaceValue { llval: x, .. }) | OperandValue::Immediate(x) => {
338338
bx.set_var_name(x, name);
339339
}
340340
OperandValue::Pair(a, b) => {

compiler/rustc_codegen_ssa/src/mir/operand.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@ pub enum OperandValue<V> {
2323
/// The second value, if any, is the extra data (vtable or length)
2424
/// which indicates that it refers to an unsized rvalue.
2525
///
26-
/// An `OperandValue` has this variant for types which are neither
27-
/// `Immediate` nor `Pair`s. The backend value in this variant must be a
28-
/// pointer to the *non*-immediate backend type. That pointee type is the
26+
/// An `OperandValue` *must* be this variant for any type for which
27+
/// [`LayoutTypeMethods::is_backend_ref`] returns `true`.
28+
/// (That basically amounts to "isn't one of the other variants".)
29+
///
30+
/// This holds a [`PlaceValue`] (like a [`PlaceRef`] does) with a pointer
31+
/// to the location holding the value. The type behind that pointer is the
2932
/// one returned by [`LayoutTypeMethods::backend_type`].
30-
Ref(V, Option<V>, Align),
33+
Ref(PlaceValue<V>),
3134
/// A single LLVM immediate value.
3235
///
3336
/// An `OperandValue` *must* be this variant for any type for which
@@ -362,7 +365,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
362365
OperandValue::Pair(bx.const_poison(ibty0), bx.const_poison(ibty1))
363366
} else {
364367
let ptr = bx.cx().type_ptr();
365-
OperandValue::Ref(bx.const_poison(ptr), None, layout.align.abi)
368+
OperandValue::Ref(PlaceValue::new_sized(bx.const_poison(ptr), layout.align.abi))
366369
}
367370
}
368371

@@ -410,17 +413,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
410413
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
411414
// value is through `undef`/`poison`, and the store itself is useless.
412415
}
413-
OperandValue::Ref(llval, None, source_align) => {
416+
OperandValue::Ref(val) => {
414417
assert!(dest.layout.is_sized(), "cannot directly store unsized values");
415-
let source_place = PlaceRef {
416-
val: PlaceValue::new_sized(llval, source_align),
417-
layout: dest.layout,
418-
};
418+
if val.llextra.is_some() {
419+
bug!("cannot directly store unsized values");
420+
}
421+
let source_place = PlaceRef { val, layout: dest.layout };
419422
bx.typed_place_copy_with_flags(dest, source_place, flags);
420423
}
421-
OperandValue::Ref(_, Some(_), _) => {
422-
bug!("cannot directly store unsized values");
423-
}
424424
OperandValue::Immediate(s) => {
425425
let val = bx.from_immediate(s);
426426
bx.store_with_flags(val, dest.val.llval, dest.val.align, flags);
@@ -457,7 +457,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
457457
.unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest))
458458
.ty;
459459

460-
let OperandValue::Ref(llptr, Some(llextra), _) = self else {
460+
let OperandValue::Ref(PlaceValue { llval: llptr, llextra: Some(llextra), .. }) = self
461+
else {
461462
bug!("store_unsized called with a sized value (or with an extern type)")
462463
};
463464

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6868
base::coerce_unsized_into(bx, scratch, dest);
6969
scratch.storage_dead(bx);
7070
}
71-
OperandValue::Ref(llref, None, align) => {
72-
let source = PlaceRef::new_sized_aligned(llref, operand.layout, align);
71+
OperandValue::Ref(val) => {
72+
if val.llextra.is_some() {
73+
bug!("unsized coercion on an unsized rvalue");
74+
}
75+
let source = PlaceRef { val, layout: operand.layout };
7376
base::coerce_unsized_into(bx, source, dest);
7477
}
75-
OperandValue::Ref(_, Some(_), _) => {
76-
bug!("unsized coercion on an unsized rvalue");
77-
}
7878
OperandValue::ZeroSized => {
7979
bug!("unsized coercion on a ZST rvalue");
8080
}
@@ -220,10 +220,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
220220
let cast_kind = self.value_kind(cast);
221221

222222
match operand.val {
223-
OperandValue::Ref(ptr, meta, align) => {
224-
debug_assert_eq!(meta, None);
223+
OperandValue::Ref(source_place_val) => {
224+
debug_assert_eq!(source_place_val.llextra, None);
225225
debug_assert!(matches!(operand_kind, OperandValueKind::Ref));
226-
let fake_place = PlaceRef::new_sized_aligned(ptr, cast, align);
226+
let fake_place = PlaceRef { val: source_place_val, layout: cast };
227227
Some(bx.load_operand(fake_place).val)
228228
}
229229
OperandValue::ZeroSized => {
@@ -490,7 +490,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
490490
}
491491
mir::CastKind::DynStar => {
492492
let (lldata, llextra) = match operand.val {
493-
OperandValue::Ref(_, _, _) => todo!(),
493+
OperandValue::Ref(..) => todo!(),
494494
OperandValue::Immediate(v) => (v, None),
495495
OperandValue::Pair(v, l) => (v, Some(l)),
496496
OperandValue::ZeroSized => bug!("ZST -- which is not PointerLike -- in DynStar"),

0 commit comments

Comments
 (0)