Skip to content

Commit e482df6

Browse files
committed
Introduce non-incremental queries and load the dep graph with a query
1 parent 87f4623 commit e482df6

File tree

34 files changed

+386
-266
lines changed

34 files changed

+386
-266
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ macro_rules! define_dep_nodes {
229229
(tcx.sess.opts.debugging_opts.incremental_info ||
230230
tcx.sess.opts.debugging_opts.query_dep_graph)
231231
{
232-
tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
232+
tcx.dep_graph().register_dep_node_debug_str(dep_node, || {
233233
arg.to_debug_str(tcx)
234234
});
235235
}
@@ -252,7 +252,7 @@ macro_rules! define_dep_nodes {
252252
(tcx.sess.opts.debugging_opts.incremental_info ||
253253
tcx.sess.opts.debugging_opts.query_dep_graph)
254254
{
255-
tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
255+
tcx.dep_graph().register_dep_node_debug_str(dep_node, || {
256256
tupled_args.to_debug_str(tcx)
257257
});
258258
}
@@ -373,7 +373,7 @@ impl fmt::Debug for DepNode {
373373
if let Some(tcx) = opt_tcx {
374374
if let Some(def_id) = self.extract_def_id(tcx) {
375375
write!(f, "{}", tcx.def_path_debug_str(def_id))?;
376-
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
376+
} else if let Some(ref s) = tcx.dep_graph().dep_node_debug_str(*self) {
377377
write!(f, "{}", s)?;
378378
} else {
379379
write!(f, "{}", self.hash)?;
@@ -407,6 +407,10 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
407407
// We use this for most things when incr. comp. is turned off.
408408
[] Null,
409409

410+
// Represents all queries which are not incremental.
411+
// This is always treated as a red dep node.
412+
[] NonIncremental,
413+
410414
// Represents the `Krate` as a whole (the `hir::Krate` value) (as
411415
// distinct from the krate module). This is basically a hash of
412416
// the entire krate, so if you read from `Krate` (e.g., by calling
@@ -435,8 +439,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
435439
[anon] TraitSelect,
436440

437441
[] CompileCodegenUnit(InternedString),
438-
439-
[eval_always] Analysis(CrateNum),
440442
]);
441443

442444
pub trait RecoverKey<'tcx>: Sized {

src/librustc/dep_graph/graph.rs

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@ use super::safe::DepGraphSafe;
2020
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
2121
use super::prev::PreviousDepGraph;
2222

23+
pub type WorkProductMap = FxHashMap<WorkProductId, WorkProduct>;
24+
25+
pub enum LoadResult<T> {
26+
Ok { data: T },
27+
DataOutOfDate,
28+
Error { message: String },
29+
}
30+
31+
/// Either a result that has already be computed or a
32+
/// handle that will let us wait until it is computed
33+
/// by a background thread.
34+
pub enum MaybeAsync<T> {
35+
Sync(T),
36+
Async(std::thread::JoinHandle<T>)
37+
}
38+
impl<T> MaybeAsync<T> {
39+
pub fn open(self) -> std::thread::Result<T> {
40+
match self {
41+
MaybeAsync::Sync(result) => Ok(result),
42+
MaybeAsync::Async(handle) => handle.join()
43+
}
44+
}
45+
}
46+
47+
pub type DepGraphFuture = MaybeAsync<LoadResult<(PreviousDepGraph, WorkProductMap)>>;
48+
2349
#[derive(Clone)]
2450
pub struct DepGraph {
2551
data: Option<Lrc<DepGraphData>>,
@@ -30,7 +56,7 @@ newtype_index! {
3056
}
3157

3258
impl DepNodeIndex {
33-
const INVALID: DepNodeIndex = DepNodeIndex::MAX;
59+
pub(crate) const INVALID: DepNodeIndex = DepNodeIndex::MAX;
3460
}
3561

3662
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -95,17 +121,29 @@ impl DepGraph {
95121
prev_work_products: FxHashMap<WorkProductId, WorkProduct>) -> DepGraph {
96122
let prev_graph_node_count = prev_graph.node_count();
97123

124+
let mut data = DepGraphData {
125+
previous_work_products: prev_work_products,
126+
dep_node_debug: Default::default(),
127+
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
128+
emitted_diagnostics: Default::default(),
129+
emitted_diagnostics_cond_var: Condvar::new(),
130+
previous: prev_graph,
131+
colors: DepNodeColorMap::new(prev_graph_node_count),
132+
loaded_from_cache: Default::default(),
133+
};
134+
135+
let non_incr_dep_node = DepNode::new_no_params(DepKind::NonIncremental);
136+
137+
// Allocate the NonIncremental node
138+
data.current.get_mut().alloc_node(non_incr_dep_node, smallvec![], Fingerprint::ZERO);
139+
140+
data.previous.node_to_index_opt(&non_incr_dep_node).map(|prev_index| {
141+
// Color previous NonIncremental node as red
142+
data.colors.insert(prev_index, DepNodeColor::Red);
143+
});
144+
98145
DepGraph {
99-
data: Some(Lrc::new(DepGraphData {
100-
previous_work_products: prev_work_products,
101-
dep_node_debug: Default::default(),
102-
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
103-
emitted_diagnostics: Default::default(),
104-
emitted_diagnostics_cond_var: Condvar::new(),
105-
previous: prev_graph,
106-
colors: DepNodeColorMap::new(prev_graph_node_count),
107-
loaded_from_cache: Default::default(),
108-
})),
146+
data: Some(Lrc::new(data)),
109147
}
110148
}
111149

@@ -136,18 +174,21 @@ impl DepGraph {
136174
DepGraphQuery::new(&nodes[..], &edges[..])
137175
}
138176

139-
pub fn assert_ignored(&self)
140-
{
141-
if let Some(..) = self.data {
142-
ty::tls::with_context_opt(|icx| {
143-
let icx = if let Some(icx) = icx { icx } else { return };
144-
assert!(icx.task_deps.is_none(), "expected no task dependency tracking");
145-
})
146-
}
177+
pub fn assert_ignored() {
178+
ty::tls::with_context_opt(|icx| {
179+
let icx = if let Some(icx) = icx { icx } else { return };
180+
assert!(icx.task_deps.is_none(), "expected no task dependency tracking");
181+
})
147182
}
148183

149184
pub fn with_ignore<OP,R>(&self, op: OP) -> R
150185
where OP: FnOnce() -> R
186+
{
187+
Self::ignore_deps(op)
188+
}
189+
190+
pub fn ignore_deps<OP,R>(op: OP) -> R
191+
where OP: FnOnce() -> R
151192
{
152193
ty::tls::with_context(|icx| {
153194
let icx = ty::tls::ImplicitCtxt {
@@ -395,6 +436,16 @@ impl DepGraph {
395436
hash_result)
396437
}
397438

439+
#[inline]
440+
pub fn read_non_incr(tcx: TyCtxt<'_, '_, '_>) {
441+
// Avoid loading the `dep_graph` here if we don't need to track dependencies.
442+
// We want to load the `dep_graph` in the background.
443+
if ty::tls::with_context(|icx| icx.task_deps.is_none()) {
444+
return;
445+
}
446+
tcx.dep_graph().read(DepNode::new_no_params(DepKind::NonIncremental));
447+
}
448+
398449
#[inline]
399450
pub fn read(&self, v: DepNode) {
400451
if let Some(ref data) = self.data {

src/librustc/dep_graph/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub mod cgu_reuse_tracker;
1111
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
1212
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs};
1313
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
14-
pub use self::graph::WorkProductFileKind;
14+
pub use self::graph::{WorkProductFileKind, DepGraphFuture, LoadResult, WorkProductMap, MaybeAsync};
1515
pub use self::prev::PreviousDepGraph;
1616
pub use self::query::DepGraphQuery;
1717
pub use self::safe::AssertDepGraphSafe;

src/librustc/hir/lowering.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,13 @@ impl<'a> ImplTraitContext<'a> {
212212
pub fn lower_crate(
213213
sess: &Session,
214214
cstore: &dyn CrateStore,
215-
dep_graph: &DepGraph,
216215
krate: &Crate,
217216
resolver: &mut dyn Resolver,
218217
) -> hir::Crate {
219218
// We're constructing the HIR here; we don't care what we will
220219
// read, since we haven't even constructed the *input* to
221220
// incr. comp. yet.
222-
dep_graph.assert_ignored();
221+
DepGraph::assert_ignored();
223222

224223
LoweringContext {
225224
crate_root: std_inject::injected_crate_name(),

src/librustc/hir/map/hir_id_validator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
22
use crate::hir::{self, intravisit, HirId, ItemLocalId};
3+
use crate::dep_graph::DepGraph;
34
use syntax::ast::NodeId;
45
use crate::hir::itemlikevisit::ItemLikeVisitor;
56
use rustc_data_structures::fx::FxHashSet;
67
use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter};
78

89
pub fn check_crate<'hir>(hir_map: &hir::map::Map<'hir>) {
9-
hir_map.dep_graph.assert_ignored();
10+
DepGraph::assert_ignored();
1011

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

src/librustc/hir/map/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ pub fn map_crate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Map<'tcx> {
12441244
let mut collector = NodeCollector::root(
12451245
tcx.sess,
12461246
krate,
1247-
&tcx.dep_graph,
1247+
&tcx.dep_graph(),
12481248
&hir.defs,
12491249
&hir_to_node_id,
12501250
hcx
@@ -1274,7 +1274,7 @@ pub fn map_crate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Map<'tcx> {
12741274

12751275
let map = Map {
12761276
forest: &hir.forest,
1277-
dep_graph: tcx.dep_graph.clone(),
1277+
dep_graph: tcx.dep_graph().clone(),
12781278
crate_hash,
12791279
map,
12801280
hir_to_node_id,

src/librustc/query/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ use syntax_pos::symbol::InternedString;
3030
// as they will raise an fatal error on query cycles instead.
3131
rustc_queries! {
3232
Other {
33+
query dep_graph_future(_: LocalCrate) -> Lrc<Steal<Option<DepGraphFuture>>> {
34+
no_hash
35+
eval_always
36+
desc { "loading the dependency graph in the background" }
37+
}
38+
39+
query load_dep_graph(_: LocalCrate) -> &'tcx DepGraph {
40+
no_hash
41+
eval_always
42+
desc { "loading the dependency graph" }
43+
}
44+
3345
query parse(_: LocalCrate) -> Result<Lrc<Steal<ast::Crate>>, ErrorReported> {
3446
no_hash
3547
eval_always
@@ -76,6 +88,13 @@ rustc_queries! {
7688
desc { "indexing HIR" }
7789
}
7890

91+
/// Run analysis passes on the crate
92+
query analysis(_: CrateNum) -> Result<(), ErrorReported> {
93+
no_hash
94+
eval_always
95+
desc { "running analysis passes on this crate" }
96+
}
97+
7998
/// Records the type of every item.
8099
query type_of(key: DefId) -> Ty<'tcx> {
81100
cache { key.is_local() }

src/librustc/traits/select.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,10 +1190,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11901190
where
11911191
OP: FnOnce(&mut Self) -> R,
11921192
{
1193-
let (result, dep_node) = self.tcx()
1194-
.dep_graph
1195-
.with_anon_task(DepKind::TraitSelect, || op(self));
1196-
self.tcx().dep_graph.read_index(dep_node);
1193+
let dep_graph = self.tcx().dep_graph();
1194+
let (result, dep_node) = dep_graph.with_anon_task(DepKind::TraitSelect, || op(self));
1195+
dep_graph.read_index(dep_node);
11971196
(result, dep_node)
11981197
}
11991198

@@ -3944,7 +3943,7 @@ impl<T: Clone> WithDepNode<T> {
39443943
}
39453944

39463945
pub fn get(&self, tcx: TyCtxt<'_, '_, '_>) -> T {
3947-
tcx.dep_graph.read_index(self.dep_node);
3946+
tcx.dep_graph().read_index(self.dep_node);
39483947
self.cached_value.clone()
39493948
}
39503949
}

src/librustc/ty/context.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,10 @@ pub struct GlobalCtxt<'tcx> {
10121012

10131013
pub sess: &'tcx Session,
10141014

1015-
pub dep_graph: DepGraph,
1015+
pub dep_graph_store: Once<DepGraph>,
1016+
1017+
// FIXME: Get rid of the double indirection here
1018+
dep_graph: AtomicOnce<&'tcx DepGraph>,
10161019

10171020
/// Common types, pre-interned for your convenience.
10181021
pub types: CommonTypes<'tcx>,
@@ -1082,17 +1085,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10821085
self.lowered_hir().def_path_hash_to_def_id.as_ref()
10831086
}
10841087

1088+
#[inline(always)]
1089+
pub fn dep_graph(self) -> &'gcx DepGraph {
1090+
self.dep_graph.get_or_init(|| {
1091+
// We shouldn't be tracking dependencies beforing loading the dep graph
1092+
DepGraph::assert_ignored();
1093+
self.load_dep_graph(LocalCrate)
1094+
})
1095+
}
1096+
10851097
#[inline(always)]
10861098
pub fn lowered_hir(self) -> &'gcx hir::LoweredHir {
10871099
self.lowered_hir.get_or_init(|| {
1088-
// FIXME: The ignore here is only sound because all queries
1089-
// used to compute LoweredHir are eval_always
1090-
self.dep_graph.with_ignore(|| {
1091-
let map = self.lower_ast_to_hir(LocalCrate).unwrap();
1092-
self.lowered_hir.init(map);
1093-
self.allocate_metadata_dep_nodes();
1094-
map
1095-
})
1100+
// We shouldn't have loaded the dep graph yet here,
1101+
// so we should not be tracking dependencies.
1102+
DepGraph::assert_ignored();
1103+
let map = self.lower_ast_to_hir(LocalCrate).unwrap();
1104+
self.lowered_hir.init(map);
1105+
self.allocate_metadata_dep_nodes();
1106+
map
10961107
})
10971108
}
10981109

@@ -1104,7 +1115,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11041115
pub fn hir(self) -> &'gcx hir_map::Map<'gcx> {
11051116
self.hir_map.get_or_init(|| {
11061117
// We can use `with_ignore` here because the hir map does its own tracking
1107-
self.dep_graph.with_ignore(|| self.hir_map(LOCAL_CRATE))
1118+
DepGraph::ignore_deps(|| self.hir_map(LOCAL_CRATE))
11081119
})
11091120
}
11101121

@@ -1209,7 +1220,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12091220
local_providers: ty::query::Providers<'tcx>,
12101221
extern_providers: ty::query::Providers<'tcx>,
12111222
arenas: &'tcx AllArenas<'tcx>,
1212-
dep_graph: DepGraph,
12131223
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
12141224
crate_name: Option<String>,
12151225
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1231,7 +1241,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12311241
sess_rc: s.clone(),
12321242
global_arenas: &arenas.global,
12331243
global_interners: interners,
1234-
dep_graph,
1244+
dep_graph: AtomicOnce::new(),
1245+
dep_graph_store: Once::new(),
12351246
types: common_types,
12361247
lowered_hir: AtomicOnce::new(),
12371248
hir_map: AtomicOnce::new(),
@@ -1400,7 +1411,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14001411
// With full-fledged red/green, the method will probably become unnecessary
14011412
// as this will be done on-demand.
14021413
pub fn allocate_metadata_dep_nodes(self) {
1403-
if !self.dep_graph.is_fully_enabled() {
1414+
if !self.dep_graph().is_fully_enabled() {
14041415
return
14051416
}
14061417

@@ -1410,11 +1421,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14101421
for cnum in self.cstore.crates_untracked() {
14111422
let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
14121423
let crate_hash = self.cstore.crate_hash_untracked(cnum);
1413-
self.dep_graph.with_task(dep_node,
1414-
self,
1415-
crate_hash,
1416-
|_, x| x, // No transformation needed
1417-
Some(dep_graph::hash_result),
1424+
self.dep_graph().with_task(
1425+
dep_node,
1426+
self,
1427+
crate_hash,
1428+
|_, x| x, // No transformation needed
1429+
Some(dep_graph::hash_result),
14181430
);
14191431
}
14201432
});

0 commit comments

Comments
 (0)