Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 360ee87

Browse files
committedSep 9, 2023
Load the dep graph before parsing
1 parent b0b8c52 commit 360ee87

File tree

2 files changed

+71
-43
lines changed

2 files changed

+71
-43
lines changed
 

‎compiler/rustc_incremental/src/persist/fs.rs

+35-9
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,18 @@
105105
106106
use crate::errors;
107107
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
108+
use rustc_data_structures::stable_hasher::{Hash64, StableHasher};
108109
use rustc_data_structures::svh::Svh;
109110
use rustc_data_structures::unord::{UnordMap, UnordSet};
110111
use rustc_data_structures::{base_n, flock};
111112
use rustc_errors::ErrorGuaranteed;
112113
use rustc_fs_util::{link_or_copy, try_canonicalize, LinkOrCopy};
114+
use rustc_session::config::{CrateType, Input};
113115
use rustc_session::{Session, StableCrateId};
114-
use rustc_span::Symbol;
116+
use rustc_span::symbol;
115117

116118
use std::fs as std_fs;
119+
use std::hash::Hash;
117120
use std::io::{self, ErrorKind};
118121
use std::path::{Path, PathBuf};
119122
use std::time::{Duration, SystemTime, UNIX_EPOCH};
@@ -202,11 +205,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
202205
/// The garbage collection will take care of it.
203206
///
204207
/// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph
205-
pub fn prepare_session_directory(
206-
sess: &Session,
207-
crate_name: Symbol,
208-
stable_crate_id: StableCrateId,
209-
) -> Result<(), ErrorGuaranteed> {
208+
pub fn prepare_session_directory(sess: &Session) -> Result<(), ErrorGuaranteed> {
210209
if sess.opts.incremental.is_none() {
211210
return Ok(());
212211
}
@@ -216,7 +215,7 @@ pub fn prepare_session_directory(
216215
debug!("prepare_session_directory");
217216

218217
// {incr-comp-dir}/{crate-name-and-disambiguator}
219-
let crate_dir = crate_path(sess, crate_name, stable_crate_id);
218+
let crate_dir = crate_path(sess);
220219
debug!("crate-dir: {}", crate_dir.display());
221220
create_dir(sess, &crate_dir, "crate")?;
222221

@@ -601,12 +600,39 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
601600
Ok(UNIX_EPOCH + duration)
602601
}
603602

604-
fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf {
603+
fn crate_path(sess: &Session) -> PathBuf {
604+
// Use the crate name from the command line if available and valid
605+
let crate_name = sess.opts.crate_name.as_ref().and_then(|name| {
606+
name.as_str().chars().all(|c| c.is_alphanumeric() || c == '_').then_some(&name[..])
607+
});
608+
609+
// Create a hash for metadata and the rust version
610+
let metadata_and_version = StableCrateId::new(
611+
symbol::kw::Empty,
612+
// JUSTIFICATION: before wrapper fn is available
613+
#[allow(rustc::bad_opt_access)]
614+
sess.opts.crate_types.contains(&CrateType::Executable),
615+
sess.opts.cg.metadata.clone(),
616+
sess.cfg_version,
617+
);
618+
619+
// Find a file path to differentiate crates if crate name is missing
620+
let canonical_file_path = crate_name.is_none().then(|| match &sess.io.input {
621+
Input::File(file) => try_canonicalize(file).ok(),
622+
Input::Str { .. } => None,
623+
});
624+
625+
let mut hasher = StableHasher::new();
626+
crate_name.hash(&mut hasher);
627+
metadata_and_version.hash(&mut hasher);
628+
canonical_file_path.hash(&mut hasher);
629+
let stable_crate_id: Hash64 = hasher.finish();
630+
605631
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
606632

607633
let stable_crate_id = base_n::encode(stable_crate_id.as_u64() as u128, INT_ENCODE_BASE);
608634

609-
let crate_name = format!("{crate_name}-{stable_crate_id}");
635+
let crate_name = format!("{}-{stable_crate_id}", crate_name.unwrap_or("unknown.crate"));
610636
incr_dir.join(crate_name)
611637
}
612638

‎compiler/rustc_interface/src/queries.rs

+36-34
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
2121
use rustc_session::cstore::Untracked;
2222
use rustc_session::{output::find_crate_name, Session};
2323
use rustc_span::symbol::sym;
24-
use rustc_span::Symbol;
2524
use std::any::Any;
2625
use std::cell::{RefCell, RefMut};
2726
use std::sync::Arc;
@@ -85,6 +84,7 @@ pub struct Queries<'tcx> {
8584
arena: WorkerLocal<Arena<'tcx>>,
8685
hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>,
8786

87+
dep_graph_future: Query<Option<DepGraphFuture>>,
8888
parse: Query<ast::Crate>,
8989
pre_configure: Query<(ast::Crate, ast::AttrVec)>,
9090
// This just points to what's in `gcx_cell`.
@@ -98,6 +98,7 @@ impl<'tcx> Queries<'tcx> {
9898
gcx_cell: OnceLock::new(),
9999
arena: WorkerLocal::new(|_| Arena::default()),
100100
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
101+
dep_graph_future: Default::default(),
101102
parse: Default::default(),
102103
pre_configure: Default::default(),
103104
gcx: Default::default(),
@@ -112,8 +113,13 @@ impl<'tcx> Queries<'tcx> {
112113
}
113114

114115
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
115-
self.parse
116-
.compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit()))
116+
self.parse.compute(|| {
117+
// Compute the dependency graph (in the background). We want to do this as early as
118+
// possible, to give the DepGraph maximum time to load before `dep_graph` is called.
119+
self.dep_graph_future()?;
120+
121+
passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit())
122+
})
117123
}
118124

119125
pub fn pre_configure(&self) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec)>> {
@@ -133,41 +139,41 @@ impl<'tcx> Queries<'tcx> {
133139
})
134140
}
135141

136-
fn dep_graph_future(
137-
&self,
138-
crate_name: Symbol,
139-
stable_crate_id: StableCrateId,
140-
) -> Result<Option<DepGraphFuture>> {
141-
let sess = self.session();
142-
143-
// `load_dep_graph` can only be called after `prepare_session_directory`.
144-
rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
145-
let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
146-
147-
if sess.opts.incremental.is_some() {
148-
sess.time("incr_comp_garbage_collect_session_directories", || {
149-
if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
150-
warn!(
151-
"Error while trying to garbage collect incremental \
152-
compilation cache directory: {}",
153-
e
154-
);
155-
}
156-
});
157-
}
142+
fn dep_graph_future(&self) -> Result<QueryResult<'_, Option<DepGraphFuture>>> {
143+
self.dep_graph_future.compute(|| {
144+
let sess = self.session();
145+
146+
// `load_dep_graph` can only be called after `prepare_session_directory`.
147+
rustc_incremental::prepare_session_directory(sess)?;
148+
let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
149+
150+
if sess.opts.incremental.is_some() {
151+
sess.time("incr_comp_garbage_collect_session_directories", || {
152+
if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
153+
warn!(
154+
"Error while trying to garbage collect incremental \
155+
compilation cache directory: {}",
156+
e
157+
);
158+
}
159+
});
160+
}
158161

159-
Ok(res)
162+
Ok(res)
163+
})
160164
}
161165

162-
fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
163-
dep_graph_future
166+
fn dep_graph(&self) -> Result<DepGraph> {
167+
Ok(self
168+
.dep_graph_future()?
169+
.steal()
164170
.and_then(|future| {
165171
let sess = self.session();
166172
let (prev_graph, prev_work_products) =
167173
sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
168174
rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
169175
})
170-
.unwrap_or_else(DepGraph::new_disabled)
176+
.unwrap_or_else(DepGraph::new_disabled))
171177
}
172178

173179
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
@@ -185,10 +191,6 @@ impl<'tcx> Queries<'tcx> {
185191
sess.cfg_version,
186192
);
187193

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)?;
191-
192194
let lint_store = Lrc::new(passes::create_lint_store(
193195
sess,
194196
&*self.codegen_backend().metadata_loader(),
@@ -210,7 +212,7 @@ impl<'tcx> Queries<'tcx> {
210212
crate_types,
211213
stable_crate_id,
212214
lint_store,
213-
self.dep_graph(dep_graph_future),
215+
self.dep_graph()?,
214216
untracked,
215217
&self.gcx_cell,
216218
&self.arena,

0 commit comments

Comments
 (0)
Please sign in to comment.