Auto merge of #36973 - nnethercote:dep_graph, r=nikomatsakis

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 avoids some useless allocation
and vector manipulations when it is disabled (i.e. when incremental
compilation is off) which improves speed by 1--2% on most of the
rustc-benchmarks.

This commit has an observable functional change: when the dep_graph is
disabled its `shadow_graph` will no longer receive messages. This should
be ok because these message are only used when debug assertions are
enabled.

r? @nikomatsakis
This commit is contained in:
bors 2016-10-19 22:05:13 -07:00 committed by GitHub
commit eb38d426c4
4 changed files with 47 additions and 24 deletions

View File

@ -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<DefId> {
self.data.thread.query()
}
pub fn in_ignore<'graph>(&'graph self) -> raii::IgnoreTask<'graph> {
pub fn in_ignore<'graph>(&'graph self) -> Option<raii::IgnoreTask<'graph>> {
raii::IgnoreTask::new(&self.data.thread)
}
pub fn in_task<'graph>(&'graph self, key: DepNode<DefId>) -> raii::DepTask<'graph> {
pub fn in_task<'graph>(&'graph self, key: DepNode<DefId>) -> Option<raii::DepTask<'graph>> {
raii::DepTask::new(&self.data.thread, key)
}
@ -85,11 +78,15 @@ impl DepGraph {
}
pub fn read(&self, v: DepNode<DefId>) {
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<DefId>) {
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

View File

@ -19,15 +19,21 @@ pub struct DepTask<'graph> {
impl<'graph> DepTask<'graph> {
pub fn new(data: &'graph DepGraphThreadData, key: DepNode<DefId>)
-> DepTask<'graph> {
data.enqueue(DepMessage::PushTask(key.clone()));
DepTask { data: data, key: Some(key) }
-> Option<DepTask<'graph>> {
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<IgnoreTask<'graph>> {
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);
}
}
}

View File

@ -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() {

View File

@ -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<DefId> {
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);
}
}