Skip to content

Commit 512bd84

Browse files
committed
Auto merge of rust-lang#94075 - mikebenfield:wip-enum, r=oli-obk
Use niche-filling optimization even when multiple variants have data. Fixes rust-lang#46213
2 parents c2804e6 + d7a750b commit 512bd84

File tree

22 files changed

+377
-196
lines changed

22 files changed

+377
-196
lines changed

compiler/rustc_ast/src/ast.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3075,7 +3075,8 @@ mod size_asserts {
30753075
static_assert_size!(Block, 48);
30763076
static_assert_size!(Expr, 104);
30773077
static_assert_size!(ExprKind, 72);
3078-
static_assert_size!(Fn, 192);
3078+
#[cfg(not(bootstrap))]
3079+
static_assert_size!(Fn, 184);
30793080
static_assert_size!(ForeignItem, 96);
30803081
static_assert_size!(ForeignItemKind, 24);
30813082
static_assert_size!(GenericArg, 24);

compiler/rustc_codegen_cranelift/src/discriminant.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
4242
Variants::Multiple {
4343
tag: _,
4444
tag_field,
45-
tag_encoding: TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
45+
tag_encoding: TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
4646
variants: _,
4747
} => {
48-
if variant_index != dataful_variant {
48+
if variant_index != untagged_variant {
4949
let niche = place.place_field(fx, mir::Field::new(tag_field));
5050
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
5151
let niche_value = ty::ScalarInt::try_from_uint(
@@ -113,7 +113,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
113113
let res = CValue::by_val(val, dest_layout);
114114
dest.write_cvalue(fx, res);
115115
}
116-
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
116+
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
117117
// Rebase from niche values to discriminants, and check
118118
// whether the result is in range for the niche variants.
119119

@@ -169,8 +169,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
169169
fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
170170
};
171171

172-
let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
173-
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
172+
let untagged_variant =
173+
fx.bcx.ins().iconst(cast_to, i64::from(untagged_variant.as_u32()));
174+
let discr = fx.bcx.ins().select(is_niche, niche_discr, untagged_variant);
174175
let res = CValue::by_val(discr, dest_layout);
175176
dest.write_cvalue(fx, res);
176177
}

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0;
9999
/// compiler versions.
100100
///
101101
/// Niche-tag enums have one special variant, usually called the
102-
/// "dataful variant". This variant has a field that
102+
/// "untagged variant". This variant has a field that
103103
/// doubles as the tag of the enum. The variant is active when the value of
104104
/// that field is within a pre-defined range. Therefore the variant struct
105105
/// has a `DISCR_BEGIN` and `DISCR_END` field instead of `DISCR_EXACT` in
@@ -249,7 +249,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
249249
None,
250250
),
251251
Variants::Multiple {
252-
tag_encoding: TagEncoding::Niche { dataful_variant, .. },
252+
tag_encoding: TagEncoding::Niche { untagged_variant, .. },
253253
ref variants,
254254
tag_field,
255255
..
@@ -260,7 +260,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
260260
enum_type_di_node,
261261
variants.indices(),
262262
tag_field,
263-
Some(dataful_variant),
263+
Some(untagged_variant),
264264
),
265265
}
266266
},
@@ -391,7 +391,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
391391
enum_type_di_node: &'ll DIType,
392392
variant_indices: impl Iterator<Item = VariantIdx> + Clone,
393393
tag_field: usize,
394-
dataful_variant_index: Option<VariantIdx>,
394+
untagged_variant_index: Option<VariantIdx>,
395395
) -> SmallVec<&'ll DIType> {
396396
let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
397397

@@ -436,7 +436,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
436436
variant_names_type_di_node,
437437
tag_base_type,
438438
tag_field,
439-
dataful_variant_index,
439+
untagged_variant_index,
440440
)
441441
}
442442

@@ -472,7 +472,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
472472
enum_or_generator_type_and_layout: TyAndLayout<'tcx>,
473473
enum_or_generator_type_di_node: &'ll DIType,
474474
variant_index: VariantIdx,
475-
dataful_variant_index: Option<VariantIdx>,
475+
untagged_variant_index: Option<VariantIdx>,
476476
variant_struct_type_di_node: &'ll DIType,
477477
variant_names_type_di_node: &'ll DIType,
478478
tag_base_type_di_node: &'ll DIType,
@@ -517,7 +517,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
517517
}
518518
}
519519
DiscrResult::Range(min, max) => {
520-
assert_eq!(Some(variant_index), dataful_variant_index);
520+
assert_eq!(Some(variant_index), untagged_variant_index);
521521
if is_128_bits {
522522
DiscrKind::Range128(min, max)
523523
} else {
@@ -757,7 +757,7 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
757757
discr_type_di_node: &'ll DIType,
758758
tag_base_type: Ty<'tcx>,
759759
tag_field: usize,
760-
dataful_variant_index: Option<VariantIdx>,
760+
untagged_variant_index: Option<VariantIdx>,
761761
) -> SmallVec<&'ll DIType> {
762762
let tag_base_type_di_node = type_di_node(cx, tag_base_type);
763763
let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
@@ -776,7 +776,7 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
776776
enum_type_and_layout,
777777
enum_type_di_node,
778778
variant_member_info.variant_index,
779-
dataful_variant_index,
779+
untagged_variant_index,
780780
variant_member_info.variant_struct_type_di_node,
781781
discr_type_di_node,
782782
tag_base_type_di_node,

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ impl DiscrResult {
417417
/// Returns the discriminant value corresponding to the variant index.
418418
///
419419
/// Will return `None` if there is less than two variants (because then the enum won't have)
420-
/// a tag, and if this is the dataful variant of a niche-layout enum (because then there is no
420+
/// a tag, and if this is the untagged variant of a niche-layout enum (because then there is no
421421
/// single discriminant value).
422422
fn compute_discriminant_value<'ll, 'tcx>(
423423
cx: &CodegenCx<'ll, 'tcx>,
@@ -430,11 +430,11 @@ fn compute_discriminant_value<'ll, 'tcx>(
430430
enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val,
431431
),
432432
&Variants::Multiple {
433-
tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant },
433+
tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, untagged_variant },
434434
tag,
435435
..
436436
} => {
437-
if variant_index == dataful_variant {
437+
if variant_index == untagged_variant {
438438
let valid_range = enum_type_and_layout
439439
.for_variant(cx, variant_index)
440440
.largest_niche

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ fn build_discr_member_di_node<'ll, 'tcx>(
378378
///
379379
/// The DW_AT_discr_value is optional, and is omitted if
380380
/// - This is the only variant of a univariant enum (i.e. their is no discriminant)
381-
/// - This is the "dataful" variant of a niche-layout enum
381+
/// - This is the "untagged" variant of a niche-layout enum
382382
/// (where only the other variants are identified by a single value)
383383
///
384384
/// There is only ever a single member, the type of which is a struct that describes the

compiler/rustc_codegen_ssa/src/mir/place.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
244244
};
245245
bx.intcast(tag.immediate(), cast_to, signed)
246246
}
247-
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
247+
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
248248
// Rebase from niche values to discriminants, and check
249249
// whether the result is in range for the niche variants.
250250
let niche_llty = bx.cx().immediate_backend_type(tag.layout);
@@ -302,7 +302,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
302302
bx.select(
303303
is_niche,
304304
niche_discr,
305-
bx.cx().const_uint(cast_to, dataful_variant.as_u32() as u64),
305+
bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
306306
)
307307
}
308308
}
@@ -337,11 +337,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
337337
}
338338
Variants::Multiple {
339339
tag_encoding:
340-
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
340+
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
341341
tag_field,
342342
..
343343
} => {
344-
if variant_index != dataful_variant {
344+
if variant_index != untagged_variant {
345345
let niche = self.project_field(bx, tag_field);
346346
let niche_llty = bx.cx().immediate_backend_type(niche.layout);
347347
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();

compiler/rustc_const_eval/src/interpret/operand.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
718718
// Return the cast value, and the index.
719719
(discr_val, index.0)
720720
}
721-
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
721+
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
722722
let tag_val = tag_val.to_scalar();
723723
// Compute the variant this niche value/"tag" corresponds to. With niche layout,
724724
// discriminant (encoded in niche/tag) and variant index are the same.
@@ -736,7 +736,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
736736
if !ptr_valid {
737737
throw_ub!(InvalidTag(dbg_val))
738738
}
739-
dataful_variant
739+
untagged_variant
740740
}
741741
Ok(tag_bits) => {
742742
let tag_bits = tag_bits.assert_bits(tag_layout.size);
@@ -766,7 +766,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
766766
assert!(usize::try_from(variant_index).unwrap() < variants_len);
767767
VariantIdx::from_u32(variant_index)
768768
} else {
769-
dataful_variant
769+
untagged_variant
770770
}
771771
}
772772
};
@@ -780,13 +780,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
780780
}
781781

782782
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
783-
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
783+
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64", not(bootstrap)))]
784784
mod size_asserts {
785785
use super::*;
786786
use rustc_data_structures::static_assert_size;
787787
// These are in alphabetical order, which is easy to maintain.
788-
static_assert_size!(Immediate, 56);
789-
static_assert_size!(ImmTy<'_>, 72);
790-
static_assert_size!(Operand, 64);
791-
static_assert_size!(OpTy<'_>, 88);
788+
static_assert_size!(Immediate, 48);
789+
static_assert_size!(ImmTy<'_>, 64);
790+
static_assert_size!(Operand, 56);
791+
static_assert_size!(OpTy<'_>, 80);
792792
}

compiler/rustc_const_eval/src/interpret/place.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -817,15 +817,15 @@ where
817817
}
818818
abi::Variants::Multiple {
819819
tag_encoding:
820-
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
820+
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
821821
tag: tag_layout,
822822
tag_field,
823823
..
824824
} => {
825825
// No need to validate that the discriminant here because the
826826
// `TyAndLayout::for_variant()` call earlier already checks the variant is valid.
827827

828-
if variant_index != dataful_variant {
828+
if variant_index != untagged_variant {
829829
let variants_start = niche_variants.start().as_u32();
830830
let variant_index_relative = variant_index
831831
.as_u32()
@@ -890,6 +890,8 @@ mod size_asserts {
890890
static_assert_size!(MemPlaceMeta, 24);
891891
static_assert_size!(MemPlace, 40);
892892
static_assert_size!(MPlaceTy<'_>, 64);
893-
static_assert_size!(Place, 48);
894-
static_assert_size!(PlaceTy<'_>, 72);
893+
#[cfg(not(bootstrap))]
894+
static_assert_size!(Place, 40);
895+
#[cfg(not(bootstrap))]
896+
static_assert_size!(PlaceTy<'_>, 64);
895897
}

compiler/rustc_data_structures/src/obligation_forest/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ pub trait ObligationProcessor {
117117
}
118118

119119
/// The result type used by `process_obligation`.
120+
// `repr(C)` to inhibit the niche filling optimization. Otherwise, the `match` appearing
121+
// in `process_obligations` is significantly slower, which can substantially affect
122+
// benchmarks like `rustc-perf`'s inflate and keccak.
123+
#[repr(C)]
120124
#[derive(Debug)]
121125
pub enum ProcessResult<O, E> {
122126
Unchanged,

compiler/rustc_errors/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a, ErrorGuaranteed>>;
6969
// (See also the comment on `DiagnosticBuilder`'s `diagnostic` field.)
7070
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
7171
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16);
72-
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
73-
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
72+
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64", not(bootstrap)))]
73+
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
7474

7575
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
7676
pub enum SuggestionStyle {

compiler/rustc_hir/src/hir.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -3473,12 +3473,15 @@ mod size_asserts {
34733473
static_assert_size!(FnDecl<'_>, 40);
34743474
static_assert_size!(ForeignItem<'_>, 72);
34753475
static_assert_size!(ForeignItemKind<'_>, 40);
3476-
static_assert_size!(GenericArg<'_>, 40);
3476+
#[cfg(not(bootstrap))]
3477+
static_assert_size!(GenericArg<'_>, 32);
34773478
static_assert_size!(GenericBound<'_>, 48);
34783479
static_assert_size!(Generics<'_>, 56);
34793480
static_assert_size!(Impl<'_>, 80);
3480-
static_assert_size!(ImplItem<'_>, 88);
3481-
static_assert_size!(ImplItemKind<'_>, 40);
3481+
#[cfg(not(bootstrap))]
3482+
static_assert_size!(ImplItem<'_>, 80);
3483+
#[cfg(not(bootstrap))]
3484+
static_assert_size!(ImplItemKind<'_>, 32);
34823485
static_assert_size!(Item<'_>, 80);
34833486
static_assert_size!(ItemKind<'_>, 48);
34843487
static_assert_size!(Local<'_>, 64);
@@ -3490,8 +3493,10 @@ mod size_asserts {
34903493
static_assert_size!(QPath<'_>, 24);
34913494
static_assert_size!(Stmt<'_>, 32);
34923495
static_assert_size!(StmtKind<'_>, 16);
3493-
static_assert_size!(TraitItem<'_>, 96);
3494-
static_assert_size!(TraitItemKind<'_>, 56);
3496+
#[cfg(not(bootstrap))]
3497+
static_assert_size!(TraitItem<'static>, 88);
3498+
#[cfg(not(bootstrap))]
3499+
static_assert_size!(TraitItemKind<'_>, 48);
34953500
static_assert_size!(Ty<'_>, 72);
34963501
static_assert_size!(TyKind<'_>, 56);
34973502
}

compiler/rustc_middle/src/mir/syntax.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,8 @@ pub enum BinOp {
12311231
mod size_asserts {
12321232
use super::*;
12331233
// These are in alphabetical order, which is easy to maintain.
1234-
static_assert_size!(AggregateKind<'_>, 48);
1234+
#[cfg(not(bootstrap))]
1235+
static_assert_size!(AggregateKind<'_>, 40);
12351236
static_assert_size!(Operand<'_>, 24);
12361237
static_assert_size!(Place<'_>, 16);
12371238
static_assert_size!(PlaceElem<'_>, 24);

compiler/rustc_middle/src/thir.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -825,8 +825,12 @@ mod size_asserts {
825825
static_assert_size!(Block, 56);
826826
static_assert_size!(Expr<'_>, 64);
827827
static_assert_size!(ExprKind<'_>, 40);
828-
static_assert_size!(Pat<'_>, 72);
829-
static_assert_size!(PatKind<'_>, 56);
830-
static_assert_size!(Stmt<'_>, 56);
831-
static_assert_size!(StmtKind<'_>, 48);
828+
#[cfg(not(bootstrap))]
829+
static_assert_size!(Pat<'_>, 64);
830+
#[cfg(not(bootstrap))]
831+
static_assert_size!(PatKind<'_>, 48);
832+
#[cfg(not(bootstrap))]
833+
static_assert_size!(Stmt<'_>, 48);
834+
#[cfg(not(bootstrap))]
835+
static_assert_size!(StmtKind<'_>, 40);
832836
}

0 commit comments

Comments
 (0)