Use FieldIdx in various things related to aggregates

Shrank `AggregateKind` by 8 bytes on x64, since the active field of a union is tracked as an `Option<FieldIdx>` instead of `Option<usize>`.
This commit is contained in:
Scott McMurray 2023-04-01 20:11:38 -07:00
parent 480068c235
commit b5b6def021
13 changed files with 51 additions and 46 deletions

View File

@ -6,6 +6,7 @@
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::GeneratorKind;
use rustc_index::vec::IndexSlice;
use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt};
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
@ -825,7 +826,7 @@ pub(super) fn move_spans(
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
let places = &[Operand::Move(place)];
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
self.closure_span(closure_def_id, moved_place, places)
self.closure_span(closure_def_id, moved_place, IndexSlice::from_raw(places))
{
return ClosureUse {
generator_kind,
@ -975,7 +976,7 @@ fn closure_span(
&self,
def_id: LocalDefId,
target_place: PlaceRef<'tcx>,
places: &[Operand<'tcx>],
places: &IndexSlice<FieldIdx, Operand<'tcx>>,
) -> Option<(Span, Option<GeneratorKind>, Span, Span)> {
debug!(
"closure_span: def_id={:?} target_place={:?} places={:?}",

View File

@ -1343,7 +1343,7 @@ fn consume_rvalue(
self.infcx.tcx.mir_borrowck(def_id);
debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
for field in used_mut_upvars {
self.propagate_closure_used_mut_upvar(&operands[field.index()]);
self.propagate_closure_used_mut_upvar(&operands[*field]);
}
}
AggregateKind::Adt(..)

View File

@ -14,7 +14,7 @@
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::lang_items::LangItem;
use rustc_index::vec::IndexVec;
use rustc_index::vec::{IndexSlice, IndexVec};
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::region_constraints::RegionConstraintData;
@ -1716,7 +1716,7 @@ fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
fn aggregate_field_ty(
&mut self,
ak: &AggregateKind<'tcx>,
field_index: usize,
field_index: FieldIdx,
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
@ -1725,8 +1725,7 @@ fn aggregate_field_ty(
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
let def = tcx.adt_def(adt_did);
let variant = &def.variant(variant_index);
let adj_field_index =
FieldIdx::from_usize(active_field_index.unwrap_or(field_index));
let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location))
} else {
@ -1734,7 +1733,7 @@ fn aggregate_field_ty(
}
}
AggregateKind::Closure(_, substs) => {
match substs.as_closure().upvar_tys().nth(field_index) {
match substs.as_closure().upvar_tys().nth(field_index.as_usize()) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys().count(),
@ -1745,7 +1744,7 @@ fn aggregate_field_ty(
// It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in
// aggregate rvalues.
match substs.as_generator().prefix_tys().nth(field_index) {
match substs.as_generator().prefix_tys().nth(field_index.as_usize()) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys().count(),
@ -2350,7 +2349,7 @@ fn check_aggregate_rvalue(
body: &Body<'tcx>,
rvalue: &Rvalue<'tcx>,
aggregate_kind: &AggregateKind<'tcx>,
operands: &[Operand<'tcx>],
operands: &IndexSlice<FieldIdx, Operand<'tcx>>,
location: Location,
) {
let tcx = self.tcx();
@ -2362,7 +2361,7 @@ fn check_aggregate_rvalue(
return;
}
for (i, operand) in operands.iter().enumerate() {
for (i, operand) in operands.iter_enumerated() {
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
Ok(field_ty) => field_ty,
Err(FieldAccessError::OutOfRange { field_count }) => {
@ -2370,8 +2369,8 @@ fn check_aggregate_rvalue(
self,
rvalue,
"accessed field #{} but variant only has {}",
i,
field_count
i.as_u32(),
field_count,
);
continue;
}

View File

@ -802,14 +802,15 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
for (i, operand) in operands.iter().enumerate() {
for (i, operand) in operands.iter_enumerated() {
let operand = codegen_operand(fx, operand);
let field_index = active_field_index.unwrap_or(i);
let to = if let mir::AggregateKind::Array(_) = **kind {
let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64);
let array_index = i64::from(field_index.as_u32());
let index = fx.bcx.ins().iconst(fx.pointer_type, array_index);
variant_dest.place_index(fx, index)
} else {
variant_dest.place_field(fx, FieldIdx::new(field_index))
variant_dest.place_field(fx, field_index)
};
to.write_cvalue(fx, operand);
}

View File

@ -306,9 +306,9 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
assert_eq!(def_a, def_b);
for i in 0..def_a.variant(FIRST_VARIANT).fields.len() {
let src_f = src.project_field(bx, i);
let dst_f = dst.project_field(bx, i);
for i in def_a.variant(FIRST_VARIANT).fields.indices() {
let src_f = src.project_field(bx, i.as_usize());
let dst_f = dst.project_field(bx, i.as_usize());
if dst_f.layout.is_zst() {
continue;

View File

@ -123,16 +123,16 @@ pub fn codegen_rvalue(
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
for (i, operand) in operands.iter().enumerate() {
for (i, operand) in operands.iter_enumerated() {
let op = self.codegen_operand(bx, operand);
// Do not generate stores and GEPis for zero-sized fields.
if !op.layout.is_zst() {
let field_index = active_field_index.unwrap_or(i);
let field = if let mir::AggregateKind::Array(_) = **kind {
let llindex = bx.cx().const_usize(field_index as u64);
let llindex = bx.cx().const_usize(field_index.as_u32().into());
variant_dest.project_index(bx, llindex)
} else {
variant_dest.project_field(bx, field_index)
variant_dest.project_field(bx, field_index.as_usize())
};
op.val.store(bx, field);
}

View File

@ -5,10 +5,11 @@
use either::{Either, Left, Right};
use rustc_ast::Mutability;
use rustc_index::vec::IndexSlice;
use rustc_middle::mir;
use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, FIRST_VARIANT};
use rustc_target::abi::{self, Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT};
use super::{
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
@ -787,7 +788,7 @@ pub fn allocate_str(
pub fn write_aggregate(
&mut self,
kind: &mir::AggregateKind<'tcx>,
operands: &[mir::Operand<'tcx>],
operands: &IndexSlice<FieldIdx, mir::Operand<'tcx>>,
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
self.write_uninit(&dest)?;
@ -801,9 +802,9 @@ pub fn write_aggregate(
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
for (field_index, operand) in operands.iter().enumerate() {
for (field_index, operand) in operands.iter_enumerated() {
let field_index = active_field_index.unwrap_or(field_index);
let field_dest = self.place_field(&variant_dest, field_index)?;
let field_dest = self.place_field(&variant_dest, field_index.as_usize())?;
let op = self.eval_operand(operand, Some(field_dest.layout))?;
self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?;
}

View File

@ -93,6 +93,12 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
}
}
impl<I: Idx, T> IndexVec<I, T> {
#[inline]
pub fn new() -> Self {

View File

@ -16,6 +16,7 @@
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir};
use rustc_hir::{self, GeneratorKind};
use rustc_index::vec::IndexVec;
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_ast::Mutability;
@ -1125,7 +1126,7 @@ pub enum Rvalue<'tcx> {
///
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
/// generator lowering, `Generator` aggregate kinds are disallowed too.
Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
///
@ -1186,7 +1187,7 @@ pub enum AggregateKind<'tcx> {
/// active field number and is present only for union expressions
/// -- e.g., for a union expression `SomeUnion { c: .. }`, the
/// active field index would identity the field `c`
Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
Closure(DefId, SubstsRef<'tcx>),
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
@ -1263,7 +1264,7 @@ pub enum BinOp {
mod size_asserts {
use super::*;
// tidy-alphabetical-start
static_assert_size!(AggregateKind<'_>, 40);
static_assert_size!(AggregateKind<'_>, 32);
static_assert_size!(Operand<'_>, 24);
static_assert_size!(Place<'_>, 16);
static_assert_size!(PlaceElem<'_>, 24);

View File

@ -185,7 +185,7 @@ fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
},
ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => {
let is_union = adt_def.is_union();
let active_field_index = is_union.then(|| fields[0].name.index());
let active_field_index = is_union.then(|| fields[0].name);
Ok(Rvalue::Aggregate(
Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)),

View File

@ -1,8 +1,8 @@
//! See docs in `build/expr/mod.rs`.
use rustc_index::vec::Idx;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ty::util::IntTypeExt;
use rustc_target::abi::{Abi, Primitive};
use rustc_target::abi::{Abi, FieldIdx, Primitive};
use crate::build::expr::as_place::PlaceBase;
use crate::build::expr::category::{Category, RvalueFunc};
@ -17,7 +17,6 @@
use rustc_middle::ty::cast::{mir_cast_kind, CastTy};
use rustc_middle::ty::{self, Ty, UpvarSubsts};
use rustc_span::Span;
use rustc_target::abi::FieldIdx;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Returns an rvalue suitable for use until the end of the current
@ -327,7 +326,7 @@ pub(crate) fn as_rvalue(
// first process the set of fields
let el_ty = expr.ty.sequence_element_type(this.tcx);
let fields: Vec<_> = fields
let fields: IndexVec<FieldIdx, _> = fields
.into_iter()
.copied()
.map(|f| {
@ -348,7 +347,7 @@ pub(crate) fn as_rvalue(
ExprKind::Tuple { ref fields } => {
// see (*) above
// first process the set of fields
let fields: Vec<_> = fields
let fields: IndexVec<FieldIdx, _> = fields
.into_iter()
.copied()
.map(|f| {
@ -402,7 +401,7 @@ pub(crate) fn as_rvalue(
}
// see (*) above
let operands: Vec<_> = upvars
let operands: IndexVec<FieldIdx, _> = upvars
.into_iter()
.copied()
.map(|upvar| {
@ -710,7 +709,7 @@ fn build_zero_repeat(
}
this.record_operands_moved(&[value_operand]);
}
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), Vec::new()))
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new()))
}
fn limit_capture_mutability(

View File

@ -6,11 +6,9 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_index::vec::Idx;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::CanonicalUserTypeAnnotation;
use rustc_target::abi::FieldIdx;
use std::iter;
impl<'a, 'tcx> Builder<'a, 'tcx> {
@ -320,7 +318,7 @@ pub(crate) fn expr_into_dest(
// See the notes for `ExprKind::Array` in `as_rvalue` and for
// `ExprKind::Borrow` above.
let is_union = adt_def.is_union();
let active_field_index = is_union.then(|| fields[0].name.index());
let active_field_index = is_union.then(|| fields[0].name);
let scope = this.local_scope();
@ -344,10 +342,9 @@ pub(crate) fn expr_into_dest(
})
.collect();
let field_names: Vec<_> =
(0..adt_def.variant(variant_index).fields.len()).map(FieldIdx::new).collect();
let field_names = adt_def.variant(variant_index).fields.indices();
let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
let fields = if let Some(FruInfo { base, field_types }) = base {
let place_builder =
unpack!(block = this.as_place_builder(block, &this.thir[*base]));
@ -364,7 +361,7 @@ pub(crate) fn expr_into_dest(
})
.collect()
} else {
field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect()
field_names.filter_map(|n| fields_map.get(&n).cloned()).collect()
};
let inferred_ty = expr.ty;

View File

@ -274,7 +274,7 @@ fn make_state(
statements.push(Statement {
kind: StatementKind::Assign(Box::new((
Place::return_place(),
Rvalue::Aggregate(Box::new(kind), vec![]),
Rvalue::Aggregate(Box::new(kind), IndexVec::new()),
))),
source_info,
});
@ -287,7 +287,7 @@ fn make_state(
statements.push(Statement {
kind: StatementKind::Assign(Box::new((
Place::return_place(),
Rvalue::Aggregate(Box::new(kind), vec![val]),
Rvalue::Aggregate(Box::new(kind), IndexVec::from_iter([val])),
))),
source_info,
});