Skip to content

Commit

Permalink
Introduce non-incremental queries and load the dep graph with a query
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Jul 8, 2019
1 parent 391fc05 commit 9a80997
Show file tree
Hide file tree
Showing 33 changed files with 358 additions and 259 deletions.
1 change: 1 addition & 0 deletions src/librustc/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ macro_rules! arena_types {
rustc::hir::def_id::DefId,
rustc::ty::subst::SubstsRef<$tcx>
)>,
[few] dep_graph: rustc::dep_graph::DepGraph,
[few] lowered_hir: rustc::hir::LoweredHir,
[few] hir_map: rustc::hir::map::Map<$tcx>,
[few, decode] mir_keys: rustc::util::nodemap::DefIdSet,
Expand Down
12 changes: 7 additions & 5 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ macro_rules! define_dep_nodes {
(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, || {
tcx.dep_graph().register_dep_node_debug_str(dep_node, || {
arg.to_debug_str(tcx)
});
}
Expand All @@ -247,7 +247,7 @@ macro_rules! define_dep_nodes {
(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, || {
tcx.dep_graph().register_dep_node_debug_str(dep_node, || {
tupled_args.to_debug_str(tcx)
});
}
Expand Down Expand Up @@ -368,7 +368,7 @@ impl fmt::Debug for DepNode {
if let Some(tcx) = opt_tcx {
if let Some(def_id) = self.extract_def_id(tcx) {
write!(f, "{}", tcx.def_path_debug_str(def_id))?;
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
} else if let Some(ref s) = tcx.dep_graph().dep_node_debug_str(*self) {
write!(f, "{}", s)?;
} else {
write!(f, "{}", self.hash)?;
Expand Down Expand Up @@ -402,6 +402,10 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
// We use this for most things when incr. comp. is turned off.
[] Null,

// Represents all queries which are not incremental.
// This is always treated as a red dep node.
[] NonIncremental,

// Represents the `Krate` as a whole (the `hir::Krate` value) (as
// distinct from the krate module). This is basically a hash of
// the entire krate, so if you read from `Krate` (e.g., by calling
Expand Down Expand Up @@ -430,8 +434,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
[anon] TraitSelect,

[] CompileCodegenUnit(InternedString),

[eval_always] Analysis(CrateNum),
]);

pub trait RecoverKey<'tcx>: Sized {
Expand Down
89 changes: 70 additions & 19 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,32 @@ use super::safe::DepGraphSafe;
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
use super::prev::PreviousDepGraph;

pub type WorkProductMap = FxHashMap<WorkProductId, WorkProduct>;

pub enum LoadResult<T> {
Ok { data: T },
DataOutOfDate,
Error { message: String },
}

/// Either a result that has already be computed or a
/// handle that will let us wait until it is computed
/// by a background thread.
pub enum MaybeAsync<T> {
Sync(T),
Async(std::thread::JoinHandle<T>)
}
impl<T> MaybeAsync<T> {
pub fn open(self) -> std::thread::Result<T> {
match self {
MaybeAsync::Sync(result) => Ok(result),
MaybeAsync::Async(handle) => handle.join()
}
}
}

pub type DepGraphFuture = MaybeAsync<LoadResult<(PreviousDepGraph, WorkProductMap)>>;

#[derive(Clone)]
pub struct DepGraph {
data: Option<Lrc<DepGraphData>>,
Expand All @@ -30,7 +56,7 @@ newtype_index! {
}

impl DepNodeIndex {
const INVALID: DepNodeIndex = DepNodeIndex::MAX;
pub(crate) const INVALID: DepNodeIndex = DepNodeIndex::MAX;
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -94,17 +120,29 @@ impl DepGraph {
prev_work_products: FxHashMap<WorkProductId, WorkProduct>) -> DepGraph {
let prev_graph_node_count = prev_graph.node_count();

let mut data = DepGraphData {
previous_work_products: prev_work_products,
dep_node_debug: Default::default(),
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
emitted_diagnostics: Default::default(),
emitted_diagnostics_cond_var: Condvar::new(),
previous: prev_graph,
colors: DepNodeColorMap::new(prev_graph_node_count),
loaded_from_cache: Default::default(),
};

let non_incr_dep_node = DepNode::new_no_params(DepKind::NonIncremental);

// Allocate the NonIncremental node
data.current.get_mut().alloc_node(non_incr_dep_node, smallvec![], Fingerprint::ZERO);

data.previous.node_to_index_opt(&non_incr_dep_node).map(|prev_index| {
// Color previous NonIncremental node as red
data.colors.insert(prev_index, DepNodeColor::Red);
});

DepGraph {
data: Some(Lrc::new(DepGraphData {
previous_work_products: prev_work_products,
dep_node_debug: Default::default(),
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
emitted_diagnostics: Default::default(),
emitted_diagnostics_cond_var: Condvar::new(),
previous: prev_graph,
colors: DepNodeColorMap::new(prev_graph_node_count),
loaded_from_cache: Default::default(),
})),
data: Some(Lrc::new(data)),
}
}

Expand Down Expand Up @@ -135,18 +173,21 @@ impl DepGraph {
DepGraphQuery::new(&nodes[..], &edges[..])
}

pub fn assert_ignored(&self)
{
if let Some(..) = self.data {
ty::tls::with_context_opt(|icx| {
let icx = if let Some(icx) = icx { icx } else { return };
assert!(icx.task_deps.is_none(), "expected no task dependency tracking");
})
}
pub fn assert_ignored() {
ty::tls::with_context_opt(|icx| {
let icx = if let Some(icx) = icx { icx } else { return };
assert!(icx.task_deps.is_none(), "expected no task dependency tracking");
})
}

pub fn with_ignore<OP,R>(&self, op: OP) -> R
where OP: FnOnce() -> R
{
Self::ignore_deps(op)
}

pub fn ignore_deps<OP,R>(op: OP) -> R
where OP: FnOnce() -> R
{
ty::tls::with_context(|icx| {
let icx = ty::tls::ImplicitCtxt {
Expand Down Expand Up @@ -394,6 +435,16 @@ impl DepGraph {
hash_result)
}

#[inline]
pub fn read_non_incr(tcx: TyCtxt<'_>) {
// Avoid loading the `dep_graph` here if we don't need to track dependencies.
// We want to load the `dep_graph` in the background.
if ty::tls::with_context(|icx| icx.task_deps.is_none()) {
return;
}
tcx.dep_graph().read(DepNode::new_no_params(DepKind::NonIncremental));
}

#[inline]
pub fn read(&self, v: DepNode) {
if let Some(ref data) = self.data {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub mod cgu_reuse_tracker;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
pub use self::graph::WorkProductFileKind;
pub use self::graph::{WorkProductFileKind, DepGraphFuture, LoadResult, WorkProductMap, MaybeAsync};
pub use self::prev::PreviousDepGraph;
pub use self::query::DepGraphQuery;
pub use self::safe::AssertDepGraphSafe;
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,13 @@ impl<'a> ImplTraitContext<'a> {
pub fn lower_crate(
sess: &Session,
cstore: &dyn CrateStore,
dep_graph: &DepGraph,
krate: &Crate,
resolver: &mut dyn Resolver,
) -> hir::Crate {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
dep_graph.assert_ignored();
DepGraph::assert_ignored();

LoweringContext {
crate_root: std_inject::injected_crate_name().map(Symbol::intern),
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/hir/map/hir_id_validator.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
use crate::hir::{self, intravisit, HirId, ItemLocalId};
use crate::dep_graph::DepGraph;
use crate::hir::itemlikevisit::ItemLikeVisitor;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter};

pub fn check_crate(hir_map: &hir::map::Map<'_>) {
hir_map.dep_graph.assert_ignored();
DepGraph::assert_ignored();

let errors = Lock::new(Vec::new());

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,7 @@ pub fn map_crate(tcx: TyCtxt<'_>) -> Map<'_> {
let mut collector = NodeCollector::root(
tcx.sess,
krate,
&tcx.dep_graph,
&tcx.dep_graph(),
&hir.defs,
&hir_to_node_id,
hcx
Expand All @@ -1167,7 +1167,7 @@ pub fn map_crate(tcx: TyCtxt<'_>) -> Map<'_> {

let map = Map {
forest: &hir.forest,
dep_graph: tcx.dep_graph.clone(),
dep_graph: tcx.dep_graph().clone(),
crate_hash,
map,
hir_to_node_id,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ impl<'tcx> CodegenUnit<'tcx> {

pub fn work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
let work_product_id = self.work_product_id();
tcx.dep_graph
tcx.dep_graph()
.previous_work_product(&work_product_id)
.unwrap_or_else(|| {
panic!("Could not find work-product for CGU `{}`", self.name())
Expand Down
19 changes: 19 additions & 0 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ use syntax_pos::symbol::InternedString;
// as they will raise an fatal error on query cycles instead.
rustc_queries! {
Other {
query dep_graph_future(_: ()) -> Lrc<Steal<Option<DepGraphFuture>>> {
no_hash
eval_always
desc { "loading the dependency graph in the background" }
}

query load_dep_graph(_: ()) -> &'tcx DepGraph {
no_hash
eval_always
desc { "loading the dependency graph" }
}

query parse(_: ()) -> Result<Lrc<Steal<ast::Crate>>, ErrorReported> {
no_hash
eval_always
Expand Down Expand Up @@ -77,6 +89,13 @@ rustc_queries! {
desc { "indexing HIR" }
}

/// Run analysis passes on the crate
query analysis(_: CrateNum) -> Result<(), ErrorReported> {
no_hash
eval_always
desc { "running analysis passes on this crate" }
}

/// Records the type of every item.
query type_of(key: DefId) -> Ty<'tcx> {
cache_on_disk_if { key.is_local() }
Expand Down
9 changes: 4 additions & 5 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,10 +1318,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
where
OP: FnOnce(&mut Self) -> R,
{
let (result, dep_node) = self.tcx()
.dep_graph
.with_anon_task(DepKind::TraitSelect, || op(self));
self.tcx().dep_graph.read_index(dep_node);
let dep_graph = self.tcx().dep_graph();
let (result, dep_node) = dep_graph.with_anon_task(DepKind::TraitSelect, || op(self));
dep_graph.read_index(dep_node);
(result, dep_node)
}

Expand Down Expand Up @@ -4328,7 +4327,7 @@ impl<T: Clone> WithDepNode<T> {
}

pub fn get(&self, tcx: TyCtxt<'_>) -> T {
tcx.dep_graph.read_index(self.dep_node);
tcx.dep_graph().read_index(self.dep_node);
self.cached_value.clone()
}
}
Loading

0 comments on commit 9a80997

Please sign in to comment.