Skip to content

Commit 7b5d801

Browse files
committed
Remove cgu_reuse_tracker from Session
This removes a bit of global mutable state
1 parent 2b9f244 commit 7b5d801

File tree

18 files changed

+284
-279
lines changed

18 files changed

+284
-279
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3496,6 +3496,7 @@ dependencies = [
34963496
"serde_json",
34973497
"smallvec",
34983498
"tempfile",
3499+
"thin-vec",
34993500
"thorin-dwp",
35003501
"tracing",
35013502
"windows",

compiler/rustc_codegen_cranelift/src/driver/aot.rs

+36-32
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::path::PathBuf;
66
use std::sync::Arc;
77
use std::thread::JoinHandle;
88

9+
use rustc_codegen_ssa::assert_module_sources::CguReuse;
910
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
1011
use rustc_codegen_ssa::base::determine_cgu_reuse;
1112
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
@@ -14,7 +15,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1415
use rustc_metadata::EncodedMetadata;
1516
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
1617
use rustc_middle::mir::mono::{CodegenUnit, MonoItem};
17-
use rustc_session::cgu_reuse_tracker::CguReuse;
1818
use rustc_session::config::{DebugInfo, OutputFilenames, OutputType};
1919
use rustc_session::Session;
2020

@@ -376,43 +376,47 @@ pub(crate) fn run_aot(
376376
}
377377
}
378378

379+
// Calculate the CGU reuse
380+
let cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
381+
cgus.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::<Vec<_>>()
382+
});
383+
384+
rustc_codegen_ssa::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| {
385+
for (i, cgu) in cgus.iter().enumerate() {
386+
let cgu_reuse = cgu_reuse[i];
387+
cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse);
388+
}
389+
});
390+
379391
let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx));
380392

381393
let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len());
382394

383395
let modules = tcx.sess.time("codegen mono items", || {
384396
cgus.iter()
385-
.map(|cgu| {
386-
let cgu_reuse = if backend_config.disable_incr_cache {
387-
CguReuse::No
388-
} else {
389-
determine_cgu_reuse(tcx, cgu)
390-
};
391-
tcx.sess.cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse);
392-
393-
match cgu_reuse {
394-
CguReuse::No => {
395-
let dep_node = cgu.codegen_dep_node(tcx);
396-
tcx.dep_graph
397-
.with_task(
398-
dep_node,
399-
tcx,
400-
(
401-
backend_config.clone(),
402-
global_asm_config.clone(),
403-
cgu.name(),
404-
concurrency_limiter.acquire(tcx.sess.diagnostic()),
405-
),
406-
module_codegen,
407-
Some(rustc_middle::dep_graph::hash_result),
408-
)
409-
.0
410-
}
411-
CguReuse::PreLto => unreachable!(),
412-
CguReuse::PostLto => {
413-
concurrency_limiter.job_already_done();
414-
OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))
415-
}
397+
.enumerate()
398+
.map(|(i, cgu)| match cgu_reuse[i] {
399+
CguReuse::No => {
400+
let dep_node = cgu.codegen_dep_node(tcx);
401+
tcx.dep_graph
402+
.with_task(
403+
dep_node,
404+
tcx,
405+
(
406+
backend_config.clone(),
407+
global_asm_config.clone(),
408+
cgu.name(),
409+
concurrency_limiter.acquire(tcx.sess.diagnostic()),
410+
),
411+
module_codegen,
412+
Some(rustc_middle::dep_graph::hash_result),
413+
)
414+
.0
415+
}
416+
CguReuse::PreLto => unreachable!(),
417+
CguReuse::PostLto => {
418+
concurrency_limiter.job_already_done();
419+
OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))
416420
}
417421
})
418422
.collect::<Vec<_>>()

compiler/rustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pathdiff = "0.2.0"
1616
serde_json = "1.0.59"
1717
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
1818
regex = "1.4"
19+
thin-vec = "0.2.12"
1920

2021
rustc_serialize = { path = "../rustc_serialize" }
2122
rustc_arena = { path = "../rustc_arena" }

compiler/rustc_codegen_ssa/messages.ftl

+24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing
1111
1212
codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty
1313
14+
codegen_ssa_cgu_not_recorded =
15+
CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded
16+
1417
codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
1518
1619
codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error}
@@ -41,6 +44,8 @@ codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
4144
4245
codegen_ssa_failed_to_write = failed to write {$path}: {$error}
4346
47+
codegen_ssa_field_associated_value_expected = associated value expected for `{$name}`
48+
4449
codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced
4550
4651
codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced
@@ -50,6 +55,12 @@ codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordina
5055
5156
codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
5257
58+
codegen_ssa_incorrect_cgu_reuse_type =
59+
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
60+
[one] {"at least "}
61+
*[other] {""}
62+
}`{$expected_reuse}`
63+
5364
codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
5465
5566
codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
@@ -157,19 +168,30 @@ codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for
157168
158169
codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}
159170
171+
codegen_ssa_malformed_cgu_name =
172+
found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case).
173+
160174
codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error}
161175
162176
codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload
163177
164178
codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering
165179
180+
codegen_ssa_missing_query_depgraph =
181+
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
182+
166183
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
167184
168185
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
169186
170187
codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
171188
.help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead
172189
190+
codegen_ssa_no_field = no field `{$name}`
191+
192+
codegen_ssa_no_module_named =
193+
no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}
194+
173195
codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
174196
175197
codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
@@ -305,6 +327,8 @@ codegen_ssa_unknown_atomic_operation = unknown atomic operation
305327
306328
codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic
307329
330+
codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified
331+
308332
codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
309333
310334
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target

compiler/rustc_incremental/src/assert_module_sources.rs renamed to compiler/rustc_codegen_ssa/src/assert_module_sources.rs

+143-6
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,22 @@
2525
2626
use crate::errors;
2727
use rustc_ast as ast;
28+
use rustc_data_structures::fx::FxHashMap;
2829
use rustc_data_structures::unord::UnordSet;
30+
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
2931
use rustc_hir::def_id::LOCAL_CRATE;
3032
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
3133
use rustc_middle::ty::TyCtxt;
32-
use rustc_session::cgu_reuse_tracker::*;
33-
use rustc_span::symbol::{sym, Symbol};
34+
use rustc_session::Session;
35+
use rustc_span::symbol::sym;
36+
use rustc_span::{Span, Symbol};
37+
use std::borrow::Cow;
38+
use std::fmt::{self};
39+
use std::sync::{Arc, Mutex};
3440
use thin_vec::ThinVec;
3541

3642
#[allow(missing_docs)]
37-
pub fn assert_module_sources(tcx: TyCtxt<'_>) {
43+
pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&CguReuseTracker)) {
3844
tcx.dep_graph.with_ignore(|| {
3945
if tcx.sess.opts.incremental.is_none() {
4046
return;
@@ -43,17 +49,30 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
4349
let available_cgus =
4450
tcx.collect_and_partition_mono_items(()).1.iter().map(|cgu| cgu.name()).collect();
4551

46-
let ams = AssertModuleSource { tcx, available_cgus };
52+
let ams = AssertModuleSource {
53+
tcx,
54+
available_cgus,
55+
cgu_reuse_tracker: if tcx.sess.opts.unstable_opts.query_dep_graph {
56+
CguReuseTracker::new()
57+
} else {
58+
CguReuseTracker::new_disabled()
59+
},
60+
};
4761

4862
for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) {
4963
ams.check_attr(attr);
5064
}
51-
})
65+
66+
set_reuse(&ams.cgu_reuse_tracker);
67+
68+
ams.cgu_reuse_tracker.check_expected_reuse(tcx.sess);
69+
});
5270
}
5371

5472
struct AssertModuleSource<'tcx> {
5573
tcx: TyCtxt<'tcx>,
5674
available_cgus: UnordSet<Symbol>,
75+
cgu_reuse_tracker: CguReuseTracker,
5776
}
5877

5978
impl<'tcx> AssertModuleSource<'tcx> {
@@ -129,7 +148,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
129148
});
130149
}
131150

132-
self.tcx.sess.cgu_reuse_tracker.set_expectation(
151+
self.cgu_reuse_tracker.set_expectation(
133152
cgu_name,
134153
&user_path,
135154
attr.span,
@@ -169,3 +188,121 @@ impl<'tcx> AssertModuleSource<'tcx> {
169188
false
170189
}
171190
}
191+
192+
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
193+
pub enum CguReuse {
194+
No,
195+
PreLto,
196+
PostLto,
197+
}
198+
199+
impl fmt::Display for CguReuse {
200+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201+
match *self {
202+
CguReuse::No => write!(f, "No"),
203+
CguReuse::PreLto => write!(f, "PreLto "),
204+
CguReuse::PostLto => write!(f, "PostLto "),
205+
}
206+
}
207+
}
208+
209+
impl IntoDiagnosticArg for CguReuse {
210+
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
211+
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
212+
}
213+
}
214+
215+
#[derive(Copy, Clone, Debug, PartialEq)]
216+
pub enum ComparisonKind {
217+
Exact,
218+
AtLeast,
219+
}
220+
221+
struct TrackerData {
222+
actual_reuse: FxHashMap<String, CguReuse>,
223+
expected_reuse: FxHashMap<String, (String, SendSpan, CguReuse, ComparisonKind)>,
224+
}
225+
226+
// Span does not implement `Send`, so we can't just store it in the shared
227+
// `TrackerData` object. Instead of splitting up `TrackerData` into shared and
228+
// non-shared parts (which would be complicated), we just mark the `Span` here
229+
// explicitly as `Send`. That's safe because the span data here is only ever
230+
// accessed from the main thread.
231+
struct SendSpan(Span);
232+
unsafe impl Send for SendSpan {}
233+
234+
#[derive(Clone)]
235+
pub struct CguReuseTracker {
236+
data: Option<Arc<Mutex<TrackerData>>>,
237+
}
238+
239+
impl CguReuseTracker {
240+
pub fn new() -> CguReuseTracker {
241+
let data =
242+
TrackerData { actual_reuse: Default::default(), expected_reuse: Default::default() };
243+
244+
CguReuseTracker { data: Some(Arc::new(Mutex::new(data))) }
245+
}
246+
247+
pub fn new_disabled() -> CguReuseTracker {
248+
CguReuseTracker { data: None }
249+
}
250+
251+
pub fn set_actual_reuse(&self, cgu_name: &str, kind: CguReuse) {
252+
if let Some(ref data) = self.data {
253+
debug!("set_actual_reuse({cgu_name:?}, {kind:?})");
254+
255+
let prev_reuse = data.lock().unwrap().actual_reuse.insert(cgu_name.to_string(), kind);
256+
assert!(prev_reuse.is_none());
257+
}
258+
}
259+
260+
pub fn set_expectation(
261+
&self,
262+
cgu_name: Symbol,
263+
cgu_user_name: &str,
264+
error_span: Span,
265+
expected_reuse: CguReuse,
266+
comparison_kind: ComparisonKind,
267+
) {
268+
if let Some(ref data) = self.data {
269+
debug!("set_expectation({cgu_name:?}, {expected_reuse:?}, {comparison_kind:?})");
270+
let mut data = data.lock().unwrap();
271+
272+
data.expected_reuse.insert(
273+
cgu_name.to_string(),
274+
(cgu_user_name.to_string(), SendSpan(error_span), expected_reuse, comparison_kind),
275+
);
276+
}
277+
}
278+
279+
pub fn check_expected_reuse(&self, sess: &Session) {
280+
if let Some(ref data) = self.data {
281+
let data = data.lock().unwrap();
282+
283+
for (cgu_name, &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind)) in
284+
&data.expected_reuse
285+
{
286+
if let Some(&actual_reuse) = data.actual_reuse.get(cgu_name) {
287+
let (error, at_least) = match comparison_kind {
288+
ComparisonKind::Exact => (expected_reuse != actual_reuse, false),
289+
ComparisonKind::AtLeast => (actual_reuse < expected_reuse, true),
290+
};
291+
292+
if error {
293+
let at_least = if at_least { 1 } else { 0 };
294+
errors::IncorrectCguReuseType {
295+
span: error_span.0,
296+
cgu_user_name,
297+
actual_reuse,
298+
expected_reuse,
299+
at_least,
300+
};
301+
}
302+
} else {
303+
sess.emit_fatal(errors::CguNotRecorded { cgu_user_name, cgu_name });
304+
}
305+
}
306+
}
307+
}
308+
}

compiler/rustc_codegen_ssa/src/back/write.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1958,8 +1958,6 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
19581958
}
19591959
});
19601960

1961-
sess.cgu_reuse_tracker.check_expected_reuse(sess);
1962-
19631961
sess.abort_if_errors();
19641962

19651963
let work_products =

0 commit comments

Comments
 (0)