Skip to content

Commit

Permalink
Tell rustc about unused bits in Span.
Browse files Browse the repository at this point in the history
This shrinks the size of `Option<Span>` and similar types, which shrinks
several AST and HIR nodes. The most important of these are `hir::Expr`
and `ast::Ty`.

This change was first attempted in rust-lang#93747 where it had little effect.
But the improved niche-filling implemented by rust-lang#94075 means this change
now has a much bigger effect.

Co-authored-by: Camille Gillot <[email protected]>
  • Loading branch information
nnethercote and cjgillot committed Oct 17, 2022
1 parent bf286a8 commit 273fb2a
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 108 deletions.
12 changes: 6 additions & 6 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3040,19 +3040,19 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// tidy-alphabetical-start
static_assert_size!(AssocItem, 104);
static_assert_size!(AssocItemKind, 32);
static_assert_size!(AssocItem, 96);
static_assert_size!(AssocItemKind, 24);
static_assert_size!(Attribute, 32);
static_assert_size!(Block, 48);
static_assert_size!(Expr, 104);
static_assert_size!(ExprKind, 72);
static_assert_size!(Fn, 184);
static_assert_size!(Fn, 168);
static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24);
static_assert_size!(GenericArg, 24);
static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 72);
static_assert_size!(Impl, 200);
static_assert_size!(Impl, 184);
static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48);
Expand All @@ -3065,7 +3065,7 @@ mod size_asserts {
static_assert_size!(PatKind, 96);
static_assert_size!(Stmt, 32);
static_assert_size!(StmtKind, 16);
static_assert_size!(Ty, 96);
static_assert_size!(TyKind, 72);
static_assert_size!(Ty, 88);
static_assert_size!(TyKind, 64);
// tidy-alphabetical-end
}
12 changes: 6 additions & 6 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3517,20 +3517,20 @@ mod size_asserts {
// tidy-alphabetical-start
static_assert_size!(Block<'_>, 48);
static_assert_size!(Body<'_>, 32);
static_assert_size!(Expr<'_>, 64);
static_assert_size!(ExprKind<'_>, 48);
static_assert_size!(Expr<'_>, 56);
static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(FnDecl<'_>, 40);
static_assert_size!(ForeignItem<'_>, 72);
static_assert_size!(ForeignItemKind<'_>, 40);
static_assert_size!(GenericArg<'_>, 24);
static_assert_size!(GenericBound<'_>, 48);
static_assert_size!(Generics<'_>, 56);
static_assert_size!(Impl<'_>, 80);
static_assert_size!(Impl<'_>, 72);
static_assert_size!(ImplItem<'_>, 80);
static_assert_size!(ImplItemKind<'_>, 32);
static_assert_size!(Item<'_>, 80);
static_assert_size!(ItemKind<'_>, 48);
static_assert_size!(Local<'_>, 64);
static_assert_size!(Local<'_>, 56);
static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72);
static_assert_size!(Path<'_>, 40);
Expand All @@ -3540,8 +3540,8 @@ mod size_asserts {
static_assert_size!(Res, 12);
static_assert_size!(Stmt<'_>, 32);
static_assert_size!(StmtKind<'_>, 16);
static_assert_size!(TraitItem<'_>, 88);
static_assert_size!(TraitItemKind<'_>, 48);
static_assert_size!(TraitItem<'_>, 80);
static_assert_size!(TraitItemKind<'_>, 40);
static_assert_size!(Ty<'_>, 48);
static_assert_size!(TyKind<'_>, 32);
// tidy-alphabetical-end
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub struct Parser<'a> {
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
// it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Parser<'_>, 328);
rustc_data_structures::static_assert_size!(Parser<'_>, 320);

/// Stores span information about a closure.
#[derive(Clone)]
Expand Down
22 changes: 16 additions & 6 deletions compiler/rustc_span/src/span_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,23 @@ use rustc_data_structures::fx::FxIndexSet;
#[rustc_pass_by_value]
pub struct Span {
base_or_index: u32,
len_or_tag: u16,
len_or_tag: LenOrTag,
ctxt_or_tag: u16,
}

const LEN_TAG: u16 = 0b1000_0000_0000_0000;
// LEN_TAG allows for some extra values at the top. Declare them to rustc to use as niches.
#[rustc_layout_scalar_valid_range_end(0b1000_0000_0000_0000)]
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
struct LenOrTag(u16);

const LEN_TAG: LenOrTag = unsafe { LenOrTag(0b1000_0000_0000_0000) };
const MAX_LEN: u32 = 0b0111_1111_1111_1111;
const CTXT_TAG: u32 = 0b1111_1111_1111_1111;
const MAX_CTXT: u32 = CTXT_TAG - 1;

/// Dummy span, both position and length are zero, syntax context is zero as well.
pub const DUMMY_SP: Span = Span { base_or_index: 0, len_or_tag: 0, ctxt_or_tag: 0 };
pub const DUMMY_SP: Span =
Span { base_or_index: 0, len_or_tag: unsafe { LenOrTag(0) }, ctxt_or_tag: 0 };

impl Span {
#[inline]
Expand All @@ -97,7 +103,11 @@ impl Span {

if len <= MAX_LEN && ctxt2 <= MAX_CTXT && parent.is_none() {
// Inline format.
Span { base_or_index: base, len_or_tag: len as u16, ctxt_or_tag: ctxt2 as u16 }
Span {
base_or_index: base,
len_or_tag: unsafe { LenOrTag(len as u16) },
ctxt_or_tag: ctxt2 as u16,
}
} else {
// Interned format.
let index =
Expand All @@ -122,10 +132,10 @@ impl Span {
pub fn data_untracked(self) -> SpanData {
if self.len_or_tag != LEN_TAG {
// Inline format.
debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
debug_assert!(self.len_or_tag.0 as u32 <= MAX_LEN);
SpanData {
lo: BytePos(self.base_or_index),
hi: BytePos(self.base_or_index + self.len_or_tag as u32),
hi: BytePos(self.base_or_index + self.len_or_tag.0 as u32),
ctxt: SyntaxContext::from_u32(self.ctxt_or_tag as u32),
parent: None,
}
Expand Down
Loading

0 comments on commit 273fb2a

Please sign in to comment.