Skip to content

Commit 3021c1d

Browse files
committed
rustc: Attach an mpsc channel to TyCtxt
This commit attaches a channel to the LLVM workers to the `TyCtxt` which will later be used during the codegen query to actually send work to LLVM workers. Otherwise this commit is just plumbing this channel throughout the compiler to ensure it reaches the right consumers.
1 parent 2eada58 commit 3021c1d

File tree

4 files changed

+50
-23
lines changed

4 files changed

+50
-23
lines changed

src/librustc/ty/context.rs

+11
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ use std::mem;
6464
use std::ops::Deref;
6565
use std::iter;
6666
use std::rc::Rc;
67+
use std::sync::mpsc;
6768
use syntax::abi;
6869
use syntax::ast::{self, Name, NodeId};
6970
use syntax::attr;
@@ -901,6 +902,14 @@ pub struct GlobalCtxt<'tcx> {
901902
/// error reporting, and so is lazily initialized and generally
902903
/// shouldn't taint the common path (hence the RefCell).
903904
pub all_traits: RefCell<Option<Vec<DefId>>>,
905+
906+
/// A general purpose channel to throw data out the back towards LLVM worker
907+
/// threads.
908+
///
909+
/// This is intended to only get used during the trans phase of the compiler
910+
/// when satisfying the query for a particular codegen unit. Internally in
911+
/// the query it'll send data along this channel to get processed later.
912+
pub tx_to_llvm_workers: mpsc::Sender<Box<Any + Send>>,
904913
}
905914

906915
impl<'tcx> GlobalCtxt<'tcx> {
@@ -1025,6 +1034,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10251034
named_region_map: resolve_lifetime::NamedRegionMap,
10261035
hir: hir_map::Map<'tcx>,
10271036
crate_name: &str,
1037+
tx: mpsc::Sender<Box<Any + Send>>,
10281038
f: F) -> R
10291039
where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R
10301040
{
@@ -1145,6 +1155,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11451155
derive_macros: RefCell::new(NodeMap()),
11461156
stability_interner: RefCell::new(FxHashSet()),
11471157
all_traits: RefCell::new(None),
1158+
tx_to_llvm_workers: tx,
11481159
}, f)
11491160
}
11501161

src/librustc_driver/driver.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ use super::Compilation;
4646

4747
use serialize::json;
4848

49+
use std::any::Any;
4950
use std::env;
5051
use std::ffi::{OsString, OsStr};
5152
use std::fs;
5253
use std::io::{self, Write};
5354
use std::iter;
5455
use std::path::{Path, PathBuf};
5556
use std::rc::Rc;
57+
use std::sync::mpsc;
5658
use syntax::{ast, diagnostics, visit};
5759
use syntax::attr;
5860
use syntax::ext::base::ExtCtxt;
@@ -214,7 +216,7 @@ pub fn compile_input(sess: &Session,
214216
&arena,
215217
&arenas,
216218
&crate_name,
217-
|tcx, analysis, incremental_hashes_map, result| {
219+
|tcx, analysis, incremental_hashes_map, rx, result| {
218220
{
219221
// Eventually, we will want to track plugins.
220222
let _ignore = tcx.dep_graph.in_ignore();
@@ -242,7 +244,9 @@ pub fn compile_input(sess: &Session,
242244
tcx.print_debug_stats();
243245
}
244246

245-
let trans = phase_4_translate_to_llvm(tcx, incremental_hashes_map,
247+
let trans = phase_4_translate_to_llvm(tcx,
248+
incremental_hashes_map,
249+
rx,
246250
&outputs);
247251

248252
if log_enabled!(::log::LogLevel::Info) {
@@ -914,6 +918,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
914918
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
915919
ty::CrateAnalysis,
916920
IncrementalHashesMap,
921+
mpsc::Receiver<Box<Any + Send>>,
917922
CompileResult) -> R
918923
{
919924
macro_rules! try_with_f {
@@ -1028,6 +1033,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
10281033
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges);
10291034
passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans"));
10301035

1036+
let (tx, rx) = mpsc::channel();
1037+
10311038
TyCtxt::create_and_enter(sess,
10321039
cstore,
10331040
local_providers,
@@ -1039,6 +1046,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
10391046
named_region_map,
10401047
hir_map,
10411048
name,
1049+
tx,
10421050
|tcx| {
10431051
let incremental_hashes_map =
10441052
time(time_passes,
@@ -1109,14 +1117,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
11091117

11101118
time(time_passes, "lint checking", || lint::check_crate(tcx));
11111119

1112-
return Ok(f(tcx, analysis, incremental_hashes_map, tcx.sess.compile_status()));
1120+
return Ok(f(tcx, analysis, incremental_hashes_map, rx, tcx.sess.compile_status()));
11131121
})
11141122
}
11151123

11161124
/// Run the translation phase to LLVM, after which the AST and analysis can
11171125
/// be discarded.
11181126
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11191127
incremental_hashes_map: IncrementalHashesMap,
1128+
rx: mpsc::Receiver<Box<Any + Send>>,
11201129
output_filenames: &OutputFilenames)
11211130
-> write::OngoingCrateTranslation {
11221131
let time_passes = tcx.sess.time_passes();
@@ -1126,9 +1135,9 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11261135
|| ::rustc::middle::dependency_format::calculate(tcx));
11271136

11281137
let translation =
1129-
time(time_passes,
1130-
"translation",
1131-
move || trans::trans_crate(tcx, incremental_hashes_map, output_filenames));
1138+
time(time_passes, "translation", move || {
1139+
trans::trans_crate(tcx, incremental_hashes_map, rx, output_filenames)
1140+
});
11321141

11331142
if tcx.sess.profile_queries() {
11341143
profile::dump("profile_queries".to_string())

src/librustc_trans/back/write.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use context::{is_pie_binary, get_reloc_model};
3939
use jobserver::{Client, Acquired};
4040
use rustc_demangle;
4141

42+
use std::any::Any;
4243
use std::ffi::CString;
4344
use std::fmt;
4445
use std::fs;
@@ -348,7 +349,7 @@ pub struct CodegenContext {
348349
// compiling incrementally
349350
pub incr_comp_session_dir: Option<PathBuf>,
350351
// Channel back to the main control thread to send messages to
351-
coordinator_send: Sender<Message>,
352+
coordinator_send: Sender<Box<Any + Send>>,
352353
// A reference to the TimeGraph so we can register timings. None means that
353354
// measuring is disabled.
354355
time_graph: Option<TimeGraph>,
@@ -674,7 +675,8 @@ pub fn start_async_translation(tcx: TyCtxt,
674675
crate_output: &OutputFilenames,
675676
time_graph: Option<TimeGraph>,
676677
link: LinkMeta,
677-
metadata: EncodedMetadata)
678+
metadata: EncodedMetadata,
679+
coordinator_receive: Receiver<Box<Any + Send>>)
678680
-> OngoingCrateTranslation {
679681
let sess = tcx.sess;
680682
let crate_name = tcx.crate_name(LOCAL_CRATE);
@@ -798,13 +800,12 @@ pub fn start_async_translation(tcx: TyCtxt,
798800

799801
let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
800802
let (trans_worker_send, trans_worker_receive) = channel();
801-
let (coordinator_send, coordinator_receive) = channel();
802803

803804
let coordinator_thread = start_executing_work(sess,
804805
&crate_info,
805806
shared_emitter,
806807
trans_worker_send,
807-
coordinator_send.clone(),
808+
tcx.tx_to_llvm_workers.clone(),
808809
coordinator_receive,
809810
client,
810811
time_graph.clone(),
@@ -824,7 +825,7 @@ pub fn start_async_translation(tcx: TyCtxt,
824825

825826
time_graph,
826827
output_filenames: crate_output.clone(),
827-
coordinator_send,
828+
coordinator_send: tcx.tx_to_llvm_workers.clone(),
828829
trans_worker_receive,
829830
shared_emitter_main,
830831
future: coordinator_thread
@@ -1138,8 +1139,8 @@ fn start_executing_work(sess: &Session,
11381139
crate_info: &CrateInfo,
11391140
shared_emitter: SharedEmitter,
11401141
trans_worker_send: Sender<Message>,
1141-
coordinator_send: Sender<Message>,
1142-
coordinator_receive: Receiver<Message>,
1142+
coordinator_send: Sender<Box<Any + Send>>,
1143+
coordinator_receive: Receiver<Box<Any + Send>>,
11431144
jobserver: Client,
11441145
time_graph: Option<TimeGraph>,
11451146
exported_symbols: Arc<ExportedSymbols>)
@@ -1156,7 +1157,7 @@ fn start_executing_work(sess: &Session,
11561157
// tokens on `rx` above which will get managed in the main loop below.
11571158
let coordinator_send2 = coordinator_send.clone();
11581159
let helper = jobserver.into_helper_thread(move |token| {
1159-
drop(coordinator_send2.send(Message::Token(token)));
1160+
drop(coordinator_send2.send(Box::new(Message::Token(token))));
11601161
}).expect("failed to spawn helper thread");
11611162

11621163
let mut each_linked_rlib_for_lto = Vec::new();
@@ -1430,7 +1431,8 @@ fn start_executing_work(sess: &Session,
14301431
// Relinquish accidentally acquired extra tokens
14311432
tokens.truncate(running);
14321433

1433-
match coordinator_receive.recv().unwrap() {
1434+
let msg = coordinator_receive.recv().unwrap();
1435+
match *msg.downcast::<Message>().ok().unwrap() {
14341436
// Save the token locally and the next turn of the loop will use
14351437
// this to spawn a new unit of work, or it may get dropped
14361438
// immediately if we have no more work to spawn.
@@ -1588,7 +1590,7 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
15881590
// Set up a destructor which will fire off a message that we're done as
15891591
// we exit.
15901592
struct Bomb {
1591-
coordinator_send: Sender<Message>,
1593+
coordinator_send: Sender<Box<Any + Send>>,
15921594
result: Option<CompiledModule>,
15931595
worker_id: usize,
15941596
}
@@ -1599,10 +1601,10 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
15991601
None => Err(())
16001602
};
16011603

1602-
drop(self.coordinator_send.send(Message::Done {
1604+
drop(self.coordinator_send.send(Box::new(Message::Done {
16031605
result,
16041606
worker_id: self.worker_id,
1605-
}));
1607+
})));
16061608
}
16071609
}
16081610

@@ -1845,7 +1847,7 @@ pub struct OngoingCrateTranslation {
18451847
allocator_module_config: ModuleConfig,
18461848

18471849
time_graph: Option<TimeGraph>,
1848-
coordinator_send: Sender<Message>,
1850+
coordinator_send: Sender<Box<Any + Send>>,
18491851
trans_worker_receive: Receiver<Message>,
18501852
shared_emitter_main: SharedEmitterMain,
18511853
future: thread::JoinHandle<CompiledModules>,
@@ -1931,11 +1933,11 @@ impl OngoingCrateTranslation {
19311933
module_config,
19321934
self.output_filenames.clone());
19331935

1934-
drop(self.coordinator_send.send(Message::TranslationDone {
1936+
drop(self.coordinator_send.send(Box::new(Message::TranslationDone {
19351937
llvm_work_item,
19361938
cost,
19371939
is_last
1938-
}));
1940+
})));
19391941
}
19401942

19411943
pub fn submit_pre_translated_module_to_llvm(&self,

src/librustc_trans/base.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@ use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet};
7979
use CrateInfo;
8080

8181
use libc::c_uint;
82+
use std::any::Any;
8283
use std::ffi::{CStr, CString};
8384
use std::str;
8485
use std::sync::Arc;
8586
use std::time::{Instant, Duration};
8687
use std::i32;
88+
use std::sync::mpsc;
8789
use syntax_pos::Span;
8890
use syntax::attr;
8991
use rustc::hir;
@@ -933,6 +935,7 @@ pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet {
933935

934936
pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
935937
incremental_hashes_map: IncrementalHashesMap,
938+
rx: mpsc::Receiver<Box<Any + Send>>,
936939
output_filenames: &OutputFilenames)
937940
-> OngoingCrateTranslation {
938941
check_for_rustc_errors_attr(tcx);
@@ -974,7 +977,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
974977
output_filenames,
975978
time_graph.clone(),
976979
link_meta,
977-
metadata);
980+
metadata,
981+
rx);
978982

979983
ongoing_translation.submit_pre_translated_module_to_llvm(tcx.sess, metadata_module, true);
980984

@@ -1001,7 +1005,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10011005
output_filenames,
10021006
time_graph.clone(),
10031007
link_meta,
1004-
metadata);
1008+
metadata,
1009+
rx);
10051010

10061011
// Translate an allocator shim, if any
10071012
//

0 commit comments

Comments
 (0)