Skip to content

Commit c8158e7

Browse files
committed
Make ongoing_codegen a query
1 parent 075809d commit c8158e7

File tree

10 files changed

+80
-62
lines changed

10 files changed

+80
-62
lines changed

src/librustc/query/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ rustc_queries! {
101101
desc { "running analysis passes on this crate" }
102102
}
103103

104+
query ongoing_codegen(_: CrateNum) -> Result<Lrc<ty::OngoingCodegen>, ErrorReported> {
105+
no_hash
106+
eval_always
107+
desc { "starting code generation" }
108+
}
109+
104110
/// Records the type of every item.
105111
query type_of(key: DefId) -> Ty<'tcx> {
106112
cache { key.is_local() }

src/librustc/ty/context.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5252
StableVec};
5353
use arena::{TypedArena, SyncDroplessArena};
5454
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
55-
use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal, AtomicOnce, Once};
55+
use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal, AtomicOnce, Once, OneThread};
5656
use std::any::Any;
5757
use std::borrow::Borrow;
5858
use std::cmp::Ordering;
@@ -1029,6 +1029,9 @@ pub struct GlobalCtxt<'tcx> {
10291029

10301030
pub sess_rc: Lrc<Session>,
10311031

1032+
// This stores a `Arc<dyn CodegenBackend + Send + Sync>`.
1033+
pub codegen_backend: Box<dyn Any + Send + Sync>,
1034+
10321035
lowered_hir: AtomicOnce<&'tcx hir::LoweredHir>,
10331036
hir_map: AtomicOnce<&'tcx hir_map::Map<'tcx>>,
10341037

@@ -1071,6 +1074,7 @@ pub struct GlobalCtxt<'tcx> {
10711074
/// when satisfying the query for a particular codegen unit. Internally in
10721075
/// the query it'll send data along this channel to get processed later.
10731076
pub tx_to_llvm_workers: Lock<mpsc::Sender<Box<dyn Any + Send>>>,
1077+
pub rx_to_llvm_workers: Steal<OneThread<mpsc::Receiver<Box<dyn Any + Send>>>>,
10741078
}
10751079

10761080
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
@@ -1224,7 +1228,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12241228
extern_providers: ty::query::Providers<'tcx>,
12251229
arenas: &'tcx AllArenas<'tcx>,
12261230
crate_name: Option<String>,
1227-
tx: mpsc::Sender<Box<dyn Any + Send>>,
1231+
codegen_backend: Box<dyn Any + Send + Sync>,
12281232
io: InputsAndOutputs,
12291233
) -> GlobalCtxt<'tcx> {
12301234
let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| {
@@ -1235,12 +1239,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12351239
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
12361240
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
12371241
providers[LOCAL_CRATE] = local_providers;
1242+
let (tx, rx) = mpsc::channel();
12381243

12391244
GlobalCtxt {
12401245
sess: &**s,
12411246
cstore,
12421247
cstore_rc,
12431248
sess_rc: s.clone(),
1249+
codegen_backend,
12441250
global_arenas: &arenas.global,
12451251
global_interners: interners,
12461252
dep_graph: AtomicOnce::new(),
@@ -1264,6 +1270,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12641270
allocation_interner: Default::default(),
12651271
alloc_map: Lock::new(interpret::AllocMap::new()),
12661272
tx_to_llvm_workers: Lock::new(tx),
1273+
rx_to_llvm_workers: Steal::new(OneThread::new(rx)),
12671274
io,
12681275
}
12691276
}

src/librustc/ty/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ use crate::mir::Mir;
2121
use crate::mir::interpret::{GlobalId, ErrorHandled};
2222
use crate::mir::GeneratorLayout;
2323
use crate::session::CrateDisambiguator;
24+
use crate::session::config::OutputFilenames;
25+
use crate::dep_graph::DepGraph;
2426
use crate::traits::{self, Reveal};
2527
use crate::ty;
2628
use crate::ty::layout::VariantIdx;
2729
use crate::ty::subst::{Subst, InternalSubsts, SubstsRef};
2830
use crate::ty::util::{IntTypeExt, Discr};
2931
use crate::ty::walk::TypeWalker;
32+
use crate::ty::steal::Steal;
3033
use crate::util::captures::Captures;
3134
use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap};
3235
use arena::SyncDroplessArena;
@@ -39,6 +42,7 @@ use std::fmt;
3942
use std::hash::{Hash, Hasher};
4043
use std::ops::Deref;
4144
use std::any::Any;
45+
use std::sync::Arc;
4246
use rustc_data_structures::sync::{self, Lrc, OneThread, ParallelIterator, par_iter};
4347
use std::slice;
4448
use std::{mem, ptr};
@@ -120,6 +124,12 @@ mod sty;
120124

121125
// Data types
122126

127+
pub struct OngoingCodegen {
128+
pub outputs: Arc<OutputFilenames>,
129+
pub dep_graph: DepGraph,
130+
pub codegen_object: Steal<OneThread<Box<dyn Any>>>,
131+
}
132+
123133
pub struct PluginInfo {
124134
pub syntax_exts: Vec<NamedSyntaxExtension>,
125135
pub attributes: Vec<(String, AttributeType)>,

src/librustc_codegen_llvm/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ unsafe impl Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
222222
unsafe impl Sync for LlvmCodegenBackend {}
223223

224224
impl LlvmCodegenBackend {
225-
pub fn new() -> Box<dyn CodegenBackend> {
226-
box LlvmCodegenBackend(())
225+
pub fn new() -> Arc<dyn CodegenBackend + Send + Sync> {
226+
Arc::new(LlvmCodegenBackend(()))
227227
}
228228
}
229229

@@ -347,7 +347,7 @@ impl CodegenBackend for LlvmCodegenBackend {
347347

348348
/// This is the entrypoint for a hot plugged rustc_codegen_llvm
349349
#[no_mangle]
350-
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
350+
pub fn __rustc_codegen_backend() -> Arc<dyn CodegenBackend + Send + Sync> {
351351
LlvmCodegenBackend::new()
352352
}
353353

src/librustc_driver/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ pub fn run_compiler(
177177
return;
178178
}
179179
let should_stop = RustcDefaultCalls::print_crate_info(
180-
&***compiler.codegen_backend(),
180+
&**compiler.codegen_backend(),
181181
compiler.session(),
182182
None,
183183
&odir,
@@ -231,7 +231,7 @@ pub fn run_compiler(
231231
interface::run_compiler(config, |compiler| {
232232
let sess = compiler.session();
233233
let should_stop = RustcDefaultCalls::print_crate_info(
234-
&***compiler.codegen_backend(),
234+
&**compiler.codegen_backend(),
235235
sess,
236236
Some(compiler.input()),
237237
compiler.output_dir(),

src/librustc_interface/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub type Result<T> = result::Result<T, ErrorReported>;
2727
/// Created by passing `Config` to `run_compiler`.
2828
pub struct Compiler {
2929
pub(crate) sess: Lrc<Session>,
30-
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
30+
codegen_backend: Arc<dyn CodegenBackend + Send + Sync>,
3131
source_map: Lrc<SourceMap>,
3232
pub(crate) io: InputsAndOutputs,
3333
pub(crate) queries: Queries,
@@ -39,7 +39,7 @@ impl Compiler {
3939
pub fn session(&self) -> &Lrc<Session> {
4040
&self.sess
4141
}
42-
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
42+
pub fn codegen_backend(&self) -> &Arc<dyn CodegenBackend + Send + Sync> {
4343
&self.codegen_backend
4444
}
4545
pub fn cstore(&self) -> &Lrc<CStore> {

src/librustc_interface/passes.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ fn load_query_result_cache<'tcx>(
911911
}
912912

913913
pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
914+
providers.ongoing_codegen = ongoing_codegen;
914915
providers.analysis = analysis;
915916
providers.hir_map = hir_map;
916917
providers.lower_ast_to_hir = lower_ast_to_hir;
@@ -968,7 +969,6 @@ impl BoxedGlobalCtxt {
968969
pub fn create_global_ctxt(
969970
compiler: &Compiler,
970971
io: InputsAndOutputs,
971-
tx: mpsc::Sender<Box<dyn Any + Send>>,
972972
) -> BoxedGlobalCtxt {
973973
let sess = compiler.session().clone();
974974
let cstore = compiler.cstore.clone();
@@ -990,6 +990,13 @@ pub fn create_global_ctxt(
990990
default_provide_extern(&mut extern_providers);
991991
codegen_backend.provide_extern(&mut extern_providers);
992992

993+
// Move the dyn Any coercion outside the generator to avoid lifetime issues
994+
fn codegen_backend_any(
995+
i: Arc<dyn CodegenBackend + Send + Sync>
996+
) -> Box<dyn Any + Send + Sync> {
997+
Box::new(i)
998+
}
999+
9931000
let gcx = TyCtxt::create_global_ctxt(
9941001
sess,
9951002
&**cstore,
@@ -998,7 +1005,7 @@ pub fn create_global_ctxt(
9981005
extern_providers,
9991006
&arenas,
10001007
crate_name,
1001-
tx,
1008+
codegen_backend_any(codegen_backend.clone()),
10021009
io,
10031010
);
10041011

@@ -1164,12 +1171,23 @@ fn analysis<'tcx>(
11641171

11651172
/// Runs the codegen backend, after which the AST and analysis can
11661173
/// be discarded.
1167-
pub fn start_codegen<'tcx>(
1168-
codegen_backend: &dyn CodegenBackend,
1174+
fn ongoing_codegen<'tcx>(
11691175
tcx: TyCtxt<'_, 'tcx, 'tcx>,
1170-
rx: mpsc::Receiver<Box<dyn Any + Send>>,
1171-
outputs: &OutputFilenames,
1172-
) -> Box<dyn Any> {
1176+
cnum: CrateNum,
1177+
) -> Result<Lrc<ty::OngoingCodegen>> {
1178+
tcx.analysis(cnum)?;
1179+
1180+
assert_eq!(cnum, LOCAL_CRATE);
1181+
// Don't do code generation if there were any errors
1182+
tcx.sess.compile_status()?;
1183+
1184+
let outputs = tcx.prepare_outputs(LocalCrate)?;
1185+
1186+
let rx = OneThread::into_inner(tcx.rx_to_llvm_workers.steal());
1187+
let codegen_backend: &dyn Any = &*tcx.codegen_backend;
1188+
let codegen_backend = codegen_backend.downcast_ref::<Arc<dyn CodegenBackend + Send + Sync>>()
1189+
.unwrap();
1190+
11731191
if log_enabled!(::log::Level::Info) {
11741192
println!("Pre-codegen");
11751193
tcx.print_debug_stats();
@@ -1189,11 +1207,15 @@ pub fn start_codegen<'tcx>(
11891207
}
11901208

11911209
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
1192-
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, outputs) {
1210+
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, &outputs) {
11931211
tcx.sess.err(&format!("could not emit MIR: {}", e));
11941212
tcx.sess.abort_if_errors();
11951213
}
11961214
}
11971215

1198-
codegen
1216+
Ok(Lrc::new(ty::OngoingCodegen {
1217+
outputs,
1218+
dep_graph: tcx.dep_graph().clone(),
1219+
codegen_object: Steal::new(OneThread::new(codegen)),
1220+
}))
11991221
}

src/librustc_interface/queries.rs

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::interface::{Compiler, Result};
22
use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt};
33

4-
use rustc_data_structures::sync::{Lrc, Lock};
4+
use rustc_data_structures::sync::{Lrc, Lock, OneThread};
55
use rustc::session::config::{Input, OutputFilenames, OutputType};
66
use rustc::session::Session;
77
use rustc::util::common::{time, ErrorReported};
@@ -83,67 +83,40 @@ impl<T> Default for Query<T> {
8383

8484
#[derive(Default)]
8585
pub(crate) struct Queries {
86-
codegen_channel: Query<(Steal<mpsc::Sender<Box<dyn Any + Send>>>,
87-
Steal<mpsc::Receiver<Box<dyn Any + Send>>>)>,
8886
global_ctxt: Query<BoxedGlobalCtxt>,
89-
ongoing_codegen: Query<(Box<dyn Any>, Arc<OutputFilenames>, DepGraph)>,
87+
ongoing_codegen: Query<Lrc<ty::OngoingCodegen>>,
9088
link: Query<()>,
9189
}
9290

9391
impl Compiler {
94-
pub fn codegen_channel(&self) -> Result<&Query<(Steal<mpsc::Sender<Box<dyn Any + Send>>>,
95-
Steal<mpsc::Receiver<Box<dyn Any + Send>>>)>> {
96-
self.queries.codegen_channel.compute(|| {
97-
let (tx, rx) = mpsc::channel();
98-
Ok((Steal::new(tx), Steal::new(rx)))
99-
})
100-
}
101-
10292
pub fn global_ctxt(&self) -> Result<&Query<BoxedGlobalCtxt>> {
10393
self.queries.global_ctxt.compute(|| {
104-
let tx = self.codegen_channel()?.peek().0.steal();
10594
Ok(passes::create_global_ctxt(
10695
self,
10796
self.io.clone(),
108-
tx
10997
))
11098
})
11199
}
112100

113101
pub fn ongoing_codegen(
114102
&self
115-
) -> Result<&Query<(Box<dyn Any>, Arc<OutputFilenames>, DepGraph)>> {
103+
) -> Result<&Query<Lrc<ty::OngoingCodegen>>> {
116104
self.queries.ongoing_codegen.compute(|| {
117-
let rx = self.codegen_channel()?.peek().1.steal();
118105
self.global_ctxt()?.peek_mut().enter(|tcx| {
119-
tcx.analysis(LOCAL_CRATE).ok();
120-
121-
// Don't do code generation if there were any errors
122-
self.session().compile_status()?;
123-
124-
let outputs = tcx.prepare_outputs(LocalCrate)?;
125-
126-
Ok((passes::start_codegen(
127-
&***self.codegen_backend(),
128-
tcx,
129-
rx,
130-
&outputs,
131-
), outputs, tcx.dep_graph().clone()))
106+
tcx.ongoing_codegen(LOCAL_CRATE)
132107
})
133108
})
134109
}
135110

136111
pub fn link(&self) -> Result<&Query<()>> {
137112
self.queries.link.compute(|| {
138-
let sess = self.session();
139-
140-
let (ongoing_codegen, outputs, dep_graph) = self.ongoing_codegen()?.take();
113+
let ongoing_codegen = self.ongoing_codegen()?.take();
141114

142115
self.codegen_backend().join_codegen_and_link(
143-
ongoing_codegen,
144-
sess,
145-
&dep_graph,
146-
&outputs,
116+
OneThread::into_inner(ongoing_codegen.codegen_object.steal()),
117+
self.session(),
118+
&ongoing_codegen.dep_graph,
119+
&ongoing_codegen.outputs,
147120
).map_err(|_| ErrorReported)?;
148121

149122
Ok(())

src/librustc_interface/util.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub fn create_session(
8888
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
8989
input_path: Option<PathBuf>,
9090
lint_caps: FxHashMap<lint::LintId, lint::Level>,
91-
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
91+
) -> (Lrc<Session>, Arc<dyn CodegenBackend + Send + Sync>, Lrc<SourceMap>) {
9292
let descriptions = diagnostics_registry();
9393

9494
let loader = file_loader.unwrap_or(box RealFileLoader);
@@ -116,7 +116,7 @@ pub fn create_session(
116116
add_configuration(&mut cfg, &sess, &*codegen_backend);
117117
sess.parse_sess.config = cfg;
118118

119-
(Lrc::new(sess), Lrc::new(codegen_backend), source_map)
119+
(Lrc::new(sess), codegen_backend, source_map)
120120
}
121121

122122
// Temporarily have stack size set to 32MB to deal with various crates with long method
@@ -239,7 +239,7 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
239239
})
240240
}
241241

242-
fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
242+
fn load_backend_from_dylib(path: &Path) -> fn() -> Arc<dyn CodegenBackend + Send + Sync> {
243243
let lib = DynamicLibrary::open(Some(path)).unwrap_or_else(|err| {
244244
let err = format!("couldn't load codegen backend {:?}: {:?}", path, err);
245245
early_error(ErrorOutputType::default(), &err);
@@ -260,10 +260,10 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
260260
}
261261
}
262262

263-
pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
263+
pub fn get_codegen_backend(sess: &Session) -> Arc<dyn CodegenBackend + Send + Sync> {
264264
static INIT: Once = Once::new();
265265

266-
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
266+
static mut LOAD: fn() -> Arc<dyn CodegenBackend + Send + Sync> = || unreachable!();
267267

268268
INIT.call_once(|| {
269269
let codegen_name = sess.opts.debugging_opts.codegen_backend.as_ref()
@@ -284,7 +284,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
284284
backend
285285
}
286286

287-
pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
287+
pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Arc<dyn CodegenBackend + Send + Sync> {
288288
// For now we only allow this function to be called once as it'll dlopen a
289289
// few things, which seems to work best if we only do that once. In
290290
// general this assertion never trips due to the once guard in `get_codegen_backend`,

src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,6 @@ impl CodegenBackend for TheBackend {
9595

9696
/// This is the entrypoint for a hot plugged rustc_codegen_llvm
9797
#[no_mangle]
98-
pub fn __rustc_codegen_backend() -> Box<CodegenBackend> {
99-
Box::new(TheBackend)
98+
pub fn __rustc_codegen_backend() -> Arc<dyn CodegenBackend + Send + Sync> {
99+
Arc::new(TheBackend)
100100
}

0 commit comments

Comments
 (0)