Skip to content

Commit 6d614dd

Browse files
committed
rustc: Move codegen to a query
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.
1 parent 3021c1d commit 6d614dd

File tree

17 files changed

+484
-428
lines changed

17 files changed

+484
-428
lines changed

src/librustc/dep_graph/dep_node.rs

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
7171
use ich::StableHashingContext;
7272
use std::fmt;
7373
use std::hash::Hash;
74+
use syntax_pos::symbol::InternedString;
7475

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

585589
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/middle/trans.rs

+31
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,34 @@ impl<'tcx> CodegenUnit<'tcx> {
7777
&mut self.items
7878
}
7979
}
80+
81+
#[derive(Clone, Default)]
82+
pub struct Stats {
83+
pub n_glues_created: usize,
84+
pub n_null_glues: usize,
85+
pub n_real_glues: usize,
86+
pub n_fns: usize,
87+
pub n_inlines: usize,
88+
pub n_closures: usize,
89+
pub n_llvm_insns: usize,
90+
pub llvm_insns: FxHashMap<String, usize>,
91+
// (ident, llvm-instructions)
92+
pub fn_stats: Vec<(String, usize)>,
93+
}
94+
95+
impl Stats {
96+
pub fn extend(&mut self, stats: Stats) {
97+
self.n_glues_created += stats.n_glues_created;
98+
self.n_null_glues += stats.n_null_glues;
99+
self.n_real_glues += stats.n_real_glues;
100+
self.n_fns += stats.n_fns;
101+
self.n_inlines += stats.n_inlines;
102+
self.n_closures += stats.n_closures;
103+
self.n_llvm_insns += stats.n_llvm_insns;
104+
105+
for (k, v) in stats.llvm_insns {
106+
*self.llvm_insns.entry(k).or_insert(0) += v;
107+
}
108+
self.fn_stats.extend(stats.fn_stats);
109+
}
110+
}

src/librustc/ty/context.rs

+10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use dep_graph::DepGraph;
1414
use errors::DiagnosticBuilder;
1515
use session::Session;
16+
use session::config::OutputFilenames;
1617
use middle;
1718
use hir::{TraitCandidate, HirId, ItemLocalId};
1819
use hir::def::{Def, Export};
@@ -65,6 +66,7 @@ use std::ops::Deref;
6566
use std::iter;
6667
use std::rc::Rc;
6768
use std::sync::mpsc;
69+
use std::sync::Arc;
6870
use syntax::abi;
6971
use syntax::ast::{self, Name, NodeId};
7072
use syntax::attr;
@@ -910,6 +912,8 @@ pub struct GlobalCtxt<'tcx> {
910912
/// when satisfying the query for a particular codegen unit. Internally in
911913
/// the query it'll send data along this channel to get processed later.
912914
pub tx_to_llvm_workers: mpsc::Sender<Box<Any + Send>>,
915+
916+
output_filenames: Arc<OutputFilenames>,
913917
}
914918

915919
impl<'tcx> GlobalCtxt<'tcx> {
@@ -1035,6 +1039,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10351039
hir: hir_map::Map<'tcx>,
10361040
crate_name: &str,
10371041
tx: mpsc::Sender<Box<Any + Send>>,
1042+
output_filenames: &OutputFilenames,
10381043
f: F) -> R
10391044
where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R
10401045
{
@@ -1156,6 +1161,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11561161
stability_interner: RefCell::new(FxHashSet()),
11571162
all_traits: RefCell::new(None),
11581163
tx_to_llvm_workers: tx,
1164+
output_filenames: Arc::new(output_filenames.clone()),
11591165
}, f)
11601166
}
11611167

@@ -2229,4 +2235,8 @@ pub fn provide(providers: &mut ty::maps::Providers) {
22292235
assert_eq!(cnum, LOCAL_CRATE);
22302236
Rc::new(tcx.cstore.postorder_cnums_untracked())
22312237
};
2238+
providers.output_filenames = |tcx, cnum| {
2239+
assert_eq!(cnum, LOCAL_CRATE);
2240+
tcx.output_filenames.clone()
2241+
};
22322242
}

src/librustc/ty/maps.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
2424
use middle::stability::{self, DeprecationEntry};
2525
use middle::lang_items::{LanguageItems, LangItem};
2626
use middle::exported_symbols::SymbolExportLevel;
27-
use middle::trans::CodegenUnit;
27+
use middle::trans::{CodegenUnit, Stats};
2828
use mir;
2929
use mir::transform::{MirSuite, MirPassIndex};
3030
use session::CompileResult;
31+
use session::config::OutputFilenames;
3132
use traits::specialization_graph;
3233
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
3334
use ty::layout::{Layout, LayoutError};
@@ -52,6 +53,7 @@ use std::ops::Deref;
5253
use std::rc::Rc;
5354
use std::sync::Arc;
5455
use syntax_pos::{Span, DUMMY_SP};
56+
use syntax_pos::symbol::InternedString;
5557
use syntax::attr;
5658
use syntax::ast;
5759
use syntax::symbol::Symbol;
@@ -180,6 +182,15 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
180182
}
181183
}
182184

185+
impl Key for InternedString {
186+
fn map_crate(&self) -> CrateNum {
187+
LOCAL_CRATE
188+
}
189+
fn default_span(&self, _tcx: TyCtxt) -> Span {
190+
DUMMY_SP
191+
}
192+
}
193+
183194
trait Value<'tcx>: Sized {
184195
fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
185196
}
@@ -760,6 +771,24 @@ impl<'tcx> QueryDescription for queries::collect_and_partition_translation_items
760771
}
761772
}
762773

774+
impl<'tcx> QueryDescription for queries::codegen_unit<'tcx> {
775+
fn describe(_tcx: TyCtxt, _: InternedString) -> String {
776+
format!("codegen_unit")
777+
}
778+
}
779+
780+
impl<'tcx> QueryDescription for queries::compile_codegen_unit<'tcx> {
781+
fn describe(_tcx: TyCtxt, _: InternedString) -> String {
782+
format!("compile_codegen_unit")
783+
}
784+
}
785+
786+
impl<'tcx> QueryDescription for queries::output_filenames<'tcx> {
787+
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
788+
format!("output_filenames")
789+
}
790+
}
791+
763792
// If enabled, send a message to the profile-queries thread
764793
macro_rules! profq_msg {
765794
($tcx:expr, $msg:expr) => {
@@ -1395,6 +1424,10 @@ define_maps! { <'tcx>
13951424
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
13961425
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
13971426
[] fn is_translated_function: IsTranslatedFunction(DefId) -> bool,
1427+
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
1428+
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
1429+
[] fn output_filenames: output_filenames_node(CrateNum)
1430+
-> Arc<OutputFilenames>,
13981431
}
13991432

14001433
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@@ -1512,3 +1545,7 @@ fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
15121545
fn collect_and_partition_translation_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
15131546
DepConstructor::CollectAndPartitionTranslationItems
15141547
}
1548+
1549+
fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
1550+
DepConstructor::OutputFilenames
1551+
}

src/librustc_driver/driver.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ pub fn compile_input(sess: &Session,
193193
&resolutions,
194194
&expanded_crate,
195195
&hir_map.krate(),
196+
&outputs,
196197
&crate_name),
197198
Ok(()));
198199
}
@@ -216,6 +217,7 @@ pub fn compile_input(sess: &Session,
216217
&arena,
217218
&arenas,
218219
&crate_name,
220+
&outputs,
219221
|tcx, analysis, incremental_hashes_map, rx, result| {
220222
{
221223
// Eventually, we will want to track plugins.
@@ -246,8 +248,7 @@ pub fn compile_input(sess: &Session,
246248

247249
let trans = phase_4_translate_to_llvm(tcx,
248250
incremental_hashes_map,
249-
rx,
250-
&outputs);
251+
rx);
251252

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

264-
Ok((outputs, trans, tcx.dep_graph.clone()))
265+
Ok((outputs.clone(), trans, tcx.dep_graph.clone()))
265266
})??
266267
};
267268

@@ -486,6 +487,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
486487
resolutions: &'a Resolutions,
487488
krate: &'a ast::Crate,
488489
hir_crate: &'a hir::Crate,
490+
output_filenames: &'a OutputFilenames,
489491
crate_name: &'a str)
490492
-> Self {
491493
CompileState {
@@ -498,6 +500,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
498500
resolutions: Some(resolutions),
499501
expanded_crate: Some(krate),
500502
hir_crate: Some(hir_crate),
503+
output_filenames: Some(output_filenames),
501504
out_file: out_file.as_ref().map(|s| &**s),
502505
..CompileState::empty(input, session, out_dir)
503506
}
@@ -913,6 +916,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
913916
arena: &'tcx DroplessArena,
914917
arenas: &'tcx GlobalArenas<'tcx>,
915918
name: &str,
919+
output_filenames: &OutputFilenames,
916920
f: F)
917921
-> Result<R, CompileIncomplete>
918922
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
@@ -922,11 +926,11 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
922926
CompileResult) -> R
923927
{
924928
macro_rules! try_with_f {
925-
($e: expr, ($t: expr, $a: expr, $h: expr)) => {
929+
($e: expr, ($($t:tt)*)) => {
926930
match $e {
927931
Ok(x) => x,
928932
Err(x) => {
929-
f($t, $a, $h, Err(x));
933+
f($($t)*, Err(x));
930934
return Err(x);
931935
}
932936
}
@@ -1047,6 +1051,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
10471051
hir_map,
10481052
name,
10491053
tx,
1054+
output_filenames,
10501055
|tcx| {
10511056
let incremental_hashes_map =
10521057
time(time_passes,
@@ -1062,7 +1067,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
10621067
|| stability::check_unstable_api_usage(tcx));
10631068

10641069
// passes are timed inside typeck
1065-
try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map));
1070+
try_with_f!(typeck::check_crate(tcx),
1071+
(tcx, analysis, incremental_hashes_map, rx));
10661072

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

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

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

11371142
let translation =
11381143
time(time_passes, "translation", move || {
1139-
trans::trans_crate(tcx, incremental_hashes_map, rx, output_filenames)
1144+
trans::trans_crate(tcx, incremental_hashes_map, rx)
11401145
});
11411146

11421147
if tcx.sess.profile_queries() {

src/librustc_driver/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
645645
ppm,
646646
state.arena.unwrap(),
647647
state.arenas.unwrap(),
648+
state.output_filenames.unwrap(),
648649
opt_uii.clone(),
649650
state.out_file);
650651
};

src/librustc_driver/pretty.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc::cfg::graphviz::LabelledCFG;
2323
use rustc::dep_graph::DepGraph;
2424
use rustc::middle::cstore::CrateStore;
2525
use rustc::session::Session;
26-
use rustc::session::config::Input;
26+
use rustc::session::config::{Input, OutputFilenames};
2727
use rustc_borrowck as borrowck;
2828
use rustc_borrowck::graphviz as borrowck_dot;
2929

@@ -205,6 +205,7 @@ impl PpSourceMode {
205205
resolutions: &Resolutions,
206206
arena: &'tcx DroplessArena,
207207
arenas: &'tcx GlobalArenas<'tcx>,
208+
output_filenames: &OutputFilenames,
208209
id: &str,
209210
f: F)
210211
-> A
@@ -235,7 +236,8 @@ impl PpSourceMode {
235236
arena,
236237
arenas,
237238
id,
238-
|tcx, _, _, _| {
239+
output_filenames,
240+
|tcx, _, _, _, _| {
239241
let empty_tables = ty::TypeckTables::empty(None);
240242
let annotation = TypedAnnotation {
241243
tcx,
@@ -888,6 +890,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
888890
ppm: PpMode,
889891
arena: &'tcx DroplessArena,
890892
arenas: &'tcx GlobalArenas<'tcx>,
893+
output_filenames: &OutputFilenames,
891894
opt_uii: Option<UserIdentifiedItem>,
892895
ofile: Option<&Path>) {
893896
let dep_graph = DepGraph::new(false);
@@ -902,6 +905,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
902905
crate_name,
903906
arena,
904907
arenas,
908+
output_filenames,
905909
ppm,
906910
opt_uii,
907911
ofile);
@@ -940,6 +944,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
940944
resolutions,
941945
arena,
942946
arenas,
947+
output_filenames,
943948
crate_name,
944949
move |annotation, krate| {
945950
debug!("pretty printing source code {:?}", s);
@@ -964,6 +969,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
964969
resolutions,
965970
arena,
966971
arenas,
972+
output_filenames,
967973
crate_name,
968974
move |annotation, _| {
969975
debug!("pretty printing source code {:?}", s);
@@ -1007,6 +1013,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
10071013
crate_name: &str,
10081014
arena: &'tcx DroplessArena,
10091015
arenas: &'tcx GlobalArenas<'tcx>,
1016+
output_filenames: &OutputFilenames,
10101017
ppm: PpMode,
10111018
uii: Option<UserIdentifiedItem>,
10121019
ofile: Option<&Path>) {
@@ -1028,7 +1035,8 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
10281035
arena,
10291036
arenas,
10301037
crate_name,
1031-
|tcx, _, _, _| {
1038+
output_filenames,
1039+
|tcx, _, _, _, _| {
10321040
match ppm {
10331041
PpmMir | PpmMirCFG => {
10341042
if let Some(nodeid) = nodeid {

0 commit comments

Comments
 (0)