1
Fork 0

intern offsetof fields

This commit is contained in:
DrMeepster 2023-03-11 16:01:25 -08:00
parent 511e457c4b
commit 61f23e0003
8 changed files with 33 additions and 11 deletions

View file

@ -719,7 +719,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
let mut current_ty = *container;
for &field in fields {
for field in fields.iter() {
match current_ty.kind() {
ty::Tuple(fields) => {
let Some(&f_ty) = fields.get(field.as_usize()) else {

View file

@ -1115,7 +1115,7 @@ pub enum Rvalue<'tcx> {
CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
/// Computes a value as described by the operation.
NullaryOp(NullOp, Ty<'tcx>),
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
/// Exactly like `BinaryOp`, but less operands.
///
@ -1212,13 +1212,13 @@ pub enum AggregateKind<'tcx> {
}
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum NullOp {
pub enum NullOp<'tcx> {
/// Returns the size of a value of that type
SizeOf,
/// Returns the minimum alignment of a type
AlignOf,
/// Returns the offset of a field
OffsetOf(Vec<FieldIdx>),
OffsetOf(&'tcx List<FieldIdx>),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -1288,6 +1288,6 @@ mod size_asserts {
static_assert_size!(Operand<'_>, 24);
static_assert_size!(Place<'_>, 16);
static_assert_size!(PlaceElem<'_>, 24);
static_assert_size!(Rvalue<'_>, 48);
static_assert_size!(Rvalue<'_>, 40);
// tidy-alphabetical-end
}

View file

@ -16,7 +16,6 @@ TrivialTypeTraversalAndLiftImpls! {
UserTypeAnnotationIndex,
BorrowKind,
CastKind,
NullOp,
hir::Movability,
BasicBlock,
SwitchTargets,
@ -26,6 +25,7 @@ TrivialTypeTraversalAndLiftImpls! {
TrivialTypeTraversalImpls! {
ConstValue<'tcx>,
NullOp<'tcx>,
}
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] {

View file

@ -20,7 +20,7 @@ use rustc_middle::mir::interpret::AllocId;
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts};
use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts};
use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
use rustc_span::def_id::LocalDefId;
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
@ -484,7 +484,7 @@ pub enum ExprKind<'tcx> {
/// Field offset (`offset_of!`)
OffsetOf {
container: Ty<'tcx>,
fields: Vec<FieldIdx>,
fields: &'tcx List<FieldIdx>,
},
/// An expression taking a reference to a thread local.
ThreadLocalRef(DefId),

View file

@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::TyCtxt;
use rustc_serialize::{Decodable, Encodable};
use rustc_span::Span;
use rustc_target::abi::FieldIdx;
pub use rustc_type_ir::{TyDecoder, TyEncoder};
use std::hash::Hash;
use std::intrinsics;
@ -401,6 +402,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty
}
}
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<FieldIdx> {
fn decode(decoder: &mut D) -> &'tcx Self {
let len = decoder.read_usize();
decoder
.interner()
.mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder)))
}
}
impl_decodable_via_ref! {
&'tcx ty::TypeckResults<'tcx>,
&'tcx ty::List<Ty<'tcx>>,
@ -412,6 +422,7 @@ impl_decodable_via_ref! {
&'tcx mir::coverage::CodeRegion,
&'tcx ty::List<ty::BoundVariableKind>,
&'tcx ty::List<ty::Predicate<'tcx>>,
&'tcx ty::List<FieldIdx>,
}
#[macro_export]

View file

@ -155,6 +155,7 @@ pub struct CtxtInterners<'tcx> {
layout: InternedSet<'tcx, LayoutS>,
adt_def: InternedSet<'tcx, AdtDefData>,
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
fields: InternedSet<'tcx, List<FieldIdx>>,
}
impl<'tcx> CtxtInterners<'tcx> {
@ -178,6 +179,7 @@ impl<'tcx> CtxtInterners<'tcx> {
layout: Default::default(),
adt_def: Default::default(),
external_constraints: Default::default(),
fields: Default::default(),
}
}
@ -1585,6 +1587,7 @@ slice_interners!(
projs: pub mk_projs(ProjectionKind),
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
fields: pub mk_fields(FieldIdx),
);
impl<'tcx> TyCtxt<'tcx> {
@ -2253,6 +2256,14 @@ impl<'tcx> TyCtxt<'tcx> {
T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
}
pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
{
T::collect_and_apply(iter, |xs| self.mk_fields(xs))
}
pub fn mk_substs_trait(
self,
self_ty: Ty<'tcx>,

View file

@ -481,8 +481,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}))))
}
ExprKind::OffsetOf { container, ref fields } => {
block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields.clone()), container))
ExprKind::OffsetOf { container, fields } => {
block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container))
}
ExprKind::Literal { .. }

View file

@ -667,7 +667,7 @@ impl<'tcx> Cx<'tcx> {
hir::ExprKind::OffsetOf(_, _) => {
let data = self.typeck_results.offset_of_data();
let &(container, ref indices) = data.get(expr.hir_id).unwrap();
let fields = indices.iter().copied().collect();
let fields = tcx.mk_fields_from_iter(indices.iter().copied());
ExprKind::OffsetOf { container, fields }
}