Skip to content

Commit

Permalink
incr.comp.: Make DepNode's std::fmt::Debug implementation useful again.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Jun 13, 2017
1 parent 3f8b936 commit 5b5499d
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 4 deletions.
124 changes: 120 additions & 4 deletions src/librustc/dep_graph/dep_node.rs
Expand Up @@ -67,6 +67,7 @@ use ich::Fingerprint;
use ty::TyCtxt;
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use ich::StableHashingContext;
use std::fmt;
use std::hash::Hash;

// erase!() just makes tokens go away. It's used to specify which macro argument
Expand Down Expand Up @@ -145,7 +146,7 @@ macro_rules! define_dep_nodes {
),*
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable)]
pub struct DepNode {
pub kind: DepKind,
Expand All @@ -166,21 +167,45 @@ macro_rules! define_dep_nodes {
let tupled_args = ( $($tuple_arg,)* );
let hash = DepNodeParams::to_fingerprint(&tupled_args,
tcx);
return DepNode {
let dep_node = DepNode {
kind: DepKind::$variant,
hash
};

if cfg!(debug_assertions) &&
!dep_node.kind.can_reconstruct_query_key() &&
(tcx.sess.opts.debugging_opts.incremental_info ||
tcx.sess.opts.debugging_opts.query_dep_graph)
{
tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
tupled_args.to_debug_str(tcx)
});
}

return dep_node;
})*

// struct args
$({
let tupled_args = ( $($struct_arg_name,)* );
let hash = DepNodeParams::to_fingerprint(&tupled_args,
tcx);
return DepNode {
let dep_node = DepNode {
kind: DepKind::$variant,
hash
};

if cfg!(debug_assertions) &&
!dep_node.kind.can_reconstruct_query_key() &&
(tcx.sess.opts.debugging_opts.incremental_info ||
tcx.sess.opts.debugging_opts.query_dep_graph)
{
tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
tupled_args.to_debug_str(tcx)
});
}

return dep_node;
})*

DepNode {
Expand Down Expand Up @@ -267,6 +292,36 @@ macro_rules! define_dep_nodes {
);
}

impl fmt::Debug for DepNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.kind)?;

if !self.kind.has_params() {
return Ok(());
}

write!(f, "(")?;

::ty::tls::with_opt(|opt_tcx| {
if let Some(tcx) = opt_tcx {
if let Some(def_id) = self.extract_def_id(tcx) {
write!(f, "{}", tcx.item_path_str(def_id))?;
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
write!(f, "{}", s)?;
} else {
write!(f, "{:?}", self.hash)?;
}
} else {
write!(f, "{:?}", self.hash)?;
}
Ok(())
})?;

write!(f, ")")
}
}


impl DefPathHash {
#[inline]
pub fn to_dep_node(self, kind: DepKind) -> DepNode {
Expand Down Expand Up @@ -434,10 +489,11 @@ define_dep_nodes!(
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> {
const CAN_RECONSTRUCT_QUERY_KEY: bool;
fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint;
fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String;
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + fmt::Debug
{
default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;

Expand All @@ -449,6 +505,10 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T

hasher.finish()
}

default fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
format!("{:?}", *self)
}
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
Expand All @@ -457,6 +517,62 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
tcx.def_path_hash(self.0).0
}

fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
tcx.item_path_str(self.0)
}
}

impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
const CAN_RECONSTRUCT_QUERY_KEY: bool = false;

fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
let (def_id_0, def_id_1) = *self;

let def_path_hash_0 = tcx.def_path_hash(def_id_0);
let def_path_hash_1 = tcx.def_path_hash(def_id_1);

def_path_hash_0.0.combine(def_path_hash_1.0)
}

fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
let (def_id_0, def_id_1) = *self;

format!("({}, {})",
tcx.def_path(def_id_0).to_string(tcx),
tcx.def_path(def_id_1).to_string(tcx))
}
}


impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIdList,) {
const CAN_RECONSTRUCT_QUERY_KEY: bool = false;

fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
let mut fingerprint = Fingerprint::zero();

for &def_id in self.0.iter() {
let def_path_hash = tcx.def_path_hash(def_id);
fingerprint = fingerprint.combine(def_path_hash.0);
}

fingerprint
}

fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
use std::fmt::Write;

let mut s = String::new();
write!(&mut s, "[").unwrap();

for &def_id in self.0.iter() {
write!(&mut s, "{}", tcx.def_path(def_id).to_string(tcx)).unwrap();
}

write!(&mut s, "]").unwrap();

s
}
}

/// A "work product" corresponds to a `.o` (or other) file that we
Expand Down
19 changes: 19 additions & 0 deletions src/librustc/dep_graph/graph.rs
Expand Up @@ -37,6 +37,8 @@ struct DepGraphData {

/// Work-products that we generate in this run.
work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,

dep_node_debug: RefCell<FxHashMap<DepNode, String>>,
}

impl DepGraph {
Expand All @@ -46,6 +48,7 @@ impl DepGraph {
thread: DepGraphThreadData::new(enabled),
previous_work_products: RefCell::new(FxHashMap()),
work_products: RefCell::new(FxHashMap()),
dep_node_debug: RefCell::new(FxHashMap()),
})
}
}
Expand Down Expand Up @@ -152,6 +155,22 @@ impl DepGraph {
pub fn previous_work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
self.data.previous_work_products.borrow()
}

#[inline(always)]
pub(super) fn register_dep_node_debug_str<F>(&self,
dep_node: DepNode,
debug_str_gen: F)
where F: FnOnce() -> String
{
let mut dep_node_debug = self.data.dep_node_debug.borrow_mut();

dep_node_debug.entry(dep_node)
.or_insert_with(debug_str_gen);
}

pub(super) fn dep_node_debug_str(&self, dep_node: DepNode) -> Option<String> {
self.data.dep_node_debug.borrow().get(&dep_node).cloned()
}
}

/// A "work product" is an intermediate result that we save into the
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/ich/fingerprint.rs
Expand Up @@ -31,9 +31,20 @@ impl Fingerprint {
self.0
}

#[inline]
pub fn combine(self, other: Fingerprint) -> Fingerprint {
// See https://stackoverflow.com/a/27952689 on why this function is
// implemented this way.
Fingerprint(
self.0.wrapping_mul(3).wrapping_add(other.0),
self.1.wrapping_mul(3).wrapping_add(other.1)
)
}

pub fn to_hex(&self) -> String {
format!("{:x}{:x}", self.0, self.1)
}

}

impl ::std::fmt::Display for Fingerprint {
Expand Down

0 comments on commit 5b5499d

Please sign in to comment.