From c10b23e2e0ef86f126a4589ac32c92f747d82eaf Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sun, 24 Sep 2017 17:20:37 +0300 Subject: [PATCH] encode region::Scope using fewer bytes 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). --- src/librustc/ich/impls_ty.rs | 17 +------------ src/librustc/middle/region.rs | 45 ++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 17e15dd5776fd..2bbf807807bad 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -515,22 +515,7 @@ impl_stable_hash_for!(enum ty::cast::CastKind { }); impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { idx }); - -impl<'gcx> HashStable> for ::middle::region::Scope { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'gcx>, - hasher: &mut StableHasher) { - 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> for region::Scope { type KeyType = region::Scope; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 807516f3bdb4a..c1793792d65bf 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -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), @@ -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 } } @@ -164,7 +169,14 @@ impl Idx for FirstStatementIndex { impl From 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 } } } @@ -172,7 +184,16 @@ impl From for Scope { 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] @@ -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 {