Skip to content

Commit 31c3f51

Browse files
authored
Rollup merge of rust-lang#77795 - bjorn3:codegen_backend_interface_refactor, r=oli-obk
Codegen backend interface refactor This moves several things away from the codegen backend to rustc_interface. There are a few behavioral changes where previously the incremental cache (incorrectly) wouldn't get finalized, but now it does. See the individual commit messages.
2 parents 858c3b3 + b620e49 commit 31c3f51

File tree

9 files changed

+96
-119
lines changed

9 files changed

+96
-119
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+2-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_codegen_ssa::traits::*;
66
use rustc_data_structures::const_cstr;
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_data_structures::small_c_str::SmallCStr;
9-
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
9+
use rustc_hir::def_id::DefId;
1010
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1111
use rustc_middle::ty::layout::HasTyCtxt;
1212
use rustc_middle::ty::query::Providers;
@@ -352,23 +352,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
352352
}
353353
}
354354

355-
pub fn provide(providers: &mut Providers) {
356-
use rustc_codegen_ssa::target_features::{all_known_features, supported_target_features};
357-
providers.supported_target_features = |tcx, cnum| {
358-
assert_eq!(cnum, LOCAL_CRATE);
359-
if tcx.sess.opts.actually_rustdoc {
360-
// rustdoc needs to be able to document functions that use all the features, so
361-
// provide them all.
362-
all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
363-
} else {
364-
supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect()
365-
}
366-
};
367-
368-
provide_extern(providers);
369-
}
370-
371-
pub fn provide_extern(providers: &mut Providers) {
355+
pub fn provide_both(providers: &mut Providers) {
372356
providers.wasm_import_module_map = |tcx, cnum| {
373357
// Build up a map from DefId to a `NativeLib` structure, where
374358
// `NativeLib` internally contains information about

compiler/rustc_codegen_llvm/src/lib.rs

+12-43
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,17 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
2323
use rustc_codegen_ssa::traits::*;
2424
use rustc_codegen_ssa::ModuleCodegen;
2525
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
26+
use rustc_data_structures::fx::FxHashMap;
2627
use rustc_errors::{ErrorReported, FatalError, Handler};
27-
use rustc_middle::dep_graph::{DepGraph, WorkProduct};
28+
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
2829
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
2930
use rustc_middle::ty::{self, TyCtxt};
30-
use rustc_serialize::json;
31-
use rustc_session::config::{self, OptLevel, OutputFilenames, PrintRequest};
31+
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
3232
use rustc_session::Session;
3333
use rustc_span::symbol::Symbol;
3434

3535
use std::any::Any;
3636
use std::ffi::CStr;
37-
use std::fs;
3837
use std::sync::Arc;
3938

4039
mod back {
@@ -249,11 +248,11 @@ impl CodegenBackend for LlvmCodegenBackend {
249248
}
250249

251250
fn provide(&self, providers: &mut ty::query::Providers) {
252-
attributes::provide(providers);
251+
attributes::provide_both(providers);
253252
}
254253

255254
fn provide_extern(&self, providers: &mut ty::query::Providers) {
256-
attributes::provide_extern(providers);
255+
attributes::provide_both(providers);
257256
}
258257

259258
fn codegen_crate<'tcx>(
@@ -274,47 +273,27 @@ impl CodegenBackend for LlvmCodegenBackend {
274273
&self,
275274
ongoing_codegen: Box<dyn Any>,
276275
sess: &Session,
277-
dep_graph: &DepGraph,
278-
) -> Result<Box<dyn Any>, ErrorReported> {
276+
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
279277
let (codegen_results, work_products) = ongoing_codegen
280278
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>()
281279
.expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>")
282280
.join(sess);
283-
if sess.opts.debugging_opts.incremental_info {
284-
rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results);
285-
}
286281

287-
sess.time("serialize_work_products", move || {
288-
rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)
282+
sess.time("llvm_dump_timing_file", || {
283+
if sess.opts.debugging_opts.llvm_time_trace {
284+
llvm_util::time_trace_profiler_finish("llvm_timings.json");
285+
}
289286
});
290287

291-
sess.compile_status()?;
292-
293-
Ok(Box::new(codegen_results))
288+
Ok((codegen_results, work_products))
294289
}
295290

296291
fn link(
297292
&self,
298293
sess: &Session,
299-
codegen_results: Box<dyn Any>,
294+
codegen_results: CodegenResults,
300295
outputs: &OutputFilenames,
301296
) -> Result<(), ErrorReported> {
302-
let codegen_results = codegen_results
303-
.downcast::<CodegenResults>()
304-
.expect("Expected CodegenResults, found Box<Any>");
305-
306-
if sess.opts.debugging_opts.no_link {
307-
// FIXME: use a binary format to encode the `.rlink` file
308-
let rlink_data = json::encode(&codegen_results).map_err(|err| {
309-
sess.fatal(&format!("failed to encode rlink: {}", err));
310-
})?;
311-
let rlink_file = outputs.with_extension(config::RLINK_EXT);
312-
fs::write(&rlink_file, rlink_data).map_err(|err| {
313-
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
314-
})?;
315-
return Ok(());
316-
}
317-
318297
// Run the linker on any artifacts that resulted from the LLVM run.
319298
// This should produce either a finished executable or library.
320299
sess.time("link_crate", || {
@@ -331,16 +310,6 @@ impl CodegenBackend for LlvmCodegenBackend {
331310
);
332311
});
333312

334-
// Now that we won't touch anything in the incremental compilation directory
335-
// any more, we can finalize it (which involves renaming it)
336-
rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash);
337-
338-
sess.time("llvm_dump_timing_file", || {
339-
if sess.opts.debugging_opts.llvm_time_trace {
340-
llvm_util::time_trace_profiler_finish("llvm_timings.json");
341-
}
342-
});
343-
344313
Ok(())
345314
}
346315
}

compiler/rustc_codegen_ssa/src/back/write.rs

-14
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap;
1313
use rustc_data_structures::profiling::SelfProfilerRef;
1414
use rustc_data_structures::profiling::TimingGuard;
1515
use rustc_data_structures::profiling::VerboseTimingGuard;
16-
use rustc_data_structures::svh::Svh;
1716
use rustc_data_structures::sync::Lrc;
1817
use rustc_errors::emitter::Emitter;
1918
use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
@@ -414,7 +413,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
414413
let sess = tcx.sess;
415414

416415
let crate_name = tcx.crate_name(LOCAL_CRATE);
417-
let crate_hash = tcx.crate_hash(LOCAL_CRATE);
418416
let no_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins);
419417
let is_compiler_builtins =
420418
tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins);
@@ -463,7 +461,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
463461
OngoingCodegen {
464462
backend,
465463
crate_name,
466-
crate_hash,
467464
metadata,
468465
windows_subsystem,
469466
linker_info,
@@ -658,15 +655,6 @@ fn produce_final_output_artifacts(
658655
// These are used in linking steps and will be cleaned up afterward.
659656
}
660657

661-
pub fn dump_incremental_data(_codegen_results: &CodegenResults) {
662-
// FIXME(mw): This does not work at the moment because the situation has
663-
// become more complicated due to incremental LTO. Now a CGU
664-
// can have more than two caching states.
665-
// println!("[incremental] Re-using {} out of {} modules",
666-
// codegen_results.modules.iter().filter(|m| m.pre_existing).count(),
667-
// codegen_results.modules.len());
668-
}
669-
670658
pub enum WorkItem<B: WriteBackendMethods> {
671659
/// Optimize a newly codegened, totally unoptimized module.
672660
Optimize(ModuleCodegen<B::Module>),
@@ -1720,7 +1708,6 @@ impl SharedEmitterMain {
17201708
pub struct OngoingCodegen<B: ExtraBackendMethods> {
17211709
pub backend: B,
17221710
pub crate_name: Symbol,
1723-
pub crate_hash: Svh,
17241711
pub metadata: EncodedMetadata,
17251712
pub windows_subsystem: Option<String>,
17261713
pub linker_info: LinkerInfo,
@@ -1766,7 +1753,6 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
17661753
(
17671754
CodegenResults {
17681755
crate_name: self.crate_name,
1769-
crate_hash: self.crate_hash,
17701756
metadata: self.metadata,
17711757
windows_subsystem: self.windows_subsystem,
17721758
linker_info: self.linker_info,

compiler/rustc_codegen_ssa/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ extern crate tracing;
2121
extern crate rustc_middle;
2222

2323
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
24-
use rustc_data_structures::svh::Svh;
2524
use rustc_data_structures::sync::Lrc;
2625
use rustc_hir::def_id::CrateNum;
2726
use rustc_hir::LangItem;
@@ -134,7 +133,6 @@ pub struct CodegenResults {
134133
pub modules: Vec<CompiledModule>,
135134
pub allocator_module: Option<CompiledModule>,
136135
pub metadata_module: Option<CompiledModule>,
137-
pub crate_hash: Svh,
138136
pub metadata: rustc_middle::middle::cstore::EncodedMetadata,
139137
pub windows_subsystem: Option<String>,
140138
pub linker_info: back::linker::LinkerInfo,
@@ -144,6 +142,7 @@ pub struct CodegenResults {
144142
pub fn provide(providers: &mut Providers) {
145143
crate::back::symbol_export::provide(providers);
146144
crate::base::provide_both(providers);
145+
crate::target_features::provide(providers);
147146
}
148147

149148
pub fn provide_extern(providers: &mut Providers) {

compiler/rustc_codegen_ssa/src/target_features.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use rustc_hir::def_id::LOCAL_CRATE;
2+
use rustc_middle::ty::query::Providers;
13
use rustc_session::Session;
24
use rustc_span::symbol::sym;
35
use rustc_span::symbol::Symbol;
@@ -148,3 +150,16 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
148150
_ => &[],
149151
}
150152
}
153+
154+
pub(crate) fn provide(providers: &mut Providers) {
155+
providers.supported_target_features = |tcx, cnum| {
156+
assert_eq!(cnum, LOCAL_CRATE);
157+
if tcx.sess.opts.actually_rustdoc {
158+
// rustdoc needs to be able to document functions that use all the features, so
159+
// whitelist them all
160+
all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
161+
} else {
162+
supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect()
163+
}
164+
};
165+
}

compiler/rustc_codegen_ssa/src/traits/backend.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use super::write::WriteBackendMethods;
22
use super::CodegenObject;
3-
use crate::ModuleCodegen;
3+
use crate::{CodegenResults, ModuleCodegen};
44

55
use rustc_ast::expand::allocator::AllocatorKind;
6+
use rustc_data_structures::fx::FxHashMap;
67
use rustc_errors::ErrorReported;
7-
use rustc_middle::dep_graph::DepGraph;
8+
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
89
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
910
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
1011
use rustc_middle::ty::query::Providers;
@@ -80,8 +81,7 @@ pub trait CodegenBackend {
8081
&self,
8182
ongoing_codegen: Box<dyn Any>,
8283
sess: &Session,
83-
dep_graph: &DepGraph,
84-
) -> Result<Box<dyn Any>, ErrorReported>;
84+
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported>;
8585

8686
/// This is called on the returned `Box<dyn Any>` from `join_codegen`
8787
///
@@ -91,7 +91,7 @@ pub trait CodegenBackend {
9191
fn link(
9292
&self,
9393
sess: &Session,
94-
codegen_results: Box<dyn Any>,
94+
codegen_results: CodegenResults,
9595
outputs: &OutputFilenames,
9696
) -> Result<(), ErrorReported>;
9797
}

compiler/rustc_driver/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ impl RustcDefaultCalls {
642642
let codegen_results: CodegenResults = json::decode(&rlink_data).unwrap_or_else(|err| {
643643
sess.fatal(&format!("failed to decode rlink: {}", err));
644644
});
645-
compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs)
645+
compiler.codegen_backend().link(&sess, codegen_results, &outputs)
646646
} else {
647647
sess.fatal("rlink must be a file")
648648
}

compiler/rustc_interface/src/queries.rs

+34-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::passes::{self, BoxedResolver, QueryContext};
33

44
use rustc_ast as ast;
55
use rustc_codegen_ssa::traits::CodegenBackend;
6+
use rustc_data_structures::svh::Svh;
67
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
78
use rustc_errors::ErrorReported;
89
use rustc_hir::def_id::LOCAL_CRATE;
@@ -13,7 +14,8 @@ use rustc_middle::arena::Arena;
1314
use rustc_middle::dep_graph::DepGraph;
1415
use rustc_middle::ty::steal::Steal;
1516
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
16-
use rustc_session::config::{OutputFilenames, OutputType};
17+
use rustc_serialize::json;
18+
use rustc_session::config::{self, OutputFilenames, OutputType};
1719
use rustc_session::{output::find_crate_name, Session};
1820
use rustc_span::symbol::sym;
1921
use std::any::Any;
@@ -331,6 +333,7 @@ impl<'tcx> Queries<'tcx> {
331333
pub fn linker(&'tcx self) -> Result<Linker> {
332334
let dep_graph = self.dep_graph()?;
333335
let prepare_outputs = self.prepare_outputs()?;
336+
let crate_hash = self.global_ctxt()?.peek_mut().enter(|tcx| tcx.crate_hash(LOCAL_CRATE));
334337
let ongoing_codegen = self.ongoing_codegen()?;
335338

336339
let sess = self.session().clone();
@@ -340,6 +343,7 @@ impl<'tcx> Queries<'tcx> {
340343
sess,
341344
dep_graph: dep_graph.peek().clone(),
342345
prepare_outputs: prepare_outputs.take(),
346+
crate_hash,
343347
ongoing_codegen: ongoing_codegen.take(),
344348
codegen_backend,
345349
})
@@ -350,18 +354,31 @@ pub struct Linker {
350354
sess: Lrc<Session>,
351355
dep_graph: DepGraph,
352356
prepare_outputs: OutputFilenames,
357+
crate_hash: Svh,
353358
ongoing_codegen: Box<dyn Any>,
354359
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
355360
}
356361

357362
impl Linker {
358363
pub fn link(self) -> Result<()> {
359-
let codegen_results =
360-
self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess, &self.dep_graph)?;
361-
let prof = self.sess.prof.clone();
364+
let (codegen_results, work_products) =
365+
self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess)?;
366+
367+
self.sess.compile_status()?;
368+
369+
let sess = &self.sess;
362370
let dep_graph = self.dep_graph;
371+
sess.time("serialize_work_products", || {
372+
rustc_incremental::save_work_product_index(&sess, &dep_graph, work_products)
373+
});
374+
375+
let prof = self.sess.prof.clone();
363376
prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph));
364377

378+
// Now that we won't touch anything in the incremental compilation directory
379+
// any more, we can finalize it (which involves renaming it)
380+
rustc_incremental::finalize_session_directory(&self.sess, self.crate_hash);
381+
365382
if !self
366383
.sess
367384
.opts
@@ -371,6 +388,19 @@ impl Linker {
371388
{
372389
return Ok(());
373390
}
391+
392+
if sess.opts.debugging_opts.no_link {
393+
// FIXME: use a binary format to encode the `.rlink` file
394+
let rlink_data = json::encode(&codegen_results).map_err(|err| {
395+
sess.fatal(&format!("failed to encode rlink: {}", err));
396+
})?;
397+
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
398+
std::fs::write(&rlink_file, rlink_data).map_err(|err| {
399+
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
400+
})?;
401+
return Ok(());
402+
}
403+
374404
self.codegen_backend.link(&self.sess, codegen_results, &self.prepare_outputs)
375405
}
376406
}

0 commit comments

Comments
 (0)