Skip to content

Commit

Permalink
rustc: Move codegen to a query
Browse files Browse the repository at this point in the history
This commit moves the actual code generation in the compiler behind a query
keyed by a codegen unit's name. This ended up entailing quite a few internal
refactorings to enable this, along with a few cut corners:

* The `OutputFilenames` structure is now tracked in the `TyCtxt` as it affects a
  whole bunch of trans and such. This is now behind a query and threaded into
  the construction of the `TyCtxt`.

* The `TyCtxt` now has a channel "out the back" intended to send data to worker
  threads in rustc_trans. This is used as a sort of side effect of the codegen
  query but morally what's happening here is the return value of the query
  (currently unit but morally a path) is only valid once the background threads
  have all finished.

* Dispatching work items to the codegen threads was refactored to only rely on
  data in `TyCtxt`, which mostly just involved refactoring where data was
  stored, moving it from the translation thread to the controller thread's
  `CodegenContext` or the like.

* A new thread locals was introduced in trans to work around the query
  system. This is used in the implementation of `assert_module_sources` which
  looks like an artifact of the old query system and will presumably go away
  once red/green is up and running.
  • Loading branch information
alexcrichton committed Sep 17, 2017
1 parent 3021c1d commit 6d614dd
Show file tree
Hide file tree
Showing 17 changed files with 484 additions and 428 deletions.
4 changes: 4 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use ich::StableHashingContext;
use std::fmt;
use std::hash::Hash;
use syntax_pos::symbol::InternedString;

// erase!() just makes tokens go away. It's used to specify which macro argument
// is repeated (i.e. which sub-expression of the macro we are in) but don't need
Expand Down Expand Up @@ -580,6 +581,9 @@ define_dep_nodes!( <'tcx>
[] ExportName(DefId),
[] ContainsExternIndicator(DefId),
[] IsTranslatedFunction(DefId),
[] CodegenUnit(InternedString),
[] CompileCodegenUnit(InternedString),
[] OutputFilenames,
);

trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
Expand Down
31 changes: 31 additions & 0 deletions src/librustc/middle/trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,34 @@ impl<'tcx> CodegenUnit<'tcx> {
&mut self.items
}
}

#[derive(Clone, Default)]
pub struct Stats {
pub n_glues_created: usize,
pub n_null_glues: usize,
pub n_real_glues: usize,
pub n_fns: usize,
pub n_inlines: usize,
pub n_closures: usize,
pub n_llvm_insns: usize,
pub llvm_insns: FxHashMap<String, usize>,
// (ident, llvm-instructions)
pub fn_stats: Vec<(String, usize)>,
}

impl Stats {
pub fn extend(&mut self, stats: Stats) {
self.n_glues_created += stats.n_glues_created;
self.n_null_glues += stats.n_null_glues;
self.n_real_glues += stats.n_real_glues;
self.n_fns += stats.n_fns;
self.n_inlines += stats.n_inlines;
self.n_closures += stats.n_closures;
self.n_llvm_insns += stats.n_llvm_insns;

for (k, v) in stats.llvm_insns {
*self.llvm_insns.entry(k).or_insert(0) += v;
}
self.fn_stats.extend(stats.fn_stats);
}
}
10 changes: 10 additions & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use dep_graph::DepGraph;
use errors::DiagnosticBuilder;
use session::Session;
use session::config::OutputFilenames;
use middle;
use hir::{TraitCandidate, HirId, ItemLocalId};
use hir::def::{Def, Export};
Expand Down Expand Up @@ -65,6 +66,7 @@ use std::ops::Deref;
use std::iter;
use std::rc::Rc;
use std::sync::mpsc;
use std::sync::Arc;
use syntax::abi;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
Expand Down Expand Up @@ -910,6 +912,8 @@ 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: mpsc::Sender<Box<Any + Send>>,

output_filenames: Arc<OutputFilenames>,
}

impl<'tcx> GlobalCtxt<'tcx> {
Expand Down Expand Up @@ -1035,6 +1039,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
hir: hir_map::Map<'tcx>,
crate_name: &str,
tx: mpsc::Sender<Box<Any + Send>>,
output_filenames: &OutputFilenames,
f: F) -> R
where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R
{
Expand Down Expand Up @@ -1156,6 +1161,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
stability_interner: RefCell::new(FxHashSet()),
all_traits: RefCell::new(None),
tx_to_llvm_workers: tx,
output_filenames: Arc::new(output_filenames.clone()),
}, f)
}

Expand Down Expand Up @@ -2229,4 +2235,8 @@ pub fn provide(providers: &mut ty::maps::Providers) {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(tcx.cstore.postorder_cnums_untracked())
};
providers.output_filenames = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
tcx.output_filenames.clone()
};
}
39 changes: 38 additions & 1 deletion src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
use middle::stability::{self, DeprecationEntry};
use middle::lang_items::{LanguageItems, LangItem};
use middle::exported_symbols::SymbolExportLevel;
use middle::trans::CodegenUnit;
use middle::trans::{CodegenUnit, Stats};
use mir;
use mir::transform::{MirSuite, MirPassIndex};
use session::CompileResult;
use session::config::OutputFilenames;
use traits::specialization_graph;
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
use ty::layout::{Layout, LayoutError};
Expand All @@ -52,6 +53,7 @@ use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;
use syntax_pos::{Span, DUMMY_SP};
use syntax_pos::symbol::InternedString;
use syntax::attr;
use syntax::ast;
use syntax::symbol::Symbol;
Expand Down Expand Up @@ -180,6 +182,15 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
}
}

impl Key for InternedString {
fn map_crate(&self) -> CrateNum {
LOCAL_CRATE
}
fn default_span(&self, _tcx: TyCtxt) -> Span {
DUMMY_SP
}
}

trait Value<'tcx>: Sized {
fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
}
Expand Down Expand Up @@ -760,6 +771,24 @@ impl<'tcx> QueryDescription for queries::collect_and_partition_translation_items
}
}

impl<'tcx> QueryDescription for queries::codegen_unit<'tcx> {
fn describe(_tcx: TyCtxt, _: InternedString) -> String {
format!("codegen_unit")
}
}

impl<'tcx> QueryDescription for queries::compile_codegen_unit<'tcx> {
fn describe(_tcx: TyCtxt, _: InternedString) -> String {
format!("compile_codegen_unit")
}
}

impl<'tcx> QueryDescription for queries::output_filenames<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("output_filenames")
}
}

// If enabled, send a message to the profile-queries thread
macro_rules! profq_msg {
($tcx:expr, $msg:expr) => {
Expand Down Expand Up @@ -1395,6 +1424,10 @@ define_maps! { <'tcx>
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
[] fn is_translated_function: IsTranslatedFunction(DefId) -> bool,
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
[] fn output_filenames: output_filenames_node(CrateNum)
-> Arc<OutputFilenames>,
}

fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
Expand Down Expand Up @@ -1512,3 +1545,7 @@ fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
fn collect_and_partition_translation_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::CollectAndPartitionTranslationItems
}

fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::OutputFilenames
}
25 changes: 15 additions & 10 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ pub fn compile_input(sess: &Session,
&resolutions,
&expanded_crate,
&hir_map.krate(),
&outputs,
&crate_name),
Ok(()));
}
Expand All @@ -216,6 +217,7 @@ pub fn compile_input(sess: &Session,
&arena,
&arenas,
&crate_name,
&outputs,
|tcx, analysis, incremental_hashes_map, rx, result| {
{
// Eventually, we will want to track plugins.
Expand Down Expand Up @@ -246,8 +248,7 @@ pub fn compile_input(sess: &Session,

let trans = phase_4_translate_to_llvm(tcx,
incremental_hashes_map,
rx,
&outputs);
rx);

if log_enabled!(::log::LogLevel::Info) {
println!("Post-trans");
Expand All @@ -261,7 +262,7 @@ pub fn compile_input(sess: &Session,
}
}

Ok((outputs, trans, tcx.dep_graph.clone()))
Ok((outputs.clone(), trans, tcx.dep_graph.clone()))
})??
};

Expand Down Expand Up @@ -486,6 +487,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
resolutions: &'a Resolutions,
krate: &'a ast::Crate,
hir_crate: &'a hir::Crate,
output_filenames: &'a OutputFilenames,
crate_name: &'a str)
-> Self {
CompileState {
Expand All @@ -498,6 +500,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
resolutions: Some(resolutions),
expanded_crate: Some(krate),
hir_crate: Some(hir_crate),
output_filenames: Some(output_filenames),
out_file: out_file.as_ref().map(|s| &**s),
..CompileState::empty(input, session, out_dir)
}
Expand Down Expand Up @@ -913,6 +916,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
arena: &'tcx DroplessArena,
arenas: &'tcx GlobalArenas<'tcx>,
name: &str,
output_filenames: &OutputFilenames,
f: F)
-> Result<R, CompileIncomplete>
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
Expand All @@ -922,11 +926,11 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
CompileResult) -> R
{
macro_rules! try_with_f {
($e: expr, ($t: expr, $a: expr, $h: expr)) => {
($e: expr, ($($t:tt)*)) => {
match $e {
Ok(x) => x,
Err(x) => {
f($t, $a, $h, Err(x));
f($($t)*, Err(x));
return Err(x);
}
}
Expand Down Expand Up @@ -1047,6 +1051,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
hir_map,
name,
tx,
output_filenames,
|tcx| {
let incremental_hashes_map =
time(time_passes,
Expand All @@ -1062,7 +1067,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|| stability::check_unstable_api_usage(tcx));

// passes are timed inside typeck
try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map));
try_with_f!(typeck::check_crate(tcx),
(tcx, analysis, incremental_hashes_map, rx));

time(time_passes,
"const checking",
Expand Down Expand Up @@ -1106,7 +1112,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
return Ok(f(tcx, analysis, incremental_hashes_map, sess.compile_status()));
return Ok(f(tcx, analysis, incremental_hashes_map, rx, sess.compile_status()));
}

time(time_passes, "death checking", || middle::dead::check_crate(tcx));
Expand All @@ -1125,8 +1131,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
/// be discarded.
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
incremental_hashes_map: IncrementalHashesMap,
rx: mpsc::Receiver<Box<Any + Send>>,
output_filenames: &OutputFilenames)
rx: mpsc::Receiver<Box<Any + Send>>)
-> write::OngoingCrateTranslation {
let time_passes = tcx.sess.time_passes();

Expand All @@ -1136,7 +1141,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

let translation =
time(time_passes, "translation", move || {
trans::trans_crate(tcx, incremental_hashes_map, rx, output_filenames)
trans::trans_crate(tcx, incremental_hashes_map, rx)
});

if tcx.sess.profile_queries() {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
ppm,
state.arena.unwrap(),
state.arenas.unwrap(),
state.output_filenames.unwrap(),
opt_uii.clone(),
state.out_file);
};
Expand Down
14 changes: 11 additions & 3 deletions src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use rustc::cfg::graphviz::LabelledCFG;
use rustc::dep_graph::DepGraph;
use rustc::middle::cstore::CrateStore;
use rustc::session::Session;
use rustc::session::config::Input;
use rustc::session::config::{Input, OutputFilenames};
use rustc_borrowck as borrowck;
use rustc_borrowck::graphviz as borrowck_dot;

Expand Down Expand Up @@ -205,6 +205,7 @@ impl PpSourceMode {
resolutions: &Resolutions,
arena: &'tcx DroplessArena,
arenas: &'tcx GlobalArenas<'tcx>,
output_filenames: &OutputFilenames,
id: &str,
f: F)
-> A
Expand Down Expand Up @@ -235,7 +236,8 @@ impl PpSourceMode {
arena,
arenas,
id,
|tcx, _, _, _| {
output_filenames,
|tcx, _, _, _, _| {
let empty_tables = ty::TypeckTables::empty(None);
let annotation = TypedAnnotation {
tcx,
Expand Down Expand Up @@ -888,6 +890,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
ppm: PpMode,
arena: &'tcx DroplessArena,
arenas: &'tcx GlobalArenas<'tcx>,
output_filenames: &OutputFilenames,
opt_uii: Option<UserIdentifiedItem>,
ofile: Option<&Path>) {
let dep_graph = DepGraph::new(false);
Expand All @@ -902,6 +905,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
crate_name,
arena,
arenas,
output_filenames,
ppm,
opt_uii,
ofile);
Expand Down Expand Up @@ -940,6 +944,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
resolutions,
arena,
arenas,
output_filenames,
crate_name,
move |annotation, krate| {
debug!("pretty printing source code {:?}", s);
Expand All @@ -964,6 +969,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
resolutions,
arena,
arenas,
output_filenames,
crate_name,
move |annotation, _| {
debug!("pretty printing source code {:?}", s);
Expand Down Expand Up @@ -1007,6 +1013,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
crate_name: &str,
arena: &'tcx DroplessArena,
arenas: &'tcx GlobalArenas<'tcx>,
output_filenames: &OutputFilenames,
ppm: PpMode,
uii: Option<UserIdentifiedItem>,
ofile: Option<&Path>) {
Expand All @@ -1028,7 +1035,8 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
arena,
arenas,
crate_name,
|tcx, _, _, _| {
output_filenames,
|tcx, _, _, _, _| {
match ppm {
PpmMir | PpmMirCFG => {
if let Some(nodeid) = nodeid {
Expand Down
Loading

0 comments on commit 6d614dd

Please sign in to comment.