]> git.lizzy.rs Git - rust.git/commitdiff
incr.comp.: Cache TypeckTables and add -Zincremental-queries flag.
authorMichael Woerister <michaelwoerister@posteo>
Tue, 14 Nov 2017 18:52:49 +0000 (19:52 +0100)
committerMichael Woerister <michaelwoerister@posteo>
Tue, 14 Nov 2017 18:52:49 +0000 (19:52 +0100)
src/librustc/dep_graph/graph.rs
src/librustc/dep_graph/prev.rs
src/librustc/hir/def_id.rs
src/librustc/session/config.rs
src/librustc/ty/maps/config.rs
src/librustc/ty/maps/on_disk_cache.rs
src/librustc/ty/maps/plumbing.rs
src/tools/compiletest/src/runtest.rs

index 97ac1b256124d1b9337d140e4fbc261c71b42d83..c9205f67f661f2b9ccf5f0b2a9b4349960aa5cff 100644 (file)
@@ -327,6 +327,7 @@ pub fn read_index(&self, dep_node_index: DepNodeIndex) {
         }
     }
 
+    #[inline]
     pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
         match self.fingerprints.borrow().get(dep_node) {
             Some(&fingerprint) => fingerprint,
@@ -340,6 +341,11 @@ pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
         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).
index 17001bbb0c38a4b1362c64391e37af2134014e0b..6c43b5c5ff197acc0c88704fac3ac35a5da2f783 100644 (file)
@@ -44,6 +44,11 @@ pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
         self.data.nodes[dep_node_index].0
     }
 
+    #[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
index b2eefca7fe2321123f66cfd9b7fccde36817fae1..31730960a3458a2d8c925fd9b5dfa615b0333ef7 100644 (file)
@@ -184,7 +184,7 @@ pub fn start(&self) -> usize {
 
 /// 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,
index ffb8144e07e5cb6c03475026d4f3d4f80b8469f4..2857d50fc87bce4c39088e5897f36553210a5321 100644 (file)
@@ -1042,6 +1042,8 @@ fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) ->
           "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],
index 2d979dbe7804a9376b888549467748ff3c8e096c..066b80cefa4b5073a7d41ee83ee32c056470a228 100644 (file)
@@ -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 @@ fn describe(_tcx: TyCtxt, _: Ty) -> String {
         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)
+    }
+}
+
index 6b0cc426b52aac6b6251277771cdc93edae6a430..d325d1437fc3489b0b059de0d86aadde1c646e05 100644 (file)
@@ -32,6 +32,7 @@
 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 @@ pub fn serialize<'a, 'gcx, 'lcx, E>(&self,
 
 
         // 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 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
 
 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 @@ fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
                          .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 @@ fn specialized_encode(&mut self,
     }
 }
 
+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>
index 1096d306a130ea78ea6b25da85975687454b55d3..2f8f724edad1f0fc19c4da81b1d9552d0f9beb90 100644 (file)
@@ -379,18 +379,26 @@ fn load_from_disk_and_cache_in_memory(tcx: TyCtxt<'a, $tcx, 'lcx>,
             {
                 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.
index 80ca0afe72b50d26c49c4f3c018de8e49dc5edb3..8d94039c594f832297bb3d2b058e4ae220478d7b 100644 (file)
@@ -1387,6 +1387,7 @@ fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> C
         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 into_bytes(self) -> Vec<u8> {
         stdout: stdout.into_bytes(),
         stderr: stderr.into_bytes(),
     })
-}
\ No newline at end of file
+}