]> git.lizzy.rs Git - rust.git/commitdiff
incr.comp.: Cache DepNodes with corresponding query results.
authorMichael Woerister <michaelwoerister@posteo.net>
Tue, 4 Jul 2017 15:33:43 +0000 (17:33 +0200)
committerMichael Woerister <michaelwoerister@posteo.net>
Mon, 10 Jul 2017 10:21:39 +0000 (12:21 +0200)
src/librustc/dep_graph/edges.rs
src/librustc/dep_graph/graph.rs
src/librustc/dep_graph/mod.rs
src/librustc/ty/maps.rs
src/librustc_trans/base.rs

index e67d65841d5923dab9560f03bd113354e59b7688..277b69262c92d2e633968a60f7e28ee526f12a6c 100644 (file)
 
 pub struct DepGraphEdges {
     nodes: Vec<DepNode>,
-    indices: FxHashMap<DepNode, IdIndex>,
-    edges: FxHashSet<(IdIndex, IdIndex)>,
+    indices: FxHashMap<DepNode, DepNodeIndex>,
+    edges: FxHashSet<(DepNodeIndex, DepNodeIndex)>,
     task_stack: Vec<OpenTask>,
     forbidden_edge: Option<EdgeFilter>,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-struct IdIndex {
+pub struct DepNodeIndex {
     index: u32
 }
 
-impl IdIndex {
-    fn new(v: usize) -> IdIndex {
+impl DepNodeIndex {
+
+    pub const INVALID: DepNodeIndex = DepNodeIndex { index: ::std::u32::MAX };
+
+    fn new(v: usize) -> DepNodeIndex {
         assert!((v & 0xFFFF_FFFF) == v);
-        IdIndex { index: v as u32 }
+        DepNodeIndex { index: v as u32 }
     }
 
     fn index(self) -> usize {
@@ -80,7 +83,7 @@ pub fn new() -> DepGraphEdges {
         }
     }
 
-    fn id(&self, index: IdIndex) -> DepNode {
+    fn id(&self, index: DepNodeIndex) -> DepNode {
         self.nodes[index.index()]
     }
 
@@ -101,7 +104,7 @@ pub fn push_task(&mut self, key: DepNode) {
         });
     }
 
-    pub fn pop_task(&mut self, key: DepNode) {
+    pub fn pop_task(&mut self, key: DepNode) -> DepNodeIndex {
         let popped_node = self.task_stack.pop().unwrap();
 
         if let OpenTask::Regular {
@@ -117,6 +120,8 @@ pub fn pop_task(&mut self, key: DepNode) {
                 let source_id = self.get_or_create_node(read);
                 self.edges.insert((source_id, target_id));
             }
+
+            target_id
         } else {
             bug!("pop_task() - Expected regular task to be popped")
         }
@@ -129,7 +134,7 @@ pub fn push_anon_task(&mut self) {
         });
     }
 
-    pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNode {
+    pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndex {
         let popped_node = self.task_stack.pop().unwrap();
 
         if let OpenTask::Anon {
@@ -155,8 +160,8 @@ pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNode {
                 hash: fingerprint,
             };
 
-            if self.indices.contains_key(&target_dep_node) {
-                return target_dep_node;
+            if let Some(&index) = self.indices.get(&target_dep_node) {
+                return index;
             }
 
             let target_id = self.get_or_create_node(target_dep_node);
@@ -166,7 +171,7 @@ pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNode {
                 self.edges.insert((source_id, target_id));
             }
 
-            target_dep_node
+            target_id
         } else {
             bug!("pop_anon_task() - Expected anonymous task to be popped")
         }
@@ -210,6 +215,11 @@ pub fn read(&mut self, source: DepNode) {
         }
     }
 
+    pub fn read_index(&mut self, source: DepNodeIndex) {
+        let dep_node = self.nodes[source.index()];
+        self.read(dep_node);
+    }
+
     pub fn query(&self) -> DepGraphQuery {
         let edges: Vec<_> = self.edges.iter()
                                       .map(|&(i, j)| (self.id(i), self.id(j)))
@@ -229,7 +239,7 @@ pub fn add_node(&mut self, node: DepNode) {
     }
 
     #[inline]
-    fn get_or_create_node(&mut self, dep_node: DepNode) -> IdIndex {
+    fn get_or_create_node(&mut self, dep_node: DepNode) -> DepNodeIndex {
         let DepGraphEdges {
             ref mut indices,
             ref mut nodes,
@@ -239,7 +249,7 @@ fn get_or_create_node(&mut self, dep_node: DepNode) -> IdIndex {
         *indices.entry(dep_node).or_insert_with(|| {
             let next_id = nodes.len();
             nodes.push(dep_node);
-            IdIndex::new(next_id)
+            DepNodeIndex::new(next_id)
         })
      }
 }
index 295b402c533eecfe30f430be663de8601c60cb17..de8b7ddb6ca81ccfa2670643a3270ba6cb2918ee 100644 (file)
@@ -17,7 +17,7 @@
 use super::query::DepGraphQuery;
 use super::raii;
 use super::safe::DepGraphSafe;
-use super::edges::DepGraphEdges;
+use super::edges::{DepGraphEdges, DepNodeIndex};
 
 #[derive(Clone)]
 pub struct DepGraph {
@@ -108,16 +108,27 @@ pub fn with_ignore<OP,R>(&self, op: OP) -> R
     ///   `arg` parameter.
     ///
     /// [README]: README.md
-    pub fn with_task<C, A, R>(&self, key: DepNode, cx: C, arg: A, task: fn(C, A) -> R) -> R
-        where C: DepGraphSafe, A: DepGraphSafe
+    pub fn with_task<C, A, R>(&self,
+                              key: DepNode,
+                              cx: C,
+                              arg: A,
+                              task: fn(C, A) -> R)
+                              -> (R, DepNodeIndex)
+        where C: DepGraphSafe
     {
-        let _task = self.in_task(key);
-        task(cx, arg)
+        if let Some(ref data) = self.data {
+            data.edges.borrow_mut().push_task(key);
+            let result = task(cx, arg);
+            let dep_node_index = data.edges.borrow_mut().pop_task(key);
+            (result, dep_node_index)
+        } else {
+            (task(cx, arg), DepNodeIndex::INVALID)
+        }
     }
 
     /// Execute something within an "anonymous" task, that is, a task the
     /// DepNode of which is determined by the list of inputs it read from.
-    pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNode)
+    pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeIndex)
         where OP: FnOnce() -> R
     {
         if let Some(ref data) = self.data {
@@ -126,7 +137,7 @@ pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNode)
             let dep_node = data.edges.borrow_mut().pop_anon_task(dep_kind);
             (result, dep_node)
         } else {
-            (op(), DepNode::new_no_params(DepKind::Krate))
+            (op(), DepNodeIndex::INVALID)
         }
     }
 
@@ -137,6 +148,13 @@ pub fn read(&self, v: DepNode) {
         }
     }
 
+    #[inline]
+    pub fn read_index(&self, v: DepNodeIndex) {
+        if let Some(ref data) = self.data {
+            data.edges.borrow_mut().read_index(v);
+        }
+    }
+
     /// Only to be used during graph loading
     #[inline]
     pub fn add_edge_directly(&self, source: DepNode, target: DepNode) {
index df8c3ba4ac847ec0edfef6271c6b9c6938b10fd2..ac0c88ced93c83962d6b1c46471a29eb2700d477 100644 (file)
@@ -22,6 +22,7 @@
 pub use self::dep_node::WorkProductId;
 pub use self::graph::DepGraph;
 pub use self::graph::WorkProduct;
+pub use self::edges::DepNodeIndex;
 pub use self::query::DepGraphQuery;
 pub use self::safe::AssertDepGraphSafe;
 pub use self::safe::DepGraphSafe;
index 5280901b8c5cf78b47002cafea485618ae3e58b6..e94308f351011660bd911f5aa8aafe5118fcbf5e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use dep_graph::{DepConstructor, DepNode};
+use dep_graph::{DepConstructor, DepNode, DepNodeIndex};
 use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use hir::def::Def;
 use hir;
@@ -186,7 +186,7 @@ fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
 
 struct QueryMap<D: QueryDescription> {
     phantom: PhantomData<D>,
-    map: FxHashMap<D::Key, D::Value>,
+    map: FxHashMap<D::Key, (D::Value, DepNodeIndex)>,
 }
 
 impl<M: QueryDescription> QueryMap<M> {
@@ -580,7 +580,8 @@ fn try_get_with<F, R>(tcx: TyCtxt<'a, $tcx, 'lcx>,
                        key,
                        span);
 
-                if let Some(result) = tcx.maps.$name.borrow().map.get(&key) {
+                if let Some(&(ref result, dep_node_index)) = tcx.maps.$name.borrow().map.get(&key) {
+                    tcx.dep_graph.read_index(dep_node_index);
                     return Ok(f(result));
                 }
 
@@ -591,26 +592,46 @@ fn try_get_with<F, R>(tcx: TyCtxt<'a, $tcx, 'lcx>,
                     span = key.default_span(tcx)
                 }
 
-                let _task = tcx.dep_graph.in_task(Self::to_dep_node(tcx, &key));
-
-                let result = tcx.cycle_check(span, Query::$name(key), || {
-                    let provider = tcx.maps.providers[key.map_crate()].$name;
-                    provider(tcx.global_tcx(), key)
+                let (result, dep_node_index) = tcx.cycle_check(span, Query::$name(key), || {
+                    let dep_node = Self::to_dep_node(tcx, &key);
+
+                    if dep_node.kind.is_anon() {
+                        tcx.dep_graph.with_anon_task(dep_node.kind, || {
+                            let provider = tcx.maps.providers[key.map_crate()].$name;
+                            provider(tcx.global_tcx(), key)
+                        })
+                    } else {
+                        fn run_provider<'a, 'tcx, 'lcx>(tcx: TyCtxt<'a, 'tcx, 'lcx>,
+                                                        key: $K)
+                                                        -> $V {
+                            let provider = tcx.maps.providers[key.map_crate()].$name;
+                            provider(tcx.global_tcx(), key)
+                        }
+
+                        tcx.dep_graph.with_task(dep_node, tcx, key, run_provider)
+                    }
                 })?;
 
-                Ok(f(tcx.maps.$name.borrow_mut().map.entry(key).or_insert(result)))
+                tcx.dep_graph.read_index(dep_node_index);
+
+                Ok(f(&tcx.maps
+                         .$name
+                         .borrow_mut()
+                         .map
+                         .entry(key)
+                         .or_insert((result, dep_node_index))
+                         .0))
             }
 
             pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
                            -> Result<$V, CycleError<'a, $tcx>> {
-                // We register the `read` here, but not in `force`, since
-                // `force` does not give access to the value produced (and thus
-                // we actually don't read it).
-                tcx.dep_graph.read(Self::to_dep_node(tcx, &key));
                 Self::try_get_with(tcx, span, key, Clone::clone)
             }
 
             pub fn force(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K) {
+                // Ignore dependencies, since we not reading the computed value
+                let _task = tcx.dep_graph.in_ignore();
+
                 match Self::try_get_with(tcx, span, key, |_| ()) {
                     Ok(()) => {}
                     Err(e) => tcx.report_cycle(e)
index 8298324e9968089749c5d802161b9613090656b2..9feccc1337266ab0d0d2fd9852b2b846683cac94 100644 (file)
@@ -1120,7 +1120,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         .into_iter()
         .map(|cgu| {
             let dep_node = cgu.work_product_dep_node();
-            let (stats, module) =
+            let ((stats, module), _) =
                 tcx.dep_graph.with_task(dep_node,
                                         AssertDepGraphSafe(&shared_ccx),
                                         AssertDepGraphSafe(cgu),