diff options
| -rw-r--r-- | src/librustc/dep_graph/graph.rs | 6 | ||||
| -rw-r--r-- | src/librustc/dep_graph/prev.rs | 5 | ||||
| -rw-r--r-- | src/librustc/hir/def_id.rs | 2 | ||||
| -rw-r--r-- | src/librustc/session/config.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/maps/config.rs | 27 | ||||
| -rw-r--r-- | src/librustc/ty/maps/on_disk_cache.rs | 38 | ||||
| -rw-r--r-- | src/librustc/ty/maps/plumbing.rs | 30 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest.rs | 3 |
8 files changed, 95 insertions, 18 deletions
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 97ac1b25612..c9205f67f66 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -327,6 +327,7 @@ impl DepGraph { } } + #[inline] pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint { match self.fingerprints.borrow().get(dep_node) { Some(&fingerprint) => fingerprint, @@ -340,6 +341,11 @@ impl DepGraph { self.data.as_ref().unwrap().previous.fingerprint_of(dep_node) } + #[inline] + pub fn prev_dep_node_index_of(&self, dep_node: &DepNode) -> SerializedDepNodeIndex { + self.data.as_ref().unwrap().previous.node_to_index(dep_node) + } + /// Indicates that a previous work product exists for `v`. This is /// invoked during initial start-up based on what nodes are clean /// (and what files exist in the incr. directory). diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index 17001bbb0c3..6c43b5c5ff1 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -45,6 +45,11 @@ impl PreviousDepGraph { } #[inline] + pub fn node_to_index(&self, dep_node: &DepNode) -> SerializedDepNodeIndex { + self.index[dep_node] + } + + #[inline] pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> { self.index .get(dep_node) diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index b2eefca7fe2..31730960a34 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -184,7 +184,7 @@ impl DefIndexAddressSpace { /// A DefId identifies a particular *definition*, by combining a crate /// index and a def index. -#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)] +#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, Hash, Copy)] pub struct DefId { pub krate: CrateNum, pub index: DefIndex, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index ffb8144e07e..2857d50fc87 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1042,6 +1042,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "enable incremental compilation (experimental)"), incremental_cc: bool = (false, parse_bool, [UNTRACKED], "enable cross-crate incremental compilation (even more experimental)"), + incremental_queries: bool = (false, parse_bool, [UNTRACKED], + "enable incremental compilation support for queries (experimental)"), incremental_info: bool = (false, parse_bool, [UNTRACKED], "print high-level information about incremental reuse (or the lack thereof)"), incremental_dump_hash: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 2d979dbe780..066b80cefa4 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use dep_graph::SerializedDepNodeIndex; use hir::def_id::{CrateNum, DefId, DefIndex}; use ty::{self, Ty, TyCtxt}; use ty::maps::queries; @@ -25,6 +26,16 @@ pub trait QueryConfig { pub(super) trait QueryDescription<'tcx>: QueryConfig { fn describe(tcx: TyCtxt, key: Self::Key) -> String; + + fn cache_on_disk(_: Self::Key) -> bool { + false + } + + fn load_from_disk<'a>(_: TyCtxt<'a, 'tcx, 'tcx>, + _: SerializedDepNodeIndex) + -> Self::Value { + bug!("QueryDescription::load_from_disk() called for unsupport query.") + } } impl<'tcx, M: QueryConfig<Key=DefId>> QueryDescription<'tcx> for M { @@ -538,3 +549,19 @@ impl<'tcx> QueryDescription<'tcx> for queries::fully_normalize_monormophic_ty<'t format!("normalizing types") } } + +impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { + #[inline] + fn cache_on_disk(def_id: Self::Key) -> bool { + def_id.is_local() + } + + fn load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + id: SerializedDepNodeIndex) + -> Self::Value { + let typeck_tables: ty::TypeckTables<'tcx> = tcx.on_disk_query_result_cache + .load_query_result(tcx, id); + tcx.alloc_tables(typeck_tables) + } +} + diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 6b0cc426b52..d325d1437fc 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -32,6 +32,7 @@ use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP}; use ty; use ty::codec::{self as ty_codec, TyDecoder, TyEncoder}; use ty::context::TyCtxt; +use ty::maps::config::QueryDescription; use ty::subst::Substs; // Some magic values used for verifying that encoding and decoding. These are @@ -229,9 +230,22 @@ impl<'sess> OnDiskCache<'sess> { // Encode query results - let query_result_index = EncodedQueryResultIndex::new(); - // ... we don't encode anything yet, actually + let mut query_result_index = EncodedQueryResultIndex::new(); + // Encode TypeckTables + for (def_id, entry) in tcx.maps.typeck_tables_of.borrow().map.iter() { + if ty::maps::queries::typeck_tables_of::cache_on_disk(*def_id) { + let dep_node = SerializedDepNodeIndex::new(entry.index.index()); + + // Record position of the cache entry + query_result_index.push((dep_node, encoder.position())); + + // Encode the type check tables with the SerializedDepNodeIndex + // as tag. + let typeck_tables: &ty::TypeckTables<'gcx> = &entry.value; + encoder.encode_tagged(dep_node, typeck_tables)?; + } + } // Encode query result index let query_result_index_pos = encoder.position() as u64; @@ -522,9 +536,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> { impl<'a, 'tcx, 'x> SpecializedDecoder<CrateNum> for CacheDecoder<'a, 'tcx, 'x> { fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> { - let cnum = CrateNum::from_u32(u32::decode(self)?); - let mapped = self.map_encoded_cnum_to_current(cnum); - Ok(mapped) + ty_codec::decode_cnum(self) } } @@ -576,6 +588,8 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x> .as_ref() .unwrap()[&def_path_hash]; + debug_assert!(def_id.is_local()); + // The ItemLocalId needs no remapping. let local_id = hir::ItemLocalId::decode(self)?; @@ -721,6 +735,20 @@ impl<'enc, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>> } } +impl<'enc, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'enc, 'tcx, E> + where E: 'enc + ty_codec::TyEncoder +{ + fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> { + let hir::HirId { + owner, + local_id, + } = *id; + + owner.encode(self)?; + local_id.encode(self) + } +} + // 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<'enc, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'tcx, E> diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 1096d306a13..2f8f724edad 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -379,18 +379,26 @@ macro_rules! define_maps { { debug_assert!(tcx.dep_graph.is_green(dep_node_index)); - // We don't do any caching yet, so recompute. - // The diagnostics for this query have already been promoted to - // the current session during try_mark_green(), so we can ignore - // them here. - let (result, _) = tcx.cycle_check(span, Query::$name(key), || { - tcx.sess.diagnostic().track_diagnostics(|| { - // The dep-graph for this computation is already in place - tcx.dep_graph.with_ignore(|| { - Self::compute_result(tcx, key) + let result = if tcx.sess.opts.debugging_opts.incremental_queries && + Self::cache_on_disk(key) { + let prev_dep_node_index = + tcx.dep_graph.prev_dep_node_index_of(dep_node); + Self::load_from_disk(tcx.global_tcx(), prev_dep_node_index) + } else { + let (result, _ ) = tcx.cycle_check(span, Query::$name(key), || { + // The diagnostics for this query have already been + // promoted to the current session during + // try_mark_green(), so we can ignore them here. + tcx.sess.diagnostic().track_diagnostics(|| { + // The dep-graph for this computation is already in + // place + tcx.dep_graph.with_ignore(|| { + Self::compute_result(tcx, key) + }) }) - }) - })?; + })?; + result + }; // If -Zincremental-verify-ich is specified, re-hash results from // the cache and make sure that they have the expected fingerprint. diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 80ca0afe72b..8d94039c594 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1387,6 +1387,7 @@ actual:\n\ if let Some(ref incremental_dir) = self.props.incremental_dir { rustc.args(&["-Z", &format!("incremental={}", incremental_dir.display())]); rustc.args(&["-Z", "incremental-verify-ich"]); + rustc.args(&["-Z", "incremental-queries"]); } match self.config.mode { @@ -2614,4 +2615,4 @@ fn read2_abbreviated(mut child: Child) -> io::Result<Output> { stdout: stdout.into_bytes(), stderr: stderr.into_bytes(), }) -} \ No newline at end of file +} |
