Skip to content

Commit

Permalink
Make ongoing_codegen a query
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Jul 8, 2019
1 parent e29f8f1 commit 59f099e
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 63 deletions.
6 changes: 6 additions & 0 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ rustc_queries! {
desc { "running analysis passes on this crate" }
}

query ongoing_codegen(_: CrateNum) -> Result<Lrc<ty::OngoingCodegen>, ErrorReported> {
no_hash
eval_always
desc { "starting code generation" }
}

/// Records the type of every item.
query type_of(key: DefId) -> Ty<'tcx> {
cache_on_disk_if { key.is_local() }
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
StableVec};
use arena::SyncDroplessArena;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal, AtomicOnce, Once};
use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal, AtomicOnce, Once, OneThread};
use std::any::Any;
use std::borrow::Borrow;
use std::cmp::Ordering;
Expand Down Expand Up @@ -1016,6 +1016,9 @@ pub struct GlobalCtxt<'tcx> {

pub sess_rc: Lrc<Session>,

// This stores a `Arc<dyn CodegenBackend + Send + Sync>`.
pub codegen_backend: Box<dyn Any + Send + Sync>,

lowered_hir: AtomicOnce<&'tcx hir::LoweredHir>,
hir_map: AtomicOnce<&'tcx hir_map::Map<'tcx>>,

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

impl<'tcx> TyCtxt<'tcx> {
Expand Down Expand Up @@ -1188,7 +1192,7 @@ impl<'tcx> TyCtxt<'tcx> {
extern_providers: ty::query::Providers<'tcx>,
arenas: &'tcx AllArenas,
crate_name: Option<String>,
tx: mpsc::Sender<Box<dyn Any + Send>>,
codegen_backend: Box<dyn Any + Send + Sync>,
io: InputsAndOutputs,
) -> GlobalCtxt<'tcx> {
let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| {
Expand All @@ -1207,13 +1211,15 @@ impl<'tcx> TyCtxt<'tcx> {
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;
let (tx, rx) = mpsc::channel();

GlobalCtxt {
sess: &**s,
arena: WorkerLocal::new(|_| Arena::default()),
cstore,
cstore_rc,
sess_rc: s.clone(),
codegen_backend,
interners,
dep_graph: AtomicOnce::new(),
common,
Expand All @@ -1237,6 +1243,7 @@ impl<'tcx> TyCtxt<'tcx> {
allocation_interner: Default::default(),
alloc_map: Lock::new(interpret::AllocMap::new()),
tx_to_llvm_workers: Lock::new(tx),
rx_to_llvm_workers: Steal::new(OneThread::new(rx)),
io,
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ use crate::mir::Body;
use crate::mir::interpret::{GlobalId, ErrorHandled};
use crate::mir::GeneratorLayout;
use crate::session::CrateDisambiguator;
use crate::session::config::OutputFilenames;
use crate::dep_graph::DepGraph;
use crate::traits::{self, Reveal};
use crate::ty;
use crate::ty::layout::VariantIdx;
use crate::ty::subst::{Subst, InternalSubsts, SubstsRef};
use crate::ty::util::{IntTypeExt, Discr};
use crate::ty::walk::TypeWalker;
use crate::ty::steal::Steal;
use crate::util::captures::Captures;
use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap};
use arena::SyncDroplessArena;
Expand All @@ -39,6 +42,7 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::any::Any;
use std::sync::Arc;
use rustc_data_structures::sync::{self, Lrc, OneThread, ParallelIterator, par_iter};
use std::slice;
use std::{mem, ptr};
Expand Down Expand Up @@ -122,6 +126,12 @@ mod sty;

// Data types

pub struct OngoingCodegen {
pub outputs: Arc<OutputFilenames>,
pub dep_graph: DepGraph,
pub codegen_object: Steal<OneThread<Box<dyn Any>>>,
}

pub struct PluginInfo {
pub syntax_exts: Vec<NamedSyntaxExtension>,
pub attributes: Vec<(Symbol, AttributeType)>,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_codegen_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ unsafe impl Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
unsafe impl Sync for LlvmCodegenBackend {}

impl LlvmCodegenBackend {
pub fn new() -> Box<dyn CodegenBackend> {
box LlvmCodegenBackend(())
pub fn new() -> Arc<dyn CodegenBackend + Send + Sync> {
Arc::new(LlvmCodegenBackend(()))
}
}

Expand Down Expand Up @@ -349,7 +349,7 @@ impl CodegenBackend for LlvmCodegenBackend {

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

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub fn run_compiler(
return;
}
let should_stop = RustcDefaultCalls::print_crate_info(
&***compiler.codegen_backend(),
&**compiler.codegen_backend(),
compiler.session(),
None,
&odir,
Expand Down Expand Up @@ -246,7 +246,7 @@ pub fn run_compiler(
interface::run_compiler(config, |compiler| {
let sess = compiler.session();
let should_stop = RustcDefaultCalls::print_crate_info(
&***compiler.codegen_backend(),
&**compiler.codegen_backend(),
sess,
Some(compiler.input()),
compiler.output_dir(),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub type Result<T> = result::Result<T, ErrorReported>;
/// Created by passing `Config` to `run_compiler`.
pub struct Compiler {
pub(crate) sess: Lrc<Session>,
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
codegen_backend: Arc<dyn CodegenBackend + Send + Sync>,
source_map: Lrc<SourceMap>,
pub(crate) io: InputsAndOutputs,
pub(crate) queries: Queries,
Expand All @@ -40,7 +40,7 @@ impl Compiler {
pub fn session(&self) -> &Lrc<Session> {
&self.sess
}
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
pub fn codegen_backend(&self) -> &Arc<dyn CodegenBackend + Send + Sync> {
&self.codegen_backend
}
pub fn cstore(&self) -> &Lrc<CStore> {
Expand Down
42 changes: 32 additions & 10 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,7 @@ fn load_query_result_cache<'tcx>(
}

pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
providers.ongoing_codegen = ongoing_codegen;
providers.analysis = analysis;
providers.hir_map = hir_map;
providers.lower_ast_to_hir = lower_ast_to_hir;
Expand Down Expand Up @@ -963,7 +964,6 @@ impl BoxedGlobalCtxt {
pub fn create_global_ctxt(
compiler: &Compiler,
io: InputsAndOutputs,
tx: mpsc::Sender<Box<dyn Any + Send>>,
) -> BoxedGlobalCtxt {
let sess = compiler.session().clone();
let cstore = compiler.cstore.clone();
Expand All @@ -985,6 +985,13 @@ pub fn create_global_ctxt(
default_provide_extern(&mut extern_providers);
codegen_backend.provide_extern(&mut extern_providers);

// Move the dyn Any coercion outside the generator to avoid lifetime issues
fn codegen_backend_any(
i: Arc<dyn CodegenBackend + Send + Sync>
) -> Box<dyn Any + Send + Sync> {
Box::new(i)
}

let gcx = TyCtxt::create_global_ctxt(
sess,
&**cstore,
Expand All @@ -993,7 +1000,7 @@ pub fn create_global_ctxt(
extern_providers,
&arenas,
crate_name,
tx,
codegen_backend_any(codegen_backend.clone()),
io,
);

Expand Down Expand Up @@ -1211,12 +1218,23 @@ fn encode_and_write_metadata(

/// Runs the codegen backend, after which the AST and analysis can
/// be discarded.
pub fn start_codegen<'tcx>(
codegen_backend: &dyn CodegenBackend,
fn ongoing_codegen<'tcx>(
tcx: TyCtxt<'tcx>,
rx: mpsc::Receiver<Box<dyn Any + Send>>,
outputs: &OutputFilenames,
) -> Box<dyn Any> {
cnum: CrateNum,
) -> Result<Lrc<ty::OngoingCodegen>> {
tcx.analysis(cnum)?;

assert_eq!(cnum, LOCAL_CRATE);
// Don't do code generation if there were any errors
tcx.sess.compile_status()?;

let outputs = tcx.prepare_outputs(())?;

let rx = OneThread::into_inner(tcx.rx_to_llvm_workers.steal());
let codegen_backend: &dyn Any = &*tcx.codegen_backend;
let codegen_backend = codegen_backend.downcast_ref::<Arc<dyn CodegenBackend + Send + Sync>>()
.unwrap();

if log_enabled!(::log::Level::Info) {
println!("Pre-codegen");
tcx.print_debug_stats();
Expand All @@ -1227,7 +1245,7 @@ pub fn start_codegen<'tcx>(
});

let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding and writing", || {
encode_and_write_metadata(tcx, outputs)
encode_and_write_metadata(tcx, &outputs)
});

tcx.sess.profiler(|p| p.start_activity("codegen crate"));
Expand All @@ -1242,11 +1260,15 @@ pub fn start_codegen<'tcx>(
}

if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, outputs) {
if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, &outputs) {
tcx.sess.err(&format!("could not emit MIR: {}", e));
tcx.sess.abort_if_errors();
}
}

codegen
Ok(Lrc::new(ty::OngoingCodegen {
outputs,
dep_graph: tcx.dep_graph().clone(),
codegen_object: Steal::new(OneThread::new(codegen)),
}))
}
45 changes: 9 additions & 36 deletions src/librustc_interface/queries.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::interface::{Compiler, Result};
use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt};

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

#[derive(Default)]
pub(crate) struct Queries {
codegen_channel: Query<(Steal<mpsc::Sender<Box<dyn Any + Send>>>,
Steal<mpsc::Receiver<Box<dyn Any + Send>>>)>,
global_ctxt: Query<BoxedGlobalCtxt>,
ongoing_codegen: Query<(Box<dyn Any>, Arc<OutputFilenames>, DepGraph)>,
ongoing_codegen: Query<Lrc<ty::OngoingCodegen>>,
link: Query<()>,
}

impl Compiler {
pub fn codegen_channel(&self) -> Result<&Query<(Steal<mpsc::Sender<Box<dyn Any + Send>>>,
Steal<mpsc::Receiver<Box<dyn Any + Send>>>)>> {
self.queries.codegen_channel.compute(|| {
let (tx, rx) = mpsc::channel();
Ok((Steal::new(tx), Steal::new(rx)))
})
}

pub fn global_ctxt(&self) -> Result<&Query<BoxedGlobalCtxt>> {
self.queries.global_ctxt.compute(|| {
let tx = self.codegen_channel()?.peek().0.steal();
Ok(passes::create_global_ctxt(
self,
self.io.clone(),
tx
))
})
}

pub fn ongoing_codegen(
&self
) -> Result<&Query<(Box<dyn Any>, Arc<OutputFilenames>, DepGraph)>> {
) -> Result<&Query<Lrc<ty::OngoingCodegen>>> {
self.queries.ongoing_codegen.compute(|| {
let rx = self.codegen_channel()?.peek().1.steal();
self.global_ctxt()?.peek_mut().enter(|tcx| {
tcx.analysis(LOCAL_CRATE).ok();

// Don't do code generation if there were any errors
self.session().compile_status()?;

let outputs = tcx.prepare_outputs(())?;

Ok((passes::start_codegen(
&***self.codegen_backend(),
tcx,
rx,
&outputs,
), outputs, tcx.dep_graph().clone()))
tcx.ongoing_codegen(LOCAL_CRATE)
})
})
}

pub fn link(&self) -> Result<&Query<()>> {
self.queries.link.compute(|| {
let sess = self.session();

let (ongoing_codegen, outputs, dep_graph) = self.ongoing_codegen()?.take();
let ongoing_codegen = self.ongoing_codegen()?.take();

self.codegen_backend().join_codegen_and_link(
ongoing_codegen,
sess,
&dep_graph,
&outputs,
OneThread::into_inner(ongoing_codegen.codegen_object.steal()),
self.session(),
&ongoing_codegen.dep_graph,
&ongoing_codegen.outputs,
).map_err(|_| ErrorReported)?;

Ok(())
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_interface/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub fn create_session(
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
input_path: Option<PathBuf>,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
) -> (Lrc<Session>, Arc<dyn CodegenBackend + Send + Sync>, Lrc<SourceMap>) {
let descriptions = diagnostics_registry();

let loader = file_loader.unwrap_or(box RealFileLoader);
Expand Down Expand Up @@ -117,7 +117,7 @@ pub fn create_session(
add_configuration(&mut cfg, &sess, &*codegen_backend);
sess.parse_sess.config = cfg;

(Lrc::new(sess), Lrc::new(codegen_backend), source_map)
(Lrc::new(sess), codegen_backend, source_map)
}

// Temporarily have stack size set to 32MB to deal with various crates with long method
Expand Down Expand Up @@ -246,7 +246,7 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
})
}

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

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

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

INIT.call_once(|| {
let codegen_name = sess.opts.debugging_opts.codegen_backend.as_ref()
Expand All @@ -291,7 +291,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
backend
}

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

0 comments on commit 59f099e

Please sign in to comment.