From 8fbc91cfe1fecfd8534b1b828bb64806a67d9659 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 22 Nov 2017 13:47:50 +0100 Subject: [PATCH] incr.comp.: Make MIR encoding fit for incr.comp. caching. --- src/librustc/ich/impls_mir.rs | 6 +-- src/librustc/mir/mod.rs | 25 ++++------- src/librustc/ty/maps/on_disk_cache.rs | 45 ++++++++++++++++++++ src/librustc_metadata/decoder.rs | 9 ++++ src/librustc_metadata/encoder.rs | 9 ++++ src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/shim.rs | 8 ++-- src/librustc_mir/transform/check_unsafety.rs | 4 +- 8 files changed, 81 insertions(+), 27 deletions(-) diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index e40d07d936bb..424259de4fd1 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -98,7 +98,7 @@ for mir::Terminator<'gcx> { } } -impl<'gcx, T> HashStable> for mir::ClearOnDecode +impl<'gcx, T> HashStable> for mir::ClearCrossCrate where T: HashStable> { #[inline] @@ -107,8 +107,8 @@ impl<'gcx, T> HashStable> for mir::ClearOnDecode hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - mir::ClearOnDecode::Clear => {} - mir::ClearOnDecode::Set(ref value) => { + mir::ClearCrossCrate::Clear => {} + mir::ClearCrossCrate::Set(ref value) => { value.hash_stable(hcx, hasher); } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d5df90a5ea02..76dbe6e61b4f 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -75,7 +75,7 @@ pub struct Mir<'tcx> { /// Crate-local information for each visibility scope, that can't (and /// needn't) be tracked across crates. - pub visibility_scope_info: ClearOnDecode>, + pub visibility_scope_info: ClearCrossCrate>, /// Rvalues promoted from this function, such as borrows of constants. /// Each of them is the Mir of a constant with the fn's type parameters @@ -129,8 +129,8 @@ pub const START_BLOCK: BasicBlock = BasicBlock(0); impl<'tcx> Mir<'tcx> { pub fn new(basic_blocks: IndexVec>, visibility_scopes: IndexVec, - visibility_scope_info: ClearOnDecode>, + visibility_scope_info: ClearCrossCrate>, promoted: IndexVec>, yield_ty: Option>, local_decls: IndexVec>, @@ -283,7 +283,7 @@ impl<'tcx> Mir<'tcx> { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct VisibilityScopeInfo { /// A NodeId with lint levels equivalent to this scope's lint levels. pub lint_root: ast::NodeId, @@ -291,7 +291,7 @@ pub struct VisibilityScopeInfo { pub safety: Safety, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub enum Safety { Safe, /// Unsafe because of a PushUnsafeBlock @@ -335,22 +335,13 @@ impl<'tcx> IndexMut for Mir<'tcx> { } #[derive(Clone, Debug)] -pub enum ClearOnDecode { +pub enum ClearCrossCrate { Clear, Set(T) } -impl serialize::Encodable for ClearOnDecode { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - serialize::Encodable::encode(&(), s) - } -} - -impl serialize::Decodable for ClearOnDecode { - fn decode(d: &mut D) -> Result { - serialize::Decodable::decode(d).map(|()| ClearOnDecode::Clear) - } -} +impl serialize::UseSpecializedEncodable for ClearCrossCrate {} +impl serialize::UseSpecializedDecodable for ClearCrossCrate {} /// Grouped information about the source code origin of a MIR entity. /// Intended to be inspected by diagnostics and debuginfo. diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 6f55df76df4a..01f2374033da 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -15,6 +15,7 @@ use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE}; use hir::map::definitions::DefPathHash; use middle::cstore::CrateStore; +use mir; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, @@ -36,6 +37,9 @@ use ty::context::TyCtxt; const PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1; const QUERY_RESULT_INDEX_TAG: u64 = 0x1234_5678_C3C3_C3C3; +const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0; +const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1; + /// `OnDiskCache` provides an interface to incr. comp. data cached from the /// previous compilation session. This data will eventually include the results /// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and @@ -518,12 +522,32 @@ impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> // NodeIds are not stable across compilation sessions, so we store them in their // HirId representation. This allows use to map them to the current NodeId. impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { + #[inline] fn specialized_decode(&mut self) -> Result { let hir_id = hir::HirId::decode(self)?; Ok(self.tcx().hir.hir_to_node_id(hir_id)) } } +impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder> +for CacheDecoder<'a, 'tcx, 'x> { + #[inline] + fn specialized_decode(&mut self) -> Result, Self::Error> { + let discr = u8::decode(self)?; + + match discr { + TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear), + TAG_CLEAR_CROSS_CRATE_SET => { + let val = T::decode(self)?; + Ok(mir::ClearCrossCrate::Set(val)) + } + _ => { + unreachable!() + } + } + } +} + //- ENCODING ------------------------------------------------------------------- struct CacheEncoder<'enc, 'a, 'tcx, E> @@ -658,6 +682,27 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder for CacheEncoder<'enc, 'a, 't } } +impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder> +for CacheEncoder<'enc, 'a, 'tcx, E> + where E: 'enc + ty_codec::TyEncoder, + T: Encodable, +{ + #[inline] + fn specialized_encode(&mut self, + val: &mir::ClearCrossCrate) + -> Result<(), Self::Error> { + match *val { + mir::ClearCrossCrate::Clear => { + TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self) + } + mir::ClearCrossCrate::Set(ref val) => { + TAG_CLEAR_CROSS_CRATE_SET.encode(self)?; + val.encode(self) + } + } + } +} + macro_rules! encoder_methods { ($($name:ident($ty:ty);)*) => { $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 633806d5ef56..eb2bcfc93c5f 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -21,6 +21,7 @@ use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::ich::Fingerprint; use rustc::middle::lang_items; +use rustc::mir; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::codec::TyDecoder; @@ -327,6 +328,14 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { } } +impl<'a, 'tcx, T: Decodable> SpecializedDecoder> +for DecodeContext<'a, 'tcx> { + #[inline] + fn specialized_decode(&mut self) -> Result, Self::Error> { + Ok(mir::ClearCrossCrate::Clear) + } +} + implement_ty_decoder!( DecodeContext<'a, 'tcx> ); impl<'a, 'tcx> MetadataBlob { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d82d50164cbb..de6bb9ea738b 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -157,6 +157,15 @@ impl<'a, 'tcx> SpecializedEncoder> for EncodeContext } } +impl<'a, 'tcx, T: Encodable> SpecializedEncoder> +for EncodeContext<'a, 'tcx> { + fn specialized_encode(&mut self, + _: &mir::ClearCrossCrate) + -> Result<(), Self::Error> { + Ok(()) + } +} + impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> { fn position(&self) -> usize { self.opaque.position() diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 080cf4b47cf8..2086e92a9846 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -543,7 +543,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Mir::new(self.cfg.basic_blocks, self.visibility_scopes, - ClearOnDecode::Set(self.visibility_scope_info), + ClearCrossCrate::Set(self.visibility_scope_info), IndexVec::new(), yield_ty, self.local_decls, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 119cd35910fd..15b06bd38924 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -198,7 +198,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, IndexVec::from_elem_n( VisibilityScopeData { span: span, parent_scope: None }, 1 ), - ClearOnDecode::Clear, + ClearCrossCrate::Clear, IndexVec::new(), None, local_decls_for_sig(&sig, span), @@ -345,7 +345,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { IndexVec::from_elem_n( VisibilityScopeData { span: self.span, parent_scope: None }, 1 ), - ClearOnDecode::Clear, + ClearCrossCrate::Clear, IndexVec::new(), None, self.local_decls, @@ -807,7 +807,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, IndexVec::from_elem_n( VisibilityScopeData { span: span, parent_scope: None }, 1 ), - ClearOnDecode::Clear, + ClearCrossCrate::Clear, IndexVec::new(), None, local_decls, @@ -885,7 +885,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, IndexVec::from_elem_n( VisibilityScopeData { span: span, parent_scope: None }, 1 ), - ClearOnDecode::Clear, + ClearCrossCrate::Clear, IndexVec::new(), None, local_decls, diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index c8a23280079c..720a3bf0bc0e 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -320,8 +320,8 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) let mir = &tcx.mir_built(def_id).borrow(); let visibility_scope_info = match mir.visibility_scope_info { - ClearOnDecode::Set(ref data) => data, - ClearOnDecode::Clear => { + ClearCrossCrate::Set(ref data) => data, + ClearCrossCrate::Clear => { debug!("unsafety_violations: {:?} - remote, skipping", def_id); return UnsafetyCheckResult { violations: Rc::new([]),