From cde42cd7803308793a9902022413a5e34557f9a9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Oct 2016 14:46:41 +1100 Subject: [PATCH] Don't enqueue onto a disabled dep_graph. This commit guards all calls to `DepGraphThreadData::enqueue` with a check to make sure it is enabled. This requires distinguishing between a "fully enabled" and an "enqueue-enabled" graph. This change avoids some useless allocation and vector manipulations when the graph is disabled (i.e. when incremental compilation is off) which improves speed by ~1% on some of the rustc-benchmarks. --- src/librustc/dep_graph/graph.rs | 19 ++++++++----------- src/librustc/dep_graph/raii.rs | 28 ++++++++++++++++++++-------- src/librustc/dep_graph/shadow.rs | 5 +++++ src/librustc/dep_graph/thread.rs | 19 ++++++++++++++----- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index c42eeead69ec1..fac3586afc7b9 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -51,22 +51,15 @@ impl DepGraph { } } - /// True if we are actually building a dep-graph. If this returns false, - /// then the other methods on this `DepGraph` will have no net effect. - #[inline] - pub fn enabled(&self) -> bool { - self.data.thread.enabled() - } - pub fn query(&self) -> DepGraphQuery { self.data.thread.query() } - pub fn in_ignore<'graph>(&'graph self) -> raii::IgnoreTask<'graph> { + pub fn in_ignore<'graph>(&'graph self) -> Option> { raii::IgnoreTask::new(&self.data.thread) } - pub fn in_task<'graph>(&'graph self, key: DepNode) -> raii::DepTask<'graph> { + pub fn in_task<'graph>(&'graph self, key: DepNode) -> Option> { raii::DepTask::new(&self.data.thread, key) } @@ -85,11 +78,15 @@ impl DepGraph { } pub fn read(&self, v: DepNode) { - self.data.thread.enqueue(DepMessage::Read(v)); + if self.data.thread.is_enqueue_enabled() { + self.data.thread.enqueue(DepMessage::Read(v)); + } } pub fn write(&self, v: DepNode) { - self.data.thread.enqueue(DepMessage::Write(v)); + if self.data.thread.is_enqueue_enabled() { + self.data.thread.enqueue(DepMessage::Write(v)); + } } /// Indicates that a previous work product exists for `v`. This is diff --git a/src/librustc/dep_graph/raii.rs b/src/librustc/dep_graph/raii.rs index e4f572902f9e5..e39797599acfd 100644 --- a/src/librustc/dep_graph/raii.rs +++ b/src/librustc/dep_graph/raii.rs @@ -19,15 +19,21 @@ pub struct DepTask<'graph> { impl<'graph> DepTask<'graph> { pub fn new(data: &'graph DepGraphThreadData, key: DepNode) - -> DepTask<'graph> { - data.enqueue(DepMessage::PushTask(key.clone())); - DepTask { data: data, key: Some(key) } + -> Option> { + if data.is_enqueue_enabled() { + data.enqueue(DepMessage::PushTask(key.clone())); + Some(DepTask { data: data, key: Some(key) }) + } else { + None + } } } impl<'graph> Drop for DepTask<'graph> { fn drop(&mut self) { - self.data.enqueue(DepMessage::PopTask(self.key.take().unwrap())); + if self.data.is_enqueue_enabled() { + self.data.enqueue(DepMessage::PopTask(self.key.take().unwrap())); + } } } @@ -36,15 +42,21 @@ pub struct IgnoreTask<'graph> { } impl<'graph> IgnoreTask<'graph> { - pub fn new(data: &'graph DepGraphThreadData) -> IgnoreTask<'graph> { - data.enqueue(DepMessage::PushIgnore); - IgnoreTask { data: data } + pub fn new(data: &'graph DepGraphThreadData) -> Option> { + if data.is_enqueue_enabled() { + data.enqueue(DepMessage::PushIgnore); + Some(IgnoreTask { data: data }) + } else { + None + } } } impl<'graph> Drop for IgnoreTask<'graph> { fn drop(&mut self) { - self.data.enqueue(DepMessage::PopIgnore); + if self.data.is_enqueue_enabled() { + self.data.enqueue(DepMessage::PopIgnore); + } } } diff --git a/src/librustc/dep_graph/shadow.rs b/src/librustc/dep_graph/shadow.rs index 72a321425ef06..06def4bf19af3 100644 --- a/src/librustc/dep_graph/shadow.rs +++ b/src/librustc/dep_graph/shadow.rs @@ -64,6 +64,11 @@ impl ShadowGraph { } } + #[inline] + pub fn enabled(&self) -> bool { + ENABLED + } + pub fn enqueue(&self, message: &DepMessage) { if ENABLED { match self.stack.borrow_state() { diff --git a/src/librustc/dep_graph/thread.rs b/src/librustc/dep_graph/thread.rs index 90c42d66b7adf..9f755cf86e4e4 100644 --- a/src/librustc/dep_graph/thread.rs +++ b/src/librustc/dep_graph/thread.rs @@ -88,15 +88,24 @@ impl DepGraphThreadData { } } + /// True if we are actually building the full dep-graph. #[inline] - pub fn enabled(&self) -> bool { + pub fn is_fully_enabled(&self) -> bool { self.enabled } + /// True if (a) we are actually building the full dep-graph, or (b) we are + /// only enqueuing messages in order to sanity-check them (which happens + /// when debug assertions are enabled). + #[inline] + pub fn is_enqueue_enabled(&self) -> bool { + self.is_fully_enabled() || self.shadow_graph.enabled() + } + /// Sends the current batch of messages to the thread. Installs a /// new vector of messages. fn swap(&self) { - assert!(self.enabled, "should never swap if not enabled"); + assert!(self.is_fully_enabled(), "should never swap if not fully enabled"); // should be a buffer waiting for us (though of course we may // have to wait for depgraph thread to finish processing the @@ -112,7 +121,7 @@ impl DepGraphThreadData { } pub fn query(&self) -> DepGraphQuery { - assert!(self.enabled, "cannot query if dep graph construction not enabled"); + assert!(self.is_fully_enabled(), "should never query if not fully enabled"); self.enqueue(DepMessage::Query); self.swap(); self.query_in.recv().unwrap() @@ -122,9 +131,9 @@ impl DepGraphThreadData { /// the buffer is full, this may swap.) #[inline] pub fn enqueue(&self, message: DepMessage) { + assert!(self.is_enqueue_enabled(), "should never enqueue if not enqueue-enabled"); self.shadow_graph.enqueue(&message); - - if self.enabled { + if self.is_fully_enabled() { self.enqueue_enabled(message); } }