Skip to content

Commit

Permalink
encode region::Scope using fewer bytes
Browse files Browse the repository at this point in the history
Now that region::Scope is no longer interned, its size is more
important. This PR encodes region::Scope in 8 bytes instead of 12, which
should speed up region inference somewhat (perf testing needed) and
should improve the margins on #36799 by 64MB (that's not a lot, I did
this PR mostly to speed up region inference).
  • Loading branch information
arielb1 committed Sep 24, 2017
1 parent 8214ab1 commit c10b23e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 33 deletions.
17 changes: 1 addition & 16 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,22 +515,7 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
});

impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { idx });

impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::middle::region::Scope {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
self.data().hash_stable(hcx, hasher)
}
}

impl_stable_hash_for!(enum ::middle::region::ScopeData {
Node(local_id),
Destruction(local_id),
CallSite(local_id),
Arguments(local_id),
Remainder(block_remainder)
});
impl_stable_hash_for!(struct ::middle::region::Scope { id, code });

impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for region::Scope {
type KeyType = region::Scope;
Expand Down
45 changes: 28 additions & 17 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,16 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
/// generated via deriving here.
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
pub struct Scope {
pub scope_data: ScopeData
pub(crate) id: hir::ItemLocalId,
pub(crate) code: u32
}

const SCOPE_DATA_NODE: u32 = !0;
const SCOPE_DATA_CALLSITE: u32 = !1;
const SCOPE_DATA_ARGUMENTS: u32 = !2;
const SCOPE_DATA_DESTRUCTION: u32 = !3;
const SCOPE_DATA_REMAINDER_MAX: u32 = !4;

#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
pub enum ScopeData {
Node(hir::ItemLocalId),
Expand Down Expand Up @@ -148,11 +155,9 @@ pub struct BlockRemainder {
RustcDecodable, Debug, Copy)]
pub struct FirstStatementIndex { pub idx: u32 }

pub const FIRST_STATEMENT_MAX: usize = !0u32 as usize;

impl Idx for FirstStatementIndex {
fn new(idx: usize) -> Self {
assert!(idx <= FIRST_STATEMENT_MAX);
assert!(idx <= SCOPE_DATA_REMAINDER_MAX as usize);
FirstStatementIndex { idx: idx as u32 }
}

Expand All @@ -164,15 +169,31 @@ impl Idx for FirstStatementIndex {
impl From<ScopeData> for Scope {
#[inline]
fn from(scope_data: ScopeData) -> Self {
Self { scope_data }
let (id, code) = match scope_data {
ScopeData::Node(id) => (id, SCOPE_DATA_NODE),
ScopeData::CallSite(id) => (id, SCOPE_DATA_CALLSITE),
ScopeData::Arguments(id) => (id, SCOPE_DATA_ARGUMENTS),
ScopeData::Destruction(id) => (id, SCOPE_DATA_DESTRUCTION),
ScopeData::Remainder(r) => (r.block, r.first_statement_index.index() as u32)
};
Self { id, code }
}
}

#[allow(non_snake_case)]
impl Scope {
#[inline]
pub fn data(self) -> ScopeData {
self.scope_data
match self.code {
SCOPE_DATA_NODE => ScopeData::Node(self.id),
SCOPE_DATA_CALLSITE => ScopeData::CallSite(self.id),
SCOPE_DATA_ARGUMENTS => ScopeData::Arguments(self.id),
SCOPE_DATA_DESTRUCTION => ScopeData::Destruction(self.id),
idx => ScopeData::Remainder(BlockRemainder {
block: self.id,
first_statement_index: FirstStatementIndex { idx }
})
}
}

#[inline]
Expand Down Expand Up @@ -207,17 +228,7 @@ impl Scope {
/// NB: likely to be replaced as API is refined; e.g. pnkfelix
/// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
pub fn item_local_id(&self) -> hir::ItemLocalId {
// TODO: killme
match self.data() {
ScopeData::Node(id) => id,

// These cases all return rough approximations to the
// precise scope denoted by `self`.
ScopeData::Remainder(br) => br.block,
ScopeData::Destruction(id) |
ScopeData::CallSite(id) |
ScopeData::Arguments(id) => id,
}
self.id
}

pub fn node_id(&self, tcx: TyCtxt, scope_tree: &ScopeTree) -> ast::NodeId {
Expand Down

0 comments on commit c10b23e

Please sign in to comment.