Skip to content

Commit 8bf0dec

Browse files
committed
Auto merge of #116109 - Zoxc:no-dep-graph-thread, r=oli-obk
Don't use a thread to load the dep graph This removes the use of a thread to load the dep graph. It's not currently useful as we immediately block on it. r? `@oli-obk`
2 parents d23062b + ba8d53d commit 8bf0dec

File tree

5 files changed

+68
-118
lines changed

5 files changed

+68
-118
lines changed

Diff for: compiler/rustc_incremental/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ pub use persist::load_query_result_cache;
2828
pub use persist::prepare_session_directory;
2929
pub use persist::save_dep_graph;
3030
pub use persist::save_work_product_index;
31+
pub use persist::setup_dep_graph;
3132
pub use persist::LoadResult;
32-
pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture};
3333

3434
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
3535
use rustc_fluent_macro::fluent_messages;

Diff for: compiler/rustc_incremental/src/persist/load.rs

+62-70
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33
use crate::errors;
44
use rustc_data_structures::memmap::Mmap;
55
use rustc_data_structures::unord::UnordMap;
6-
use rustc_middle::dep_graph::{DepsType, SerializedDepGraph, WorkProductMap};
6+
use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProductMap};
77
use rustc_middle::query::on_disk_cache::OnDiskCache;
88
use rustc_serialize::opaque::MemDecoder;
99
use rustc_serialize::Decodable;
1010
use rustc_session::config::IncrementalStateAssertion;
11-
use rustc_session::Session;
11+
use rustc_session::{Session, StableCrateId};
12+
use rustc_span::{ErrorGuaranteed, Symbol};
1213
use std::path::{Path, PathBuf};
1314

1415
use super::data::*;
1516
use super::file_format;
1617
use super::fs::*;
18+
use super::save::build_dep_graph;
1719
use super::work_product;
1820

1921
#[derive(Debug)]
@@ -72,21 +74,12 @@ impl<T: Default> LoadResult<T> {
7274
}
7375

7476
fn load_data(path: &Path, sess: &Session) -> LoadResult<(Mmap, usize)> {
75-
load_data_no_sess(
77+
match file_format::read_file(
7678
path,
7779
sess.opts.unstable_opts.incremental_info,
7880
sess.is_nightly_build(),
7981
sess.cfg_version,
80-
)
81-
}
82-
83-
fn load_data_no_sess(
84-
path: &Path,
85-
report_incremental_info: bool,
86-
is_nightly_build: bool,
87-
cfg_version: &'static str,
88-
) -> LoadResult<(Mmap, usize)> {
89-
match file_format::read_file(path, report_incremental_info, is_nightly_build, cfg_version) {
82+
) {
9083
Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
9184
Ok(None) => {
9285
// The file either didn't exist or was produced by an incompatible
@@ -102,47 +95,19 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
10295
work_product::delete_workproduct_files(sess, &swp.work_product);
10396
}
10497

105-
/// Either a result that has already be computed or a
106-
/// handle that will let us wait until it is computed
107-
/// by a background thread.
108-
pub enum MaybeAsync<T> {
109-
Sync(T),
110-
Async(std::thread::JoinHandle<T>),
111-
}
112-
113-
impl<T> MaybeAsync<LoadResult<T>> {
114-
/// Accesses the data returned in [`LoadResult::Ok`] in an asynchronous way if possible.
115-
pub fn open(self) -> LoadResult<T> {
116-
match self {
117-
MaybeAsync::Sync(result) => result,
118-
MaybeAsync::Async(handle) => {
119-
handle.join().unwrap_or_else(|e| LoadResult::DecodeIncrCache(e))
120-
}
121-
}
122-
}
123-
}
124-
125-
/// An asynchronous type for computing the dependency graph.
126-
pub type DepGraphFuture = MaybeAsync<LoadResult<(SerializedDepGraph, WorkProductMap)>>;
127-
128-
/// Launch a thread and load the dependency graph in the background.
129-
pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
130-
// Since `sess` isn't `Sync`, we perform all accesses to `sess`
131-
// before we fire the background thread.
132-
98+
fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProductMap)> {
13399
let prof = sess.prof.clone();
134100

135101
if sess.opts.incremental.is_none() {
136102
// No incremental compilation.
137-
return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() });
103+
return LoadResult::Ok { data: Default::default() };
138104
}
139105

140106
let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph");
141107

142108
// Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
143109
// Fortunately, we just checked that this isn't the case.
144110
let path = dep_graph_path(&sess);
145-
let report_incremental_info = sess.opts.unstable_opts.incremental_info;
146111
let expected_hash = sess.opts.dep_tracking_hash(false);
147112

148113
let mut prev_work_products = UnordMap::default();
@@ -180,40 +145,35 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
180145
}
181146
}
182147

183-
let is_nightly_build = sess.is_nightly_build();
184-
let cfg_version = sess.cfg_version;
185-
186-
MaybeAsync::Async(std::thread::spawn(move || {
187-
let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
148+
let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
188149

189-
match load_data_no_sess(&path, report_incremental_info, is_nightly_build, cfg_version) {
190-
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
191-
LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
192-
LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
193-
LoadResult::Ok { data: (bytes, start_pos) } => {
194-
let mut decoder = MemDecoder::new(&bytes, start_pos);
195-
let prev_commandline_args_hash = u64::decode(&mut decoder);
150+
match load_data(&path, sess) {
151+
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
152+
LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
153+
LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
154+
LoadResult::Ok { data: (bytes, start_pos) } => {
155+
let mut decoder = MemDecoder::new(&bytes, start_pos);
156+
let prev_commandline_args_hash = u64::decode(&mut decoder);
196157

197-
if prev_commandline_args_hash != expected_hash {
198-
if report_incremental_info {
199-
eprintln!(
200-
"[incremental] completely ignoring cache because of \
158+
if prev_commandline_args_hash != expected_hash {
159+
if sess.opts.unstable_opts.incremental_info {
160+
eprintln!(
161+
"[incremental] completely ignoring cache because of \
201162
differing commandline arguments"
202-
);
203-
}
204-
// We can't reuse the cache, purge it.
205-
debug!("load_dep_graph_new: differing commandline arg hashes");
206-
207-
// No need to do any further work
208-
return LoadResult::DataOutOfDate;
163+
);
209164
}
165+
// We can't reuse the cache, purge it.
166+
debug!("load_dep_graph_new: differing commandline arg hashes");
210167

211-
let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
212-
213-
LoadResult::Ok { data: (dep_graph, prev_work_products) }
168+
// No need to do any further work
169+
return LoadResult::DataOutOfDate;
214170
}
171+
172+
let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
173+
174+
LoadResult::Ok { data: (dep_graph, prev_work_products) }
215175
}
216-
}))
176+
}
217177
}
218178

219179
/// Attempts to load the query result cache from disk
@@ -235,3 +195,35 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
235195
_ => Some(OnDiskCache::new_empty(sess.source_map())),
236196
}
237197
}
198+
199+
/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
200+
/// new graph to an incremental session directory.
201+
pub fn setup_dep_graph(
202+
sess: &Session,
203+
crate_name: Symbol,
204+
stable_crate_id: StableCrateId,
205+
) -> Result<DepGraph, ErrorGuaranteed> {
206+
// `load_dep_graph` can only be called after `prepare_session_directory`.
207+
prepare_session_directory(sess, crate_name, stable_crate_id)?;
208+
209+
let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));
210+
211+
if sess.opts.incremental.is_some() {
212+
sess.time("incr_comp_garbage_collect_session_directories", || {
213+
if let Err(e) = garbage_collect_session_directories(sess) {
214+
warn!(
215+
"Error while trying to garbage collect incremental \
216+
compilation cache directory: {}",
217+
e
218+
);
219+
}
220+
});
221+
}
222+
223+
Ok(res
224+
.and_then(|result| {
225+
let (prev_graph, prev_work_products) = result.open(sess);
226+
build_dep_graph(sess, prev_graph, prev_work_products)
227+
})
228+
.unwrap_or_else(DepGraph::new_disabled))
229+
}

Diff for: compiler/rustc_incremental/src/persist/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ pub use fs::in_incr_comp_dir;
1616
pub use fs::in_incr_comp_dir_sess;
1717
pub use fs::prepare_session_directory;
1818
pub use load::load_query_result_cache;
19+
pub use load::setup_dep_graph;
1920
pub use load::LoadResult;
20-
pub use load::{load_dep_graph, DepGraphFuture};
21-
pub use save::build_dep_graph;
2221
pub use save::save_dep_graph;
2322
pub use save::save_work_product_index;
2423
pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir;

Diff for: compiler/rustc_incremental/src/persist/save.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
147147
/// execution, the new dependency information is not kept in memory but directly
148148
/// output to this file. `save_dep_graph` then finalizes the staging dep-graph
149149
/// and moves it to the permanent dep-graph path
150-
pub fn build_dep_graph(
150+
pub(crate) fn build_dep_graph(
151151
sess: &Session,
152152
prev_graph: SerializedDepGraph,
153153
prev_work_products: WorkProductMap,

Diff for: compiler/rustc_interface/src/queries.rs

+3-44
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_data_structures::svh::Svh;
1010
use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal};
1111
use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
1212
use rustc_hir::definitions::Definitions;
13-
use rustc_incremental::DepGraphFuture;
13+
use rustc_incremental::setup_dep_graph;
1414
use rustc_metadata::creader::CStore;
1515
use rustc_middle::arena::Arena;
1616
use rustc_middle::dep_graph::DepGraph;
@@ -19,7 +19,6 @@ use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
1919
use rustc_session::cstore::Untracked;
2020
use rustc_session::{output::find_crate_name, Session};
2121
use rustc_span::symbol::sym;
22-
use rustc_span::Symbol;
2322
use std::any::Any;
2423
use std::cell::{RefCell, RefMut};
2524
use std::sync::Arc;
@@ -132,43 +131,6 @@ impl<'tcx> Queries<'tcx> {
132131
})
133132
}
134133

135-
fn dep_graph_future(
136-
&self,
137-
crate_name: Symbol,
138-
stable_crate_id: StableCrateId,
139-
) -> Result<Option<DepGraphFuture>> {
140-
let sess = self.session();
141-
142-
// `load_dep_graph` can only be called after `prepare_session_directory`.
143-
rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
144-
let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
145-
146-
if sess.opts.incremental.is_some() {
147-
sess.time("incr_comp_garbage_collect_session_directories", || {
148-
if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
149-
warn!(
150-
"Error while trying to garbage collect incremental \
151-
compilation cache directory: {}",
152-
e
153-
);
154-
}
155-
});
156-
}
157-
158-
Ok(res)
159-
}
160-
161-
fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
162-
dep_graph_future
163-
.and_then(|future| {
164-
let sess = self.session();
165-
let (prev_graph, prev_work_products) =
166-
sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
167-
rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
168-
})
169-
.unwrap_or_else(DepGraph::new_disabled)
170-
}
171-
172134
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
173135
self.gcx.compute(|| {
174136
let sess = self.session();
@@ -184,10 +146,7 @@ impl<'tcx> Queries<'tcx> {
184146
sess.opts.cg.metadata.clone(),
185147
sess.cfg_version,
186148
);
187-
188-
// Compute the dependency graph (in the background). We want to do this as early as
189-
// possible, to give the DepGraph maximum time to load before `dep_graph` is called.
190-
let dep_graph_future = self.dep_graph_future(crate_name, stable_crate_id)?;
149+
let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
191150

192151
let lint_store = Lrc::new(passes::create_lint_store(
193152
sess,
@@ -210,7 +169,7 @@ impl<'tcx> Queries<'tcx> {
210169
crate_types,
211170
stable_crate_id,
212171
lint_store,
213-
self.dep_graph(dep_graph_future),
172+
dep_graph,
214173
untracked,
215174
&self.gcx_cell,
216175
&self.arena,

0 commit comments

Comments
 (0)