Skip to content

Commit 1d7daa2

Browse files
compiler: rustc_abi::Abi => IrForm
The initial naming of "Abi" was an awful mistake, conveying wrong ideas about how psABIs worked and even more about what the enum meant. It was only meant to represent the way the value would be described to a codegen backend as it was lowered to that intermediate representation. It was never meant to mean anything about the actual psABI handling! The conflation is because LLVM typically will associate a certain form with a certain ABI, but even that does not hold when the special cases that actually exist arise, plus the IR annotations that modify the ABI. Reframe `rustc_abi::Abi` as the `IrForm` of the type, and also rename `IrForm::Aggregate` as `IrForm::Memory`. Unfortunately, due to the persistent misunderstandings, this too is now incorrect: - Scattered ABI-relevant representation code is entangled with IrForm - We do not necessarily compute the correct IrForm to get the backend to lower the type using the correct ABI - In various places `IrForm::Aggregate` is a "real" aggregate, in others it is in fact using memory, and in some cases it is actually a scalar! Often our backend lowering code handles this sort of thing right now. That will eventually be addressed by lifting duplicated ABI-handling code to either rustc_codegen_ssa or rustc_target as appropriate.
1 parent 5f5c243 commit 1d7daa2

File tree

60 files changed

+494
-451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+494
-451
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3906,6 +3906,7 @@ dependencies = [
39063906
name = "rustc_lint"
39073907
version = "0.0.0"
39083908
dependencies = [
3909+
"rustc_abi",
39093910
"rustc_ast",
39103911
"rustc_ast_pretty",
39113912
"rustc_attr",
@@ -4095,6 +4096,7 @@ version = "0.0.0"
40954096
dependencies = [
40964097
"either",
40974098
"itertools",
4099+
"rustc_abi",
40984100
"rustc_arena",
40994101
"rustc_ast",
41004102
"rustc_attr",

compiler/rustc_abi/src/callconv.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ mod abi {
66
#[cfg(feature = "nightly")]
77
use rustc_macros::HashStable_Generic;
88

9-
#[cfg(feature = "nightly")]
10-
use crate::{Abi, FieldsShape, TyAbiInterface, TyAndLayout};
119
use crate::{Align, HasDataLayout, Size};
10+
#[cfg(feature = "nightly")]
11+
use crate::{FieldsShape, IrForm, TyAbiInterface, TyAndLayout};
1212

1313
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
1414
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -128,27 +128,27 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
128128
where
129129
Ty: TyAbiInterface<'a, C> + Copy,
130130
{
131-
match self.abi {
132-
Abi::Uninhabited => Err(Heterogeneous),
131+
match self.ir_form {
132+
IrForm::Uninhabited => Err(Heterogeneous),
133133

134134
// The primitive for this algorithm.
135-
Abi::Scalar(scalar) => {
135+
IrForm::Scalar(scalar) => {
136136
let kind = match scalar.primitive() {
137137
abi::Int(..) | abi::Pointer(_) => RegKind::Integer,
138138
abi::Float(_) => RegKind::Float,
139139
};
140140
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
141141
}
142142

143-
Abi::Vector { .. } => {
143+
IrForm::Vector { .. } => {
144144
assert!(!self.is_zst());
145145
Ok(HomogeneousAggregate::Homogeneous(Reg {
146146
kind: RegKind::Vector,
147147
size: self.size,
148148
}))
149149
}
150150

151-
Abi::ScalarPair(..) | Abi::Aggregate { sized: true } => {
151+
IrForm::ScalarPair(..) | IrForm::Memory { sized: true } => {
152152
// Helper for computing `homogeneous_aggregate`, allowing a custom
153153
// starting offset (used below for handling variants).
154154
let from_fields_at =
@@ -246,7 +246,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
246246
Ok(result)
247247
}
248248
}
249-
Abi::Aggregate { sized: false } => Err(Heterogeneous),
249+
IrForm::Memory { sized: false } => Err(Heterogeneous),
250250
}
251251
}
252252
}

compiler/rustc_abi/src/layout.rs

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_index::Idx;
66
use tracing::debug;
77

88
use crate::{
9-
Abi, AbiAndPrefAlign, Align, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
9+
AbiAndPrefAlign, Align, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, IrForm,
1010
LayoutS, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding,
1111
Variants, WrappingRange,
1212
};
@@ -28,7 +28,7 @@ where
2828
VariantIdx: Idx,
2929
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
3030
{
31-
let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited());
31+
let uninhabited = fields.iter().any(|f| f.ir_form.is_uninhabited());
3232
// We cannot ignore alignment; that might lead us to entirely discard a variant and
3333
// produce an enum that is less aligned than it should be!
3434
let is_1zst = fields.iter().all(|f| f.is_1zst());
@@ -125,7 +125,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
125125
offsets: [Size::ZERO, b_offset].into(),
126126
memory_index: [0, 1].into(),
127127
},
128-
abi: Abi::ScalarPair(a, b),
128+
ir_form: IrForm::ScalarPair(a, b),
129129
largest_niche,
130130
align,
131131
size,
@@ -216,7 +216,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
216216
LayoutS {
217217
variants: Variants::Single { index: VariantIdx::new(0) },
218218
fields: FieldsShape::Primitive,
219-
abi: Abi::Uninhabited,
219+
ir_form: IrForm::Uninhabited,
220220
largest_niche: None,
221221
align: dl.i8_align,
222222
size: Size::ZERO,
@@ -331,7 +331,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
331331

332332
if let Ok(common) = common_non_zst_abi_and_align {
333333
// Discard valid range information and allow undef
334-
let field_abi = field.abi.to_union();
334+
let field_abi = field.ir_form.to_union();
335335

336336
if let Some((common_abi, common_align)) = common {
337337
if common_abi != field_abi {
@@ -340,7 +340,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
340340
} else {
341341
// Fields with the same non-Aggregate ABI should also
342342
// have the same alignment
343-
if !matches!(common_abi, Abi::Aggregate { .. }) {
343+
if !matches!(common_abi, IrForm::Memory { .. }) {
344344
assert_eq!(
345345
common_align, field.align.abi,
346346
"non-Aggregate field with matching ABI but differing alignment"
@@ -369,11 +369,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
369369
// If all non-ZST fields have the same ABI, we may forward that ABI
370370
// for the union as a whole, unless otherwise inhibited.
371371
let abi = match common_non_zst_abi_and_align {
372-
Err(AbiMismatch) | Ok(None) => Abi::Aggregate { sized: true },
372+
Err(AbiMismatch) | Ok(None) => IrForm::Memory { sized: true },
373373
Ok(Some((abi, _))) => {
374374
if abi.inherent_align(dl).map(|a| a.abi) != Some(align.abi) {
375375
// Mismatched alignment (e.g. union is #[repr(packed)]): disable opt
376-
Abi::Aggregate { sized: true }
376+
IrForm::Memory { sized: true }
377377
} else {
378378
abi
379379
}
@@ -387,7 +387,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
387387
Ok(LayoutS {
388388
variants: Variants::Single { index: only_variant_idx },
389389
fields: FieldsShape::Union(union_field_count),
390-
abi,
390+
ir_form: abi,
391391
largest_niche: None,
392392
align,
393393
size: size.align_to(align.abi),
@@ -434,23 +434,23 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
434434
// Already doesn't have any niches
435435
Scalar::Union { .. } => {}
436436
};
437-
match &mut st.abi {
438-
Abi::Uninhabited => {}
439-
Abi::Scalar(scalar) => hide_niches(scalar),
440-
Abi::ScalarPair(a, b) => {
437+
match &mut st.ir_form {
438+
IrForm::Uninhabited => {}
439+
IrForm::Scalar(scalar) => hide_niches(scalar),
440+
IrForm::ScalarPair(a, b) => {
441441
hide_niches(a);
442442
hide_niches(b);
443443
}
444-
Abi::Vector { element, count: _ } => hide_niches(element),
445-
Abi::Aggregate { sized: _ } => {}
444+
IrForm::Vector { element, count: _ } => hide_niches(element),
445+
IrForm::Memory { sized: _ } => {}
446446
}
447447
st.largest_niche = None;
448448
return Ok(st);
449449
}
450450

451451
let (start, end) = scalar_valid_range;
452-
match st.abi {
453-
Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
452+
match st.ir_form {
453+
IrForm::Scalar(ref mut scalar) | IrForm::ScalarPair(ref mut scalar, _) => {
454454
// Enlarging validity ranges would result in missed
455455
// optimizations, *not* wrongly assuming the inner
456456
// value is valid. e.g. unions already enlarge validity ranges,
@@ -607,8 +607,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
607607
}
608608

609609
// It can't be a Scalar or ScalarPair because the offset isn't 0.
610-
if !layout.abi.is_uninhabited() {
611-
layout.abi = Abi::Aggregate { sized: true };
610+
if !layout.ir_form.is_uninhabited() {
611+
layout.ir_form = IrForm::Memory { sized: true };
612612
}
613613
layout.size += this_offset;
614614

@@ -627,26 +627,26 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
627627
let same_size = size == variant_layouts[largest_variant_index].size;
628628
let same_align = align == variant_layouts[largest_variant_index].align;
629629

630-
let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) {
631-
Abi::Uninhabited
630+
let abi = if variant_layouts.iter().all(|v| v.ir_form.is_uninhabited()) {
631+
IrForm::Uninhabited
632632
} else if same_size && same_align && others_zst {
633-
match variant_layouts[largest_variant_index].abi {
633+
match variant_layouts[largest_variant_index].ir_form {
634634
// When the total alignment and size match, we can use the
635635
// same ABI as the scalar variant with the reserved niche.
636-
Abi::Scalar(_) => Abi::Scalar(niche_scalar),
637-
Abi::ScalarPair(first, second) => {
636+
IrForm::Scalar(_) => IrForm::Scalar(niche_scalar),
637+
IrForm::ScalarPair(first, second) => {
638638
// Only the niche is guaranteed to be initialised,
639639
// so use union layouts for the other primitive.
640640
if niche_offset == Size::ZERO {
641-
Abi::ScalarPair(niche_scalar, second.to_union())
641+
IrForm::ScalarPair(niche_scalar, second.to_union())
642642
} else {
643-
Abi::ScalarPair(first.to_union(), niche_scalar)
643+
IrForm::ScalarPair(first.to_union(), niche_scalar)
644644
}
645645
}
646-
_ => Abi::Aggregate { sized: true },
646+
_ => IrForm::Memory { sized: true },
647647
}
648648
} else {
649-
Abi::Aggregate { sized: true }
649+
IrForm::Memory { sized: true }
650650
};
651651

652652
let layout = LayoutS {
@@ -664,7 +664,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
664664
offsets: [niche_offset].into(),
665665
memory_index: [0].into(),
666666
},
667-
abi,
667+
ir_form: abi,
668668
largest_niche,
669669
size,
670670
align,
@@ -681,7 +681,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
681681
let discr_type = repr.discr_type();
682682
let bits = Integer::from_attr(dl, discr_type).size().bits();
683683
for (i, mut val) in discriminants {
684-
if !repr.c() && variants[i].iter().any(|f| f.abi.is_uninhabited()) {
684+
if !repr.c() && variants[i].iter().any(|f| f.ir_form.is_uninhabited()) {
685685
continue;
686686
}
687687
if discr_type.is_signed() {
@@ -833,14 +833,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
833833
end: (max as u128 & tag_mask),
834834
},
835835
};
836-
let mut abi = Abi::Aggregate { sized: true };
836+
let mut abi = IrForm::Memory { sized: true };
837837

838-
if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
839-
abi = Abi::Uninhabited;
838+
if layout_variants.iter().all(|v| v.ir_form.is_uninhabited()) {
839+
abi = IrForm::Uninhabited;
840840
} else if tag.size(dl) == size {
841841
// Make sure we only use scalar layout when the enum is entirely its
842842
// own tag (i.e. it has no padding nor any non-ZST variant fields).
843-
abi = Abi::Scalar(tag);
843+
abi = IrForm::Scalar(tag);
844844
} else {
845845
// Try to use a ScalarPair for all tagged enums.
846846
// That's possible only if we can find a common primitive type for all variants.
@@ -864,8 +864,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
864864
break;
865865
}
866866
};
867-
let prim = match field.abi {
868-
Abi::Scalar(scalar) => {
867+
let prim = match field.ir_form {
868+
IrForm::Scalar(scalar) => {
869869
common_prim_initialized_in_all_variants &=
870870
matches!(scalar, Scalar::Initialized { .. });
871871
scalar.primitive()
@@ -934,20 +934,20 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
934934
{
935935
// We can use `ScalarPair` only when it matches our
936936
// already computed layout (including `#[repr(C)]`).
937-
abi = pair.abi;
937+
abi = pair.ir_form;
938938
}
939939
}
940940
}
941941

942942
// If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the
943943
// variants to ensure they are consistent. This is because a downcast is
944944
// semantically a NOP, and thus should not affect layout.
945-
if matches!(abi, Abi::Scalar(..) | Abi::ScalarPair(..)) {
945+
if matches!(abi, IrForm::Scalar(..) | IrForm::ScalarPair(..)) {
946946
for variant in &mut layout_variants {
947947
// We only do this for variants with fields; the others are not accessed anyway.
948948
// Also do not overwrite any already existing "clever" ABIs.
949-
if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) {
950-
variant.abi = abi;
949+
if variant.fields.count() > 0 && matches!(variant.ir_form, IrForm::Memory { .. }) {
950+
variant.ir_form = abi;
951951
// Also need to bump up the size and alignment, so that the entire value fits
952952
// in here.
953953
variant.size = cmp::max(variant.size, size);
@@ -970,7 +970,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
970970
memory_index: [0].into(),
971971
},
972972
largest_niche,
973-
abi,
973+
ir_form: abi,
974974
align,
975975
size,
976976
max_repr_align,
@@ -1252,7 +1252,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
12521252
}
12531253
let mut layout_of_single_non_zst_field = None;
12541254
let sized = unsized_field.is_none();
1255-
let mut abi = Abi::Aggregate { sized };
1255+
let mut abi = IrForm::Memory { sized };
12561256

12571257
let optimize_abi = !repr.inhibit_newtype_abi_optimization();
12581258

@@ -1270,16 +1270,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
12701270
// Field fills the struct and it has a scalar or scalar pair ABI.
12711271
if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size
12721272
{
1273-
match field.abi {
1273+
match field.ir_form {
12741274
// For plain scalars, or vectors of them, we can't unpack
12751275
// newtypes for `#[repr(C)]`, as that affects C ABIs.
1276-
Abi::Scalar(_) | Abi::Vector { .. } if optimize_abi => {
1277-
abi = field.abi;
1276+
IrForm::Scalar(_) | IrForm::Vector { .. } if optimize_abi => {
1277+
abi = field.ir_form;
12781278
}
12791279
// But scalar pairs are Rust-specific and get
12801280
// treated as aggregates by C ABIs anyway.
1281-
Abi::ScalarPair(..) => {
1282-
abi = field.abi;
1281+
IrForm::ScalarPair(..) => {
1282+
abi = field.ir_form;
12831283
}
12841284
_ => {}
12851285
}
@@ -1288,8 +1288,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
12881288

12891289
// Two non-ZST fields, and they're both scalars.
12901290
(Some((i, a)), Some((j, b)), None) => {
1291-
match (a.abi, b.abi) {
1292-
(Abi::Scalar(a), Abi::Scalar(b)) => {
1291+
match (a.ir_form, b.ir_form) {
1292+
(IrForm::Scalar(a), IrForm::Scalar(b)) => {
12931293
// Order by the memory placement, not source order.
12941294
let ((i, a), (j, b)) = if offsets[i] < offsets[j] {
12951295
((i, a), (j, b))
@@ -1315,7 +1315,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13151315
{
13161316
// We can use `ScalarPair` only when it matches our
13171317
// already computed layout (including `#[repr(C)]`).
1318-
abi = pair.abi;
1318+
abi = pair.ir_form;
13191319
}
13201320
}
13211321
_ => {}
@@ -1325,8 +1325,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13251325
_ => {}
13261326
}
13271327
}
1328-
if fields.iter().any(|f| f.abi.is_uninhabited()) {
1329-
abi = Abi::Uninhabited;
1328+
if fields.iter().any(|f| f.ir_form.is_uninhabited()) {
1329+
abi = IrForm::Uninhabited;
13301330
}
13311331

13321332
let unadjusted_abi_align = if repr.transparent() {
@@ -1344,7 +1344,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13441344
Ok(LayoutS {
13451345
variants: Variants::Single { index: VariantIdx::new(0) },
13461346
fields: FieldsShape::Arbitrary { offsets, memory_index },
1347-
abi,
1347+
ir_form: abi,
13481348
largest_niche,
13491349
align,
13501350
size,

0 commit comments

Comments
 (0)