Skip to content

Commit 7393c38

Browse files
committed
abi: switch scalar_pair_field_index to an offset.
1 parent c1cdc47 commit 7393c38

File tree

1 file changed

+45
-28
lines changed
  • crates/rustc_codegen_spirv/src

1 file changed

+45
-28
lines changed

crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -350,21 +350,21 @@ fn trans_type_impl<'tcx>(
350350
}
351351
.def_with_name(cx, span, TyLayoutNameKey::from(ty)),
352352
Abi::Scalar(ref scalar) => trans_scalar(cx, span, ty, scalar, None, is_immediate),
353-
Abi::ScalarPair(ref one, ref two) => {
354-
// Note! Do not pass through is_immediate here - they're wrapped in a struct, hence, not immediate.
355-
let one_spirv = trans_scalar(cx, span, ty, one, Some(0), false);
356-
let two_spirv = trans_scalar(cx, span, ty, two, Some(1), false);
353+
Abi::ScalarPair(ref a, ref b) => {
357354
// Note: We can't use auto_struct_layout here because the spirv types here might be undefined due to
358355
// recursive pointer types.
359-
let one_offset = Size::ZERO;
360-
let two_offset = one.value.size(cx).align_to(two.value.align(cx).abi);
356+
let a_offset = Size::ZERO;
357+
let b_offset = a.value.size(cx).align_to(b.value.align(cx).abi);
358+
// Note! Do not pass through is_immediate here - they're wrapped in a struct, hence, not immediate.
359+
let a = trans_scalar(cx, span, ty, a, Some(a_offset), false);
360+
let b = trans_scalar(cx, span, ty, b, Some(b_offset), false);
361361
let size = if ty.is_unsized() { None } else { Some(ty.size) };
362362
SpirvType::Adt {
363363
def_id: def_id_for_spirv_type_adt(ty),
364364
size,
365365
align: ty.align.abi,
366-
field_types: vec![one_spirv, two_spirv],
367-
field_offsets: vec![one_offset, two_offset],
366+
field_types: vec![a, b],
367+
field_offsets: vec![a_offset, b_offset],
368368
field_names: None,
369369
}
370370
.def_with_name(cx, span, TyLayoutNameKey::from(ty))
@@ -390,11 +390,16 @@ pub fn scalar_pair_element_backend_type<'tcx>(
390390
index: usize,
391391
is_immediate: bool,
392392
) -> Word {
393-
let scalar = match &ty.layout.abi {
394-
Abi::ScalarPair(a, b) => [a, b][index],
393+
let [a, b] = match &ty.layout.abi {
394+
Abi::ScalarPair(a, b) => [a, b],
395395
other => bug!("scalar_pair_element_backend_type invalid abi: {:?}", other),
396396
};
397-
trans_scalar(cx, span, ty, scalar, Some(index), is_immediate)
397+
let offset = match index {
398+
0 => Size::ZERO,
399+
1 => a.value.size(cx).align_to(b.value.align(cx).abi),
400+
_ => unreachable!(),
401+
};
402+
trans_scalar(cx, span, ty, [a, b][index], Some(offset), is_immediate)
398403
}
399404

400405
/// A "scalar" is a basic building block: bools, ints, floats, pointers. (i.e. not something complex like a struct)
@@ -409,7 +414,7 @@ fn trans_scalar<'tcx>(
409414
span: Span,
410415
ty: TyAndLayout<'tcx>,
411416
scalar: &Scalar,
412-
scalar_pair_field_index: Option<usize>,
417+
scalar_pair_field_offset: Option<Size>,
413418
is_immediate: bool,
414419
) -> Word {
415420
if is_immediate && scalar.is_bool() {
@@ -423,7 +428,7 @@ fn trans_scalar<'tcx>(
423428
Primitive::F32 => SpirvType::Float(32).def(span, cx),
424429
Primitive::F64 => SpirvType::Float(64).def(span, cx),
425430
Primitive::Pointer => {
426-
let pointee_ty = dig_scalar_pointee(cx, ty, scalar_pair_field_index);
431+
let pointee_ty = dig_scalar_pointee(cx, ty, scalar_pair_field_offset);
427432
// Pointers can be recursive. So, record what we're currently translating, and if we're already translating
428433
// the same type, emit an OpTypeForwardPointer and use that ID.
429434
if let Some(predefined_result) = cx
@@ -455,16 +460,21 @@ fn trans_scalar<'tcx>(
455460
fn dig_scalar_pointee<'tcx>(
456461
cx: &CodegenCx<'tcx>,
457462
ty: TyAndLayout<'tcx>,
458-
scalar_pair_field_index: Option<usize>,
463+
scalar_pair_field_offset: Option<Size>,
459464
) -> PointeeTy<'tcx> {
460465
match *ty.ty.kind() {
461466
TyKind::Ref(_, elem_ty, _) | TyKind::RawPtr(TypeAndMut { ty: elem_ty, .. }) => {
462467
let elem = cx.layout_of(elem_ty);
463-
match scalar_pair_field_index {
468+
match scalar_pair_field_offset {
464469
None => PointeeTy::Ty(elem),
465-
Some(scalar_pair_field_index) => {
470+
Some(scalar_pair_field_offset) => {
466471
if elem.is_unsized() {
467-
dig_scalar_pointee(cx, ty.field(cx, scalar_pair_field_index), None)
472+
let field_idx = if scalar_pair_field_offset == Size::ZERO {
473+
0
474+
} else {
475+
1
476+
};
477+
dig_scalar_pointee(cx, ty.field(cx, field_idx), None)
468478
} else {
469479
// This can sometimes happen in weird cases when going through the Adt case below - an ABI
470480
// of ScalarPair could be deduced, but it's actually e.g. a sized pointer followed by some other
@@ -475,25 +485,25 @@ fn dig_scalar_pointee<'tcx>(
475485
}
476486
}
477487
}
478-
TyKind::FnPtr(sig) if scalar_pair_field_index.is_none() => PointeeTy::Fn(sig),
488+
TyKind::FnPtr(sig) if scalar_pair_field_offset.is_none() => PointeeTy::Fn(sig),
479489
TyKind::Adt(def, _) if def.is_box() => {
480490
let ptr_ty = cx.layout_of(cx.tcx.mk_mut_ptr(ty.ty.boxed_ty()));
481-
dig_scalar_pointee(cx, ptr_ty, scalar_pair_field_index)
491+
dig_scalar_pointee(cx, ptr_ty, scalar_pair_field_offset)
482492
}
483493
TyKind::Tuple(_) | TyKind::Adt(..) | TyKind::Closure(..) => {
484-
dig_scalar_pointee_adt(cx, ty, scalar_pair_field_index)
494+
dig_scalar_pointee_adt(cx, ty, scalar_pair_field_offset)
485495
}
486496
ref kind => cx.tcx.sess.fatal(&format!(
487-
"TODO: Unimplemented Primitive::Pointer TyKind scalar_pair_field_index={:?} ({:#?}):\n{:#?}",
488-
scalar_pair_field_index, kind, ty
497+
"TODO: Unimplemented Primitive::Pointer TyKind scalar_pair_field_offset={:?} ({:#?}):\n{:#?}",
498+
scalar_pair_field_offset, kind, ty
489499
)),
490500
}
491501
}
492502

493503
fn dig_scalar_pointee_adt<'tcx>(
494504
cx: &CodegenCx<'tcx>,
495505
ty: TyAndLayout<'tcx>,
496-
scalar_pair_field_index: Option<usize>,
506+
scalar_pair_field_offset: Option<Size>,
497507
) -> PointeeTy<'tcx> {
498508
match &ty.variants {
499509
// If it's a Variants::Multiple, then we want to emit the type of the dataful variant, not the type of the
@@ -519,7 +529,7 @@ fn dig_scalar_pointee_adt<'tcx>(
519529
assert_eq!(1, adt.variants[dataful_variant].fields.len());
520530
assert_eq!(0, *tag_field);
521531
let field_ty = adt.variants[dataful_variant].fields[0].ty(cx.tcx, substs);
522-
dig_scalar_pointee(cx, cx.layout_of(field_ty), scalar_pair_field_index)
532+
dig_scalar_pointee(cx, cx.layout_of(field_ty), scalar_pair_field_offset)
523533
} else {
524534
bug!("Variants::Multiple not TyKind::Adt: {:#?}", ty)
525535
}
@@ -533,11 +543,18 @@ fn dig_scalar_pointee_adt<'tcx>(
533543
.map(|f| ty.field(cx, f))
534544
.filter(|f| !f.is_zst())
535545
.collect::<Vec<_>>();
536-
match scalar_pair_field_index {
537-
Some(scalar_pair_field_index) => match fields.len() {
538-
1 => dig_scalar_pointee(cx, fields[0], Some(scalar_pair_field_index)),
546+
match scalar_pair_field_offset {
547+
Some(scalar_pair_field_offset) => match fields.len() {
548+
1 => dig_scalar_pointee(cx, fields[0], Some(scalar_pair_field_offset)),
539549
// This case right here is the cause of the comment handling TyKind::Ref.
540-
2 => dig_scalar_pointee(cx, fields[scalar_pair_field_index], None),
550+
2 => {
551+
let field_idx = if scalar_pair_field_offset == Size::ZERO {
552+
0
553+
} else {
554+
1
555+
};
556+
dig_scalar_pointee(cx, fields[field_idx], None)
557+
}
541558
other => cx.tcx.sess.fatal(&format!(
542559
"Unable to dig scalar pair pointer type: fields length {}",
543560
other

0 commit comments

Comments
 (0)