]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/back/write.rs
rustdoc: pretty-print Unevaluated expressions in types.
[rust.git] / src / librustc_trans / back / write.rs
1 // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use back::lto;
12 use back::link::{self, get_linker, remove};
13 use back::linker::LinkerInfo;
14 use back::symbol_export::ExportedSymbols;
15 use rustc_incremental::{save_trans_partition, in_incr_comp_dir};
16 use rustc::middle::cstore::{LinkMeta, EncodedMetadata};
17 use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Passes, SomePasses,
18                              AllPasses, Sanitizer};
19 use rustc::session::Session;
20 use time_graph::{self, TimeGraph};
21 use llvm;
22 use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
23 use llvm::SMDiagnosticRef;
24 use {CrateTranslation, ModuleSource, ModuleTranslation, CompiledModule, ModuleKind};
25 use CrateInfo;
26 use rustc::hir::def_id::CrateNum;
27 use rustc::util::common::{time, time_depth, set_time_depth, path2cstr, print_time_passes_entry};
28 use rustc::util::fs::{link_or_copy, rename_or_copy_remove};
29 use errors::{self, Handler, Level, DiagnosticBuilder, FatalError};
30 use errors::emitter::{Emitter};
31 use syntax::ext::hygiene::Mark;
32 use syntax_pos::MultiSpan;
33 use syntax_pos::symbol::Symbol;
34 use context::{is_pie_binary, get_reloc_model};
35 use jobserver::{Client, Acquired};
36 use rustc_demangle;
37
38 use std::ffi::CString;
39 use std::fmt;
40 use std::fs;
41 use std::io;
42 use std::io::Write;
43 use std::path::{Path, PathBuf};
44 use std::str;
45 use std::sync::Arc;
46 use std::sync::mpsc::{channel, Sender, Receiver};
47 use std::slice;
48 use std::time::Instant;
49 use std::thread;
50 use libc::{c_uint, c_void, c_char, size_t};
51
52 pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [
53     ("pic", llvm::RelocMode::PIC),
54     ("static", llvm::RelocMode::Static),
55     ("default", llvm::RelocMode::Default),
56     ("dynamic-no-pic", llvm::RelocMode::DynamicNoPic),
57     ("ropi", llvm::RelocMode::ROPI),
58     ("rwpi", llvm::RelocMode::RWPI),
59     ("ropi-rwpi", llvm::RelocMode::ROPI_RWPI),
60 ];
61
62 pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [
63     ("default", llvm::CodeModel::Default),
64     ("small", llvm::CodeModel::Small),
65     ("kernel", llvm::CodeModel::Kernel),
66     ("medium", llvm::CodeModel::Medium),
67     ("large", llvm::CodeModel::Large),
68 ];
69
70 pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
71     match llvm::last_error() {
72         Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
73         None => handler.fatal(&msg),
74     }
75 }
76
77 pub fn write_output_file(
78         handler: &errors::Handler,
79         target: llvm::TargetMachineRef,
80         pm: llvm::PassManagerRef,
81         m: ModuleRef,
82         output: &Path,
83         file_type: llvm::FileType) -> Result<(), FatalError> {
84     unsafe {
85         let output_c = path2cstr(output);
86         let result = llvm::LLVMRustWriteOutputFile(
87                 target, pm, m, output_c.as_ptr(), file_type);
88         if result.into_result().is_err() {
89             let msg = format!("could not write output to {}", output.display());
90             Err(llvm_err(handler, msg))
91         } else {
92             Ok(())
93         }
94     }
95 }
96
97 // On android, we by default compile for armv7 processors. This enables
98 // things like double word CAS instructions (rather than emulating them)
99 // which are *far* more efficient. This is obviously undesirable in some
100 // cases, so if any sort of target feature is specified we don't append v7
101 // to the feature list.
102 //
103 // On iOS only armv7 and newer are supported. So it is useful to
104 // get all hardware potential via VFP3 (hardware floating point)
105 // and NEON (SIMD) instructions supported by LLVM.
106 // Note that without those flags various linking errors might
107 // arise as some of intrinsics are converted into function calls
108 // and nobody provides implementations those functions
109 fn target_feature(sess: &Session) -> String {
110     let rustc_features = [
111         "crt-static",
112     ];
113     let requested_features = sess.opts.cg.target_feature.split(',');
114     let llvm_features = requested_features.filter(|f| {
115         !rustc_features.iter().any(|s| f.contains(s))
116     });
117     format!("{},{}",
118             sess.target.target.options.features,
119             llvm_features.collect::<Vec<_>>().join(","))
120 }
121
122 fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
123     match optimize {
124       config::OptLevel::No => llvm::CodeGenOptLevel::None,
125       config::OptLevel::Less => llvm::CodeGenOptLevel::Less,
126       config::OptLevel::Default => llvm::CodeGenOptLevel::Default,
127       config::OptLevel::Aggressive => llvm::CodeGenOptLevel::Aggressive,
128       _ => llvm::CodeGenOptLevel::Default,
129     }
130 }
131
132 fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize {
133     match optimize {
134       config::OptLevel::Size => llvm::CodeGenOptSizeDefault,
135       config::OptLevel::SizeMin => llvm::CodeGenOptSizeAggressive,
136       _ => llvm::CodeGenOptSizeNone,
137     }
138 }
139
140 pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
141     let reloc_model = get_reloc_model(sess);
142
143     let opt_level = get_llvm_opt_level(sess.opts.optimize);
144     let use_softfp = sess.opts.cg.soft_float;
145
146     let ffunction_sections = sess.target.target.options.function_sections;
147     let fdata_sections = ffunction_sections;
148
149     let code_model_arg = match sess.opts.cg.code_model {
150         Some(ref s) => &s,
151         None => &sess.target.target.options.code_model,
152     };
153
154     let code_model = match CODE_GEN_MODEL_ARGS.iter().find(
155         |&&arg| arg.0 == code_model_arg) {
156         Some(x) => x.1,
157         _ => {
158             sess.err(&format!("{:?} is not a valid code model",
159                              sess.opts
160                                  .cg
161                                  .code_model));
162             sess.abort_if_errors();
163             bug!();
164         }
165     };
166
167     let triple = &sess.target.target.llvm_target;
168
169     let tm = unsafe {
170         let triple = CString::new(triple.as_bytes()).unwrap();
171         let cpu = match sess.opts.cg.target_cpu {
172             Some(ref s) => &**s,
173             None => &*sess.target.target.options.cpu
174         };
175         let cpu = CString::new(cpu.as_bytes()).unwrap();
176         let features = CString::new(target_feature(sess).as_bytes()).unwrap();
177         llvm::LLVMRustCreateTargetMachine(
178             triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
179             code_model,
180             reloc_model,
181             opt_level,
182             use_softfp,
183             is_pie_binary(sess),
184             ffunction_sections,
185             fdata_sections,
186         )
187     };
188
189     if tm.is_null() {
190         let msg = format!("Could not create LLVM TargetMachine for triple: {}",
191                           triple);
192         panic!(llvm_err(sess.diagnostic(), msg));
193     } else {
194         return tm;
195     };
196 }
197
198
199 /// Module-specific configuration for `optimize_and_codegen`.
200 pub struct ModuleConfig {
201     /// LLVM TargetMachine to use for codegen.
202     tm: TargetMachineRef,
203     /// Names of additional optimization passes to run.
204     passes: Vec<String>,
205     /// Some(level) to optimize at a certain level, or None to run
206     /// absolutely no optimizations (used for the metadata module).
207     opt_level: Option<llvm::CodeGenOptLevel>,
208
209     /// Some(level) to optimize binary size, or None to not affect program size.
210     opt_size: Option<llvm::CodeGenOptSize>,
211
212     // Flags indicating which outputs to produce.
213     emit_no_opt_bc: bool,
214     emit_bc: bool,
215     emit_lto_bc: bool,
216     emit_ir: bool,
217     emit_asm: bool,
218     emit_obj: bool,
219     // Miscellaneous flags.  These are mostly copied from command-line
220     // options.
221     no_verify: bool,
222     no_prepopulate_passes: bool,
223     no_builtins: bool,
224     time_passes: bool,
225     vectorize_loop: bool,
226     vectorize_slp: bool,
227     merge_functions: bool,
228     inline_threshold: Option<usize>,
229     // Instead of creating an object file by doing LLVM codegen, just
230     // make the object file bitcode. Provides easy compatibility with
231     // emscripten's ecc compiler, when used as the linker.
232     obj_is_bitcode: bool,
233 }
234
235 unsafe impl Send for ModuleConfig { }
236
237 impl ModuleConfig {
238     fn new(sess: &Session, passes: Vec<String>) -> ModuleConfig {
239         ModuleConfig {
240             tm: create_target_machine(sess),
241             passes,
242             opt_level: None,
243             opt_size: None,
244
245             emit_no_opt_bc: false,
246             emit_bc: false,
247             emit_lto_bc: false,
248             emit_ir: false,
249             emit_asm: false,
250             emit_obj: false,
251             obj_is_bitcode: false,
252
253             no_verify: false,
254             no_prepopulate_passes: false,
255             no_builtins: false,
256             time_passes: false,
257             vectorize_loop: false,
258             vectorize_slp: false,
259             merge_functions: false,
260             inline_threshold: None
261         }
262     }
263
264     fn set_flags(&mut self, sess: &Session, no_builtins: bool) {
265         self.no_verify = sess.no_verify();
266         self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
267         self.no_builtins = no_builtins;
268         self.time_passes = sess.time_passes();
269         self.inline_threshold = sess.opts.cg.inline_threshold;
270         self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;
271
272         // Copy what clang does by turning on loop vectorization at O2 and
273         // slp vectorization at O3. Otherwise configure other optimization aspects
274         // of this pass manager builder.
275         // Turn off vectorization for emscripten, as it's not very well supported.
276         self.vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
277                              (sess.opts.optimize == config::OptLevel::Default ||
278                               sess.opts.optimize == config::OptLevel::Aggressive) &&
279                              !sess.target.target.options.is_like_emscripten;
280
281         self.vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
282                             sess.opts.optimize == config::OptLevel::Aggressive &&
283                             !sess.target.target.options.is_like_emscripten;
284
285         self.merge_functions = sess.opts.optimize == config::OptLevel::Default ||
286                                sess.opts.optimize == config::OptLevel::Aggressive;
287     }
288
289     fn clone(&self, sess: &Session) -> ModuleConfig {
290         ModuleConfig {
291             tm: create_target_machine(sess),
292             passes: self.passes.clone(),
293             opt_level: self.opt_level,
294             opt_size: self.opt_size,
295
296             emit_no_opt_bc: self.emit_no_opt_bc,
297             emit_bc: self.emit_bc,
298             emit_lto_bc: self.emit_lto_bc,
299             emit_ir: self.emit_ir,
300             emit_asm: self.emit_asm,
301             emit_obj: self.emit_obj,
302             obj_is_bitcode: self.obj_is_bitcode,
303
304             no_verify: self.no_verify,
305             no_prepopulate_passes: self.no_prepopulate_passes,
306             no_builtins: self.no_builtins,
307             time_passes: self.time_passes,
308             vectorize_loop: self.vectorize_loop,
309             vectorize_slp: self.vectorize_slp,
310             merge_functions: self.merge_functions,
311             inline_threshold: self.inline_threshold,
312         }
313     }
314 }
315
316 impl Drop for ModuleConfig {
317     fn drop(&mut self) {
318         unsafe {
319             llvm::LLVMRustDisposeTargetMachine(self.tm);
320         }
321     }
322 }
323
324 /// Additional resources used by optimize_and_codegen (not module specific)
325 #[derive(Clone)]
326 pub struct CodegenContext {
327     // Resouces needed when running LTO
328     pub time_passes: bool,
329     pub lto: bool,
330     pub no_landing_pads: bool,
331     pub exported_symbols: Arc<ExportedSymbols>,
332     pub opts: Arc<config::Options>,
333     pub crate_types: Vec<config::CrateType>,
334     pub each_linked_rlib_for_lto: Vec<(CrateNum, PathBuf)>,
335     // Handler to use for diagnostics produced during codegen.
336     pub diag_emitter: SharedEmitter,
337     // LLVM passes added by plugins.
338     pub plugin_passes: Vec<String>,
339     // LLVM optimizations for which we want to print remarks.
340     pub remark: Passes,
341     // Worker thread number
342     pub worker: usize,
343     // The incremental compilation session directory, or None if we are not
344     // compiling incrementally
345     pub incr_comp_session_dir: Option<PathBuf>,
346     // Channel back to the main control thread to send messages to
347     coordinator_send: Sender<Message>,
348     // A reference to the TimeGraph so we can register timings. None means that
349     // measuring is disabled.
350     time_graph: Option<TimeGraph>,
351 }
352
353 impl CodegenContext {
354     fn create_diag_handler(&self) -> Handler {
355         Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone()))
356     }
357 }
358
359 struct HandlerFreeVars<'a> {
360     cgcx: &'a CodegenContext,
361     diag_handler: &'a Handler,
362 }
363
364 unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext,
365                                                msg: &'b str,
366                                                cookie: c_uint) {
367     cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string());
368 }
369
370 unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
371                                         user: *const c_void,
372                                         cookie: c_uint) {
373     let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars);
374
375     let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
376         .expect("non-UTF8 SMDiagnostic");
377
378     report_inline_asm(cgcx, &msg, cookie);
379 }
380
381 unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
382     let HandlerFreeVars { cgcx, diag_handler, .. } = *(user as *const HandlerFreeVars);
383
384     match llvm::diagnostic::Diagnostic::unpack(info) {
385         llvm::diagnostic::InlineAsm(inline) => {
386             report_inline_asm(cgcx,
387                               &llvm::twine_to_string(inline.message),
388                               inline.cookie);
389         }
390
391         llvm::diagnostic::Optimization(opt) => {
392             let enabled = match cgcx.remark {
393                 AllPasses => true,
394                 SomePasses(ref v) => v.iter().any(|s| *s == opt.pass_name),
395             };
396
397             if enabled {
398                 diag_handler.note_without_error(&format!("optimization {} for {} at {}:{}:{}: {}",
399                                                 opt.kind.describe(),
400                                                 opt.pass_name,
401                                                 opt.filename,
402                                                 opt.line,
403                                                 opt.column,
404                                                 opt.message));
405             }
406         }
407
408         _ => (),
409     }
410 }
411
412 // Unsafe due to LLVM calls.
413 unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
414                                diag_handler: &Handler,
415                                mtrans: ModuleTranslation,
416                                config: ModuleConfig,
417                                output_names: OutputFilenames)
418     -> Result<CompiledModule, FatalError>
419 {
420     let (llmod, llcx) = match mtrans.source {
421         ModuleSource::Translated(ref llvm) => (llvm.llmod, llvm.llcx),
422         ModuleSource::Preexisting(_) => {
423             bug!("optimize_and_codegen: called with ModuleSource::Preexisting")
424         }
425     };
426
427     let tm = config.tm;
428
429     let fv = HandlerFreeVars {
430         cgcx,
431         diag_handler,
432     };
433     let fv = &fv as *const HandlerFreeVars as *mut c_void;
434
435     llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
436     llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
437
438     let module_name = mtrans.name.clone();
439     let module_name = Some(&module_name[..]);
440
441     if config.emit_no_opt_bc {
442         let out = output_names.temp_path_ext("no-opt.bc", module_name);
443         let out = path2cstr(&out);
444         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
445     }
446
447     if config.opt_level.is_some() {
448         // Create the two optimizing pass managers. These mirror what clang
449         // does, and are by populated by LLVM's default PassManagerBuilder.
450         // Each manager has a different set of passes, but they also share
451         // some common passes.
452         let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod);
453         let mpm = llvm::LLVMCreatePassManager();
454
455         // If we're verifying or linting, add them to the function pass
456         // manager.
457         let addpass = |pass_name: &str| {
458             let pass_name = CString::new(pass_name).unwrap();
459             let pass = llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr());
460             if pass.is_null() {
461                 return false;
462             }
463             let pass_manager = match llvm::LLVMRustPassKind(pass) {
464                 llvm::PassKind::Function => fpm,
465                 llvm::PassKind::Module => mpm,
466                 llvm::PassKind::Other => {
467                     diag_handler.err("Encountered LLVM pass kind we can't handle");
468                     return true
469                 },
470             };
471             llvm::LLVMRustAddPass(pass_manager, pass);
472             true
473         };
474
475         if !config.no_verify { assert!(addpass("verify")); }
476         if !config.no_prepopulate_passes {
477             llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
478             llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
479             with_llvm_pmb(llmod, &config, &mut |b| {
480                 llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
481                 llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
482             })
483         }
484
485         for pass in &config.passes {
486             if !addpass(pass) {
487                 diag_handler.warn(&format!("unknown pass `{}`, ignoring",
488                                            pass));
489             }
490         }
491
492         for pass in &cgcx.plugin_passes {
493             if !addpass(pass) {
494                 diag_handler.err(&format!("a plugin asked for LLVM pass \
495                                            `{}` but LLVM does not \
496                                            recognize it", pass));
497             }
498         }
499
500         diag_handler.abort_if_errors();
501
502         // Finally, run the actual optimization passes
503         time(config.time_passes, &format!("llvm function passes [{}]", module_name.unwrap()), ||
504              llvm::LLVMRustRunFunctionPassManager(fpm, llmod));
505         time(config.time_passes, &format!("llvm module passes [{}]", module_name.unwrap()), ||
506              llvm::LLVMRunPassManager(mpm, llmod));
507
508         // Deallocate managers that we're now done with
509         llvm::LLVMDisposePassManager(fpm);
510         llvm::LLVMDisposePassManager(mpm);
511
512         if cgcx.lto {
513             time(cgcx.time_passes, "all lto passes", || {
514                 let temp_no_opt_bc_filename =
515                     output_names.temp_path_ext("no-opt.lto.bc", module_name);
516                 lto::run(cgcx,
517                          diag_handler,
518                          llmod,
519                          tm,
520                          &config,
521                          &temp_no_opt_bc_filename)
522             })?;
523             if config.emit_lto_bc {
524                 let out = output_names.temp_path_ext("lto.bc", module_name);
525                 let out = path2cstr(&out);
526                 llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
527             }
528         }
529     }
530
531     // A codegen-specific pass manager is used to generate object
532     // files for an LLVM module.
533     //
534     // Apparently each of these pass managers is a one-shot kind of
535     // thing, so we create a new one for each type of output. The
536     // pass manager passed to the closure should be ensured to not
537     // escape the closure itself, and the manager should only be
538     // used once.
539     unsafe fn with_codegen<F, R>(tm: TargetMachineRef,
540                                  llmod: ModuleRef,
541                                  no_builtins: bool,
542                                  f: F) -> R
543         where F: FnOnce(PassManagerRef) -> R,
544     {
545         let cpm = llvm::LLVMCreatePassManager();
546         llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
547         llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
548         f(cpm)
549     }
550
551     // Change what we write and cleanup based on whether obj files are
552     // just llvm bitcode. In that case write bitcode, and possibly
553     // delete the bitcode if it wasn't requested. Don't generate the
554     // machine code, instead copy the .o file from the .bc
555     let write_bc = config.emit_bc || config.obj_is_bitcode;
556     let rm_bc = !config.emit_bc && config.obj_is_bitcode;
557     let write_obj = config.emit_obj && !config.obj_is_bitcode;
558     let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;
559
560     let bc_out = output_names.temp_path(OutputType::Bitcode, module_name);
561     let obj_out = output_names.temp_path(OutputType::Object, module_name);
562
563     if write_bc {
564         let bc_out_c = path2cstr(&bc_out);
565         llvm::LLVMWriteBitcodeToFile(llmod, bc_out_c.as_ptr());
566     }
567
568     time(config.time_passes, &format!("codegen passes [{}]", module_name.unwrap()),
569          || -> Result<(), FatalError> {
570         if config.emit_ir {
571             let out = output_names.temp_path(OutputType::LlvmAssembly, module_name);
572             let out = path2cstr(&out);
573
574             extern "C" fn demangle_callback(input_ptr: *const c_char,
575                                             input_len: size_t,
576                                             output_ptr: *mut c_char,
577                                             output_len: size_t) -> size_t {
578                 let input = unsafe {
579                     slice::from_raw_parts(input_ptr as *const u8, input_len as usize)
580                 };
581
582                 let input = match str::from_utf8(input) {
583                     Ok(s) => s,
584                     Err(_) => return 0,
585                 };
586
587                 let output = unsafe {
588                     slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
589                 };
590                 let mut cursor = io::Cursor::new(output);
591
592                 let demangled = match rustc_demangle::try_demangle(input) {
593                     Ok(d) => d,
594                     Err(_) => return 0,
595                 };
596
597                 if let Err(_) = write!(cursor, "{:#}", demangled) {
598                     // Possible only if provided buffer is not big enough
599                     return 0;
600                 }
601
602                 cursor.position() as size_t
603             }
604
605             with_codegen(tm, llmod, config.no_builtins, |cpm| {
606                 llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
607                 llvm::LLVMDisposePassManager(cpm);
608             })
609         }
610
611         if config.emit_asm {
612             let path = output_names.temp_path(OutputType::Assembly, module_name);
613
614             // We can't use the same module for asm and binary output, because that triggers
615             // various errors like invalid IR or broken binaries, so we might have to clone the
616             // module to produce the asm output
617             let llmod = if config.emit_obj {
618                 llvm::LLVMCloneModule(llmod)
619             } else {
620                 llmod
621             };
622             with_codegen(tm, llmod, config.no_builtins, |cpm| {
623                 write_output_file(diag_handler, tm, cpm, llmod, &path,
624                                   llvm::FileType::AssemblyFile)
625             })?;
626             if config.emit_obj {
627                 llvm::LLVMDisposeModule(llmod);
628             }
629         }
630
631         if write_obj {
632             with_codegen(tm, llmod, config.no_builtins, |cpm| {
633                 write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
634                                   llvm::FileType::ObjectFile)
635             })?;
636         }
637
638         Ok(())
639     })?;
640
641     if copy_bc_to_obj {
642         debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
643         if let Err(e) = link_or_copy(&bc_out, &obj_out) {
644             diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
645         }
646     }
647
648     if rm_bc {
649         debug!("removing_bitcode {:?}", bc_out);
650         if let Err(e) = fs::remove_file(&bc_out) {
651             diag_handler.err(&format!("failed to remove bitcode: {}", e));
652         }
653     }
654
655     Ok(mtrans.into_compiled_module(config.emit_obj, config.emit_bc))
656 }
657
658 pub struct CompiledModules {
659     pub modules: Vec<CompiledModule>,
660     pub metadata_module: CompiledModule,
661     pub allocator_module: Option<CompiledModule>,
662 }
663
664 fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
665     sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
666     sess.opts.output_types.contains_key(&OutputType::Exe)
667 }
668
669 pub fn start_async_translation(sess: &Session,
670                                crate_output: &OutputFilenames,
671                                time_graph: Option<TimeGraph>,
672                                crate_name: Symbol,
673                                link: LinkMeta,
674                                metadata: EncodedMetadata,
675                                exported_symbols: Arc<ExportedSymbols>,
676                                no_builtins: bool,
677                                windows_subsystem: Option<String>,
678                                linker_info: LinkerInfo,
679                                crate_info: CrateInfo,
680                                no_integrated_as: bool)
681                                -> OngoingCrateTranslation {
682     let output_types_override = if no_integrated_as {
683         OutputTypes::new(&[(OutputType::Assembly, None)])
684     } else {
685         sess.opts.output_types.clone()
686     };
687
688     // Figure out what we actually need to build.
689     let mut modules_config = ModuleConfig::new(sess, sess.opts.cg.passes.clone());
690     let mut metadata_config = ModuleConfig::new(sess, vec![]);
691     let mut allocator_config = ModuleConfig::new(sess, vec![]);
692
693     if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer {
694         match *sanitizer {
695             Sanitizer::Address => {
696                 modules_config.passes.push("asan".to_owned());
697                 modules_config.passes.push("asan-module".to_owned());
698             }
699             Sanitizer::Memory => {
700                 modules_config.passes.push("msan".to_owned())
701             }
702             Sanitizer::Thread => {
703                 modules_config.passes.push("tsan".to_owned())
704             }
705             _ => {}
706         }
707     }
708
709     if sess.opts.debugging_opts.profile {
710         modules_config.passes.push("insert-gcov-profiling".to_owned())
711     }
712
713     modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize));
714     modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize));
715
716     // Save all versions of the bytecode if we're saving our temporaries.
717     if sess.opts.cg.save_temps {
718         modules_config.emit_no_opt_bc = true;
719         modules_config.emit_bc = true;
720         modules_config.emit_lto_bc = true;
721         metadata_config.emit_bc = true;
722         allocator_config.emit_bc = true;
723     }
724
725     // Emit bitcode files for the crate if we're emitting an rlib.
726     // Whenever an rlib is created, the bitcode is inserted into the
727     // archive in order to allow LTO against it.
728     if need_crate_bitcode_for_rlib(sess) {
729         modules_config.emit_bc = true;
730     }
731
732     for output_type in output_types_override.keys() {
733         match *output_type {
734             OutputType::Bitcode => { modules_config.emit_bc = true; }
735             OutputType::LlvmAssembly => { modules_config.emit_ir = true; }
736             OutputType::Assembly => {
737                 modules_config.emit_asm = true;
738                 // If we're not using the LLVM assembler, this function
739                 // could be invoked specially with output_type_assembly, so
740                 // in this case we still want the metadata object file.
741                 if !sess.opts.output_types.contains_key(&OutputType::Assembly) {
742                     metadata_config.emit_obj = true;
743                     allocator_config.emit_obj = true;
744                 }
745             }
746             OutputType::Object => { modules_config.emit_obj = true; }
747             OutputType::Metadata => { metadata_config.emit_obj = true; }
748             OutputType::Exe => {
749                 modules_config.emit_obj = true;
750                 metadata_config.emit_obj = true;
751                 allocator_config.emit_obj = true;
752             },
753             OutputType::Mir => {}
754             OutputType::DepInfo => {}
755         }
756     }
757
758     modules_config.set_flags(sess, no_builtins);
759     metadata_config.set_flags(sess, no_builtins);
760     allocator_config.set_flags(sess, no_builtins);
761
762     // Exclude metadata and allocator modules from time_passes output, since
763     // they throw off the "LLVM passes" measurement.
764     metadata_config.time_passes = false;
765     allocator_config.time_passes = false;
766
767     let client = sess.jobserver_from_env.clone().unwrap_or_else(|| {
768         // Pick a "reasonable maximum" if we don't otherwise have a jobserver in
769         // our environment, capping out at 32 so we don't take everything down
770         // by hogging the process run queue.
771         Client::new(32).expect("failed to create jobserver")
772     });
773
774     let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
775     let (trans_worker_send, trans_worker_receive) = channel();
776     let (coordinator_send, coordinator_receive) = channel();
777
778     let coordinator_thread = start_executing_work(sess,
779                                                   &crate_info,
780                                                   shared_emitter,
781                                                   trans_worker_send,
782                                                   coordinator_send.clone(),
783                                                   coordinator_receive,
784                                                   client,
785                                                   time_graph.clone(),
786                                                   exported_symbols.clone());
787     OngoingCrateTranslation {
788         crate_name,
789         link,
790         metadata,
791         windows_subsystem,
792         linker_info,
793         no_integrated_as,
794         crate_info,
795
796         regular_module_config: modules_config,
797         metadata_module_config: metadata_config,
798         allocator_module_config: allocator_config,
799
800         time_graph,
801         output_filenames: crate_output.clone(),
802         coordinator_send,
803         trans_worker_receive,
804         shared_emitter_main,
805         future: coordinator_thread
806     }
807 }
808
809 fn copy_module_artifacts_into_incr_comp_cache(sess: &Session,
810                                               compiled_modules: &CompiledModules,
811                                               crate_output: &OutputFilenames) {
812     if sess.opts.incremental.is_none() {
813         return;
814     }
815
816     for module in compiled_modules.modules.iter() {
817         let mut files = vec![];
818
819         if module.emit_obj {
820             let path = crate_output.temp_path(OutputType::Object, Some(&module.name));
821             files.push((OutputType::Object, path));
822         }
823
824         if module.emit_bc {
825             let path = crate_output.temp_path(OutputType::Bitcode, Some(&module.name));
826             files.push((OutputType::Bitcode, path));
827         }
828
829         save_trans_partition(sess, &module.name, module.symbol_name_hash, &files);
830     }
831 }
832
833 fn produce_final_output_artifacts(sess: &Session,
834                                   compiled_modules: &CompiledModules,
835                                   crate_output: &OutputFilenames) {
836     let mut user_wants_bitcode = false;
837     let mut user_wants_objects = false;
838
839     // Produce final compile outputs.
840     let copy_gracefully = |from: &Path, to: &Path| {
841         if let Err(e) = fs::copy(from, to) {
842             sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e));
843         }
844     };
845
846     let copy_if_one_unit = |output_type: OutputType,
847                             keep_numbered: bool| {
848         if compiled_modules.modules.len() == 1 {
849             // 1) Only one codegen unit.  In this case it's no difficulty
850             //    to copy `foo.0.x` to `foo.x`.
851             let module_name = Some(&compiled_modules.modules[0].name[..]);
852             let path = crate_output.temp_path(output_type, module_name);
853             copy_gracefully(&path,
854                             &crate_output.path(output_type));
855             if !sess.opts.cg.save_temps && !keep_numbered {
856                 // The user just wants `foo.x`, not `foo.#module-name#.x`.
857                 remove(sess, &path);
858             }
859         } else {
860             let ext = crate_output.temp_path(output_type, None)
861                                   .extension()
862                                   .unwrap()
863                                   .to_str()
864                                   .unwrap()
865                                   .to_owned();
866
867             if crate_output.outputs.contains_key(&output_type) {
868                 // 2) Multiple codegen units, with `--emit foo=some_name`.  We have
869                 //    no good solution for this case, so warn the user.
870                 sess.warn(&format!("ignoring emit path because multiple .{} files \
871                                     were produced", ext));
872             } else if crate_output.single_output_file.is_some() {
873                 // 3) Multiple codegen units, with `-o some_name`.  We have
874                 //    no good solution for this case, so warn the user.
875                 sess.warn(&format!("ignoring -o because multiple .{} files \
876                                     were produced", ext));
877             } else {
878                 // 4) Multiple codegen units, but no explicit name.  We
879                 //    just leave the `foo.0.x` files in place.
880                 // (We don't have to do any work in this case.)
881             }
882         }
883     };
884
885     // Flag to indicate whether the user explicitly requested bitcode.
886     // Otherwise, we produced it only as a temporary output, and will need
887     // to get rid of it.
888     for output_type in crate_output.outputs.keys() {
889         match *output_type {
890             OutputType::Bitcode => {
891                 user_wants_bitcode = true;
892                 // Copy to .bc, but always keep the .0.bc.  There is a later
893                 // check to figure out if we should delete .0.bc files, or keep
894                 // them for making an rlib.
895                 copy_if_one_unit(OutputType::Bitcode, true);
896             }
897             OutputType::LlvmAssembly => {
898                 copy_if_one_unit(OutputType::LlvmAssembly, false);
899             }
900             OutputType::Assembly => {
901                 copy_if_one_unit(OutputType::Assembly, false);
902             }
903             OutputType::Object => {
904                 user_wants_objects = true;
905                 copy_if_one_unit(OutputType::Object, true);
906             }
907             OutputType::Mir |
908             OutputType::Metadata |
909             OutputType::Exe |
910             OutputType::DepInfo => {}
911         }
912     }
913
914     // Clean up unwanted temporary files.
915
916     // We create the following files by default:
917     //  - #crate#.#module-name#.bc
918     //  - #crate#.#module-name#.o
919     //  - #crate#.crate.metadata.bc
920     //  - #crate#.crate.metadata.o
921     //  - #crate#.o (linked from crate.##.o)
922     //  - #crate#.bc (copied from crate.##.bc)
923     // We may create additional files if requested by the user (through
924     // `-C save-temps` or `--emit=` flags).
925
926     if !sess.opts.cg.save_temps {
927         // Remove the temporary .#module-name#.o objects.  If the user didn't
928         // explicitly request bitcode (with --emit=bc), and the bitcode is not
929         // needed for building an rlib, then we must remove .#module-name#.bc as
930         // well.
931
932         // Specific rules for keeping .#module-name#.bc:
933         //  - If we're building an rlib (`needs_crate_bitcode`), then keep
934         //    it.
935         //  - If the user requested bitcode (`user_wants_bitcode`), and
936         //    codegen_units > 1, then keep it.
937         //  - If the user requested bitcode but codegen_units == 1, then we
938         //    can toss .#module-name#.bc because we copied it to .bc earlier.
939         //  - If we're not building an rlib and the user didn't request
940         //    bitcode, then delete .#module-name#.bc.
941         // If you change how this works, also update back::link::link_rlib,
942         // where .#module-name#.bc files are (maybe) deleted after making an
943         // rlib.
944         let needs_crate_bitcode = need_crate_bitcode_for_rlib(sess);
945         let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe);
946
947         let keep_numbered_bitcode = needs_crate_bitcode ||
948                 (user_wants_bitcode && sess.opts.cg.codegen_units > 1);
949
950         let keep_numbered_objects = needs_crate_object ||
951                 (user_wants_objects && sess.opts.cg.codegen_units > 1);
952
953         for module in compiled_modules.modules.iter() {
954             let module_name = Some(&module.name[..]);
955
956             if module.emit_obj && !keep_numbered_objects {
957                 let path = crate_output.temp_path(OutputType::Object, module_name);
958                 remove(sess, &path);
959             }
960
961             if module.emit_bc && !keep_numbered_bitcode {
962                 let path = crate_output.temp_path(OutputType::Bitcode, module_name);
963                 remove(sess, &path);
964             }
965         }
966
967         if compiled_modules.metadata_module.emit_bc && !user_wants_bitcode {
968             let path = crate_output.temp_path(OutputType::Bitcode,
969                                               Some(&compiled_modules.metadata_module.name));
970             remove(sess, &path);
971         }
972
973         if let Some(ref allocator_module) = compiled_modules.allocator_module {
974             if allocator_module.emit_bc && !user_wants_bitcode {
975                 let path = crate_output.temp_path(OutputType::Bitcode,
976                                                   Some(&allocator_module.name));
977                 remove(sess, &path);
978             }
979         }
980     }
981
982     // We leave the following files around by default:
983     //  - #crate#.o
984     //  - #crate#.crate.metadata.o
985     //  - #crate#.bc
986     // These are used in linking steps and will be cleaned up afterward.
987 }
988
989 pub fn dump_incremental_data(trans: &CrateTranslation) {
990     let mut reuse = 0;
991     for mtrans in trans.modules.iter() {
992         if mtrans.pre_existing {
993             reuse += 1;
994         }
995     }
996     eprintln!("incremental: re-using {} out of {} modules", reuse, trans.modules.len());
997 }
998
999 struct WorkItem {
1000     mtrans: ModuleTranslation,
1001     config: ModuleConfig,
1002     output_names: OutputFilenames
1003 }
1004
1005 impl fmt::Debug for WorkItem {
1006     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1007         write!(f, "WorkItem({})", self.mtrans.name)
1008     }
1009 }
1010
1011 fn build_work_item(mtrans: ModuleTranslation,
1012                    config: ModuleConfig,
1013                    output_names: OutputFilenames)
1014                    -> WorkItem
1015 {
1016     WorkItem {
1017         mtrans,
1018         config,
1019         output_names,
1020     }
1021 }
1022
1023 fn execute_work_item(cgcx: &CodegenContext, work_item: WorkItem)
1024     -> Result<CompiledModule, FatalError>
1025 {
1026     let diag_handler = cgcx.create_diag_handler();
1027     let module_name = work_item.mtrans.name.clone();
1028
1029     let pre_existing = match work_item.mtrans.source {
1030         ModuleSource::Translated(_) => None,
1031         ModuleSource::Preexisting(ref wp) => Some(wp.clone()),
1032     };
1033
1034     if let Some(wp) = pre_existing {
1035         let incr_comp_session_dir = cgcx.incr_comp_session_dir
1036                                         .as_ref()
1037                                         .unwrap();
1038         let name = &work_item.mtrans.name;
1039         for (kind, saved_file) in wp.saved_files {
1040             let obj_out = work_item.output_names.temp_path(kind, Some(name));
1041             let source_file = in_incr_comp_dir(&incr_comp_session_dir,
1042                                                &saved_file);
1043             debug!("copying pre-existing module `{}` from {:?} to {}",
1044                    work_item.mtrans.name,
1045                    source_file,
1046                    obj_out.display());
1047             match link_or_copy(&source_file, &obj_out) {
1048                 Ok(_) => { }
1049                 Err(err) => {
1050                     diag_handler.err(&format!("unable to copy {} to {}: {}",
1051                                               source_file.display(),
1052                                               obj_out.display(),
1053                                               err));
1054                 }
1055             }
1056         }
1057
1058         Ok(CompiledModule {
1059             name: module_name,
1060             kind: ModuleKind::Regular,
1061             pre_existing: true,
1062             symbol_name_hash: work_item.mtrans.symbol_name_hash,
1063             emit_bc: work_item.config.emit_bc,
1064             emit_obj: work_item.config.emit_obj,
1065         })
1066     } else {
1067         debug!("llvm-optimizing {:?}", module_name);
1068
1069         unsafe {
1070             optimize_and_codegen(cgcx,
1071                                  &diag_handler,
1072                                  work_item.mtrans,
1073                                  work_item.config,
1074                                  work_item.output_names)
1075         }
1076     }
1077 }
1078
1079 #[derive(Debug)]
1080 enum Message {
1081     Token(io::Result<Acquired>),
1082     Done {
1083         result: Result<CompiledModule, ()>,
1084         worker_id: usize,
1085     },
1086     TranslationDone {
1087         llvm_work_item: WorkItem,
1088         cost: u64,
1089         is_last: bool,
1090     },
1091     TranslateItem,
1092 }
1093
1094 struct Diagnostic {
1095     msg: String,
1096     code: Option<String>,
1097     lvl: Level,
1098 }
1099
1100 #[derive(PartialEq, Clone, Copy, Debug)]
1101 enum MainThreadWorkerState {
1102     Idle,
1103     Translating,
1104     LLVMing,
1105 }
1106
1107 fn start_executing_work(sess: &Session,
1108                         crate_info: &CrateInfo,
1109                         shared_emitter: SharedEmitter,
1110                         trans_worker_send: Sender<Message>,
1111                         coordinator_send: Sender<Message>,
1112                         coordinator_receive: Receiver<Message>,
1113                         jobserver: Client,
1114                         time_graph: Option<TimeGraph>,
1115                         exported_symbols: Arc<ExportedSymbols>)
1116                         -> thread::JoinHandle<CompiledModules> {
1117     // First up, convert our jobserver into a helper thread so we can use normal
1118     // mpsc channels to manage our messages and such. Once we've got the helper
1119     // thread then request `n-1` tokens because all of our work items are ready
1120     // to go.
1121     //
1122     // Note that the `n-1` is here because we ourselves have a token (our
1123     // process) and we'll use that token to execute at least one unit of work.
1124     //
1125     // After we've requested all these tokens then we'll, when we can, get
1126     // tokens on `rx` above which will get managed in the main loop below.
1127     let coordinator_send2 = coordinator_send.clone();
1128     let helper = jobserver.into_helper_thread(move |token| {
1129         drop(coordinator_send2.send(Message::Token(token)));
1130     }).expect("failed to spawn helper thread");
1131
1132     let mut each_linked_rlib_for_lto = Vec::new();
1133     drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| {
1134         if link::ignored_for_lto(crate_info, cnum) {
1135             return
1136         }
1137         each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
1138     }));
1139
1140     let cgcx = CodegenContext {
1141         crate_types: sess.crate_types.borrow().clone(),
1142         each_linked_rlib_for_lto,
1143         lto: sess.lto(),
1144         no_landing_pads: sess.no_landing_pads(),
1145         opts: Arc::new(sess.opts.clone()),
1146         time_passes: sess.time_passes(),
1147         exported_symbols,
1148         plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
1149         remark: sess.opts.cg.remark.clone(),
1150         worker: 0,
1151         incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
1152         coordinator_send,
1153         diag_emitter: shared_emitter.clone(),
1154         time_graph,
1155     };
1156
1157     // This is the "main loop" of parallel work happening for parallel codegen.
1158     // It's here that we manage parallelism, schedule work, and work with
1159     // messages coming from clients.
1160     //
1161     // There are a few environmental pre-conditions that shape how the system
1162     // is set up:
1163     //
1164     // - Error reporting only can happen on the main thread because that's the
1165     //   only place where we have access to the compiler `Session`.
1166     // - LLVM work can be done on any thread.
1167     // - Translation can only happen on the main thread.
1168     // - Each thread doing substantial work most be in possession of a `Token`
1169     //   from the `Jobserver`.
1170     // - The compiler process always holds one `Token`. Any additional `Tokens`
1171     //   have to be requested from the `Jobserver`.
1172     //
1173     // Error Reporting
1174     // ===============
1175     // The error reporting restriction is handled separately from the rest: We
1176     // set up a `SharedEmitter` the holds an open channel to the main thread.
1177     // When an error occurs on any thread, the shared emitter will send the
1178     // error message to the receiver main thread (`SharedEmitterMain`). The
1179     // main thread will periodically query this error message queue and emit
1180     // any error messages it has received. It might even abort compilation if
1181     // has received a fatal error. In this case we rely on all other threads
1182     // being torn down automatically with the main thread.
1183     // Since the main thread will often be busy doing translation work, error
1184     // reporting will be somewhat delayed, since the message queue can only be
1185     // checked in between to work packages.
1186     //
1187     // Work Processing Infrastructure
1188     // ==============================
1189     // The work processing infrastructure knows three major actors:
1190     //
1191     // - the coordinator thread,
1192     // - the main thread, and
1193     // - LLVM worker threads
1194     //
1195     // The coordinator thread is running a message loop. It instructs the main
1196     // thread about what work to do when, and it will spawn off LLVM worker
1197     // threads as open LLVM WorkItems become available.
1198     //
1199     // The job of the main thread is to translate CGUs into LLVM work package
1200     // (since the main thread is the only thread that can do this). The main
1201     // thread will block until it receives a message from the coordinator, upon
1202     // which it will translate one CGU, send it to the coordinator and block
1203     // again. This way the coordinator can control what the main thread is
1204     // doing.
1205     //
1206     // The coordinator keeps a queue of LLVM WorkItems, and when a `Token` is
1207     // available, it will spawn off a new LLVM worker thread and let it process
1208     // that a WorkItem. When a LLVM worker thread is done with its WorkItem,
1209     // it will just shut down, which also frees all resources associated with
1210     // the given LLVM module, and sends a message to the coordinator that the
1211     // has been completed.
1212     //
1213     // Work Scheduling
1214     // ===============
1215     // The scheduler's goal is to minimize the time it takes to complete all
1216     // work there is, however, we also want to keep memory consumption low
1217     // if possible. These two goals are at odds with each other: If memory
1218     // consumption were not an issue, we could just let the main thread produce
1219     // LLVM WorkItems at full speed, assuring maximal utilization of
1220     // Tokens/LLVM worker threads. However, since translation usual is faster
1221     // than LLVM processing, the queue of LLVM WorkItems would fill up and each
1222     // WorkItem potentially holds on to a substantial amount of memory.
1223     //
1224     // So the actual goal is to always produce just enough LLVM WorkItems as
1225     // not to starve our LLVM worker threads. That means, once we have enough
1226     // WorkItems in our queue, we can block the main thread, so it does not
1227     // produce more until we need them.
1228     //
1229     // Doing LLVM Work on the Main Thread
1230     // ----------------------------------
1231     // Since the main thread owns the compiler processes implicit `Token`, it is
1232     // wasteful to keep it blocked without doing any work. Therefore, what we do
1233     // in this case is: We spawn off an additional LLVM worker thread that helps
1234     // reduce the queue. The work it is doing corresponds to the implicit
1235     // `Token`. The coordinator will mark the main thread as being busy with
1236     // LLVM work. (The actual work happens on another OS thread but we just care
1237     // about `Tokens`, not actual threads).
1238     //
1239     // When any LLVM worker thread finishes while the main thread is marked as
1240     // "busy with LLVM work", we can do a little switcheroo: We give the Token
1241     // of the just finished thread to the LLVM worker thread that is working on
1242     // behalf of the main thread's implicit Token, thus freeing up the main
1243     // thread again. The coordinator can then again decide what the main thread
1244     // should do. This allows the coordinator to make decisions at more points
1245     // in time.
1246     //
1247     // Striking a Balance between Throughput and Memory Consumption
1248     // ------------------------------------------------------------
1249     // Since our two goals, (1) use as many Tokens as possible and (2) keep
1250     // memory consumption as low as possible, are in conflict with each other,
1251     // we have to find a trade off between them. Right now, the goal is to keep
1252     // all workers busy, which means that no worker should find the queue empty
1253     // when it is ready to start.
1254     // How do we do achieve this? Good question :) We actually never know how
1255     // many `Tokens` are potentially available so it's hard to say how much to
1256     // fill up the queue before switching the main thread to LLVM work. Also we
1257     // currently don't have a means to estimate how long a running LLVM worker
1258     // will still be busy with it's current WorkItem. However, we know the
1259     // maximal count of available Tokens that makes sense (=the number of CPU
1260     // cores), so we can take a conservative guess. The heuristic we use here
1261     // is implemented in the `queue_full_enough()` function.
1262     //
1263     // Some Background on Jobservers
1264     // -----------------------------
1265     // It's worth also touching on the management of parallelism here. We don't
1266     // want to just spawn a thread per work item because while that's optimal
1267     // parallelism it may overload a system with too many threads or violate our
1268     // configuration for the maximum amount of cpu to use for this process. To
1269     // manage this we use the `jobserver` crate.
1270     //
1271     // Job servers are an artifact of GNU make and are used to manage
1272     // parallelism between processes. A jobserver is a glorified IPC semaphore
1273     // basically. Whenever we want to run some work we acquire the semaphore,
1274     // and whenever we're done with that work we release the semaphore. In this
1275     // manner we can ensure that the maximum number of parallel workers is
1276     // capped at any one point in time.
1277     return thread::spawn(move || {
1278         // We pretend to be within the top-level LLVM time-passes task here:
1279         set_time_depth(1);
1280
1281         let max_workers = ::num_cpus::get();
1282         let mut worker_id_counter = 0;
1283         let mut free_worker_ids = Vec::new();
1284         let mut get_worker_id = |free_worker_ids: &mut Vec<usize>| {
1285             if let Some(id) = free_worker_ids.pop() {
1286                 id
1287             } else {
1288                 let id = worker_id_counter;
1289                 worker_id_counter += 1;
1290                 id
1291             }
1292         };
1293
1294         // This is where we collect codegen units that have gone all the way
1295         // through translation and LLVM.
1296         let mut compiled_modules = vec![];
1297         let mut compiled_metadata_module = None;
1298         let mut compiled_allocator_module = None;
1299
1300         // This flag tracks whether all items have gone through translations
1301         let mut translation_done = false;
1302
1303         // This is the queue of LLVM work items that still need processing.
1304         let mut work_items = Vec::new();
1305
1306         // This are the Jobserver Tokens we currently hold. Does not include
1307         // the implicit Token the compiler process owns no matter what.
1308         let mut tokens = Vec::new();
1309
1310         let mut main_thread_worker_state = MainThreadWorkerState::Idle;
1311         let mut running = 0;
1312
1313         let mut llvm_start_time = None;
1314
1315         // Run the message loop while there's still anything that needs message
1316         // processing:
1317         while !translation_done ||
1318               work_items.len() > 0 ||
1319               running > 0 ||
1320               main_thread_worker_state != MainThreadWorkerState::Idle {
1321
1322             // While there are still CGUs to be translated, the coordinator has
1323             // to decide how to utilize the compiler processes implicit Token:
1324             // For translating more CGU or for running them through LLVM.
1325             if !translation_done {
1326                 if main_thread_worker_state == MainThreadWorkerState::Idle {
1327                     if !queue_full_enough(work_items.len(), running, max_workers) {
1328                         // The queue is not full enough, translate more items:
1329                         if let Err(_) = trans_worker_send.send(Message::TranslateItem) {
1330                             panic!("Could not send Message::TranslateItem to main thread")
1331                         }
1332                         main_thread_worker_state = MainThreadWorkerState::Translating;
1333                     } else {
1334                         // The queue is full enough to not let the worker
1335                         // threads starve. Use the implicit Token to do some
1336                         // LLVM work too.
1337                         let (item, _) = work_items.pop()
1338                             .expect("queue empty - queue_full_enough() broken?");
1339                         let cgcx = CodegenContext {
1340                             worker: get_worker_id(&mut free_worker_ids),
1341                             .. cgcx.clone()
1342                         };
1343                         maybe_start_llvm_timer(&item, &mut llvm_start_time);
1344                         main_thread_worker_state = MainThreadWorkerState::LLVMing;
1345                         spawn_work(cgcx, item);
1346                     }
1347                 }
1348             } else {
1349                 // In this branch, we know that everything has been translated,
1350                 // so it's just a matter of determining whether the implicit
1351                 // Token is free to use for LLVM work.
1352                 match main_thread_worker_state {
1353                     MainThreadWorkerState::Idle => {
1354                         if let Some((item, _)) = work_items.pop() {
1355                             let cgcx = CodegenContext {
1356                                 worker: get_worker_id(&mut free_worker_ids),
1357                                 .. cgcx.clone()
1358                             };
1359                             maybe_start_llvm_timer(&item, &mut llvm_start_time);
1360                             main_thread_worker_state = MainThreadWorkerState::LLVMing;
1361                             spawn_work(cgcx, item);
1362                         } else {
1363                             // There is no unstarted work, so let the main thread
1364                             // take over for a running worker. Otherwise the
1365                             // implicit token would just go to waste.
1366                             // We reduce the `running` counter by one. The
1367                             // `tokens.truncate()` below will take care of
1368                             // giving the Token back.
1369                             debug_assert!(running > 0);
1370                             running -= 1;
1371                             main_thread_worker_state = MainThreadWorkerState::LLVMing;
1372                         }
1373                     }
1374                     MainThreadWorkerState::Translating => {
1375                         bug!("trans worker should not be translating after \
1376                               translation was already completed")
1377                     }
1378                     MainThreadWorkerState::LLVMing => {
1379                         // Already making good use of that token
1380                     }
1381                 }
1382             }
1383
1384             // Spin up what work we can, only doing this while we've got available
1385             // parallelism slots and work left to spawn.
1386             while work_items.len() > 0 && running < tokens.len() {
1387                 let (item, _) = work_items.pop().unwrap();
1388
1389                 maybe_start_llvm_timer(&item, &mut llvm_start_time);
1390
1391                 let cgcx = CodegenContext {
1392                     worker: get_worker_id(&mut free_worker_ids),
1393                     .. cgcx.clone()
1394                 };
1395
1396                 spawn_work(cgcx, item);
1397                 running += 1;
1398             }
1399
1400             // Relinquish accidentally acquired extra tokens
1401             tokens.truncate(running);
1402
1403             match coordinator_receive.recv().unwrap() {
1404                 // Save the token locally and the next turn of the loop will use
1405                 // this to spawn a new unit of work, or it may get dropped
1406                 // immediately if we have no more work to spawn.
1407                 Message::Token(token) => {
1408                     match token {
1409                         Ok(token) => {
1410                             tokens.push(token);
1411
1412                             if main_thread_worker_state == MainThreadWorkerState::LLVMing {
1413                                 // If the main thread token is used for LLVM work
1414                                 // at the moment, we turn that thread into a regular
1415                                 // LLVM worker thread, so the main thread is free
1416                                 // to react to translation demand.
1417                                 main_thread_worker_state = MainThreadWorkerState::Idle;
1418                                 running += 1;
1419                             }
1420                         }
1421                         Err(e) => {
1422                             let msg = &format!("failed to acquire jobserver token: {}", e);
1423                             shared_emitter.fatal(msg);
1424                             // Exit the coordinator thread
1425                             panic!("{}", msg)
1426                         }
1427                     }
1428                 }
1429
1430                 Message::TranslationDone { llvm_work_item, cost, is_last } => {
1431                     // We keep the queue sorted by estimated processing cost,
1432                     // so that more expensive items are processed earlier. This
1433                     // is good for throughput as it gives the main thread more
1434                     // time to fill up the queue and it avoids scheduling
1435                     // expensive items to the end.
1436                     // Note, however, that this is not ideal for memory
1437                     // consumption, as LLVM module sizes are not evenly
1438                     // distributed.
1439                     let insertion_index =
1440                         work_items.binary_search_by_key(&cost, |&(_, cost)| cost);
1441                     let insertion_index = match insertion_index {
1442                         Ok(idx) | Err(idx) => idx
1443                     };
1444                     work_items.insert(insertion_index, (llvm_work_item, cost));
1445
1446                     if is_last {
1447                         // If this is the last, don't request a token because
1448                         // the trans worker thread will be free to handle this
1449                         // immediately.
1450                         translation_done = true;
1451                     } else {
1452                         helper.request_token();
1453                     }
1454
1455                     assert_eq!(main_thread_worker_state,
1456                                MainThreadWorkerState::Translating);
1457                     main_thread_worker_state = MainThreadWorkerState::Idle;
1458                 }
1459
1460                 // If a thread exits successfully then we drop a token associated
1461                 // with that worker and update our `running` count. We may later
1462                 // re-acquire a token to continue running more work. We may also not
1463                 // actually drop a token here if the worker was running with an
1464                 // "ephemeral token"
1465                 //
1466                 // Note that if the thread failed that means it panicked, so we
1467                 // abort immediately.
1468                 Message::Done { result: Ok(compiled_module), worker_id } => {
1469                     if main_thread_worker_state == MainThreadWorkerState::LLVMing {
1470                         main_thread_worker_state = MainThreadWorkerState::Idle;
1471                     } else {
1472                         running -= 1;
1473                     }
1474
1475                     free_worker_ids.push(worker_id);
1476
1477                     match compiled_module.kind {
1478                         ModuleKind::Regular => {
1479                             compiled_modules.push(compiled_module);
1480                         }
1481                         ModuleKind::Metadata => {
1482                             assert!(compiled_metadata_module.is_none());
1483                             compiled_metadata_module = Some(compiled_module);
1484                         }
1485                         ModuleKind::Allocator => {
1486                             assert!(compiled_allocator_module.is_none());
1487                             compiled_allocator_module = Some(compiled_module);
1488                         }
1489                     }
1490                 }
1491                 Message::Done { result: Err(()), worker_id: _ } => {
1492                     shared_emitter.fatal("aborting due to worker thread panic");
1493                     // Exit the coordinator thread
1494                     panic!("aborting due to worker thread panic")
1495                 }
1496                 Message::TranslateItem => {
1497                     bug!("the coordinator should not receive translation requests")
1498                 }
1499             }
1500         }
1501
1502         if let Some(llvm_start_time) = llvm_start_time {
1503             let total_llvm_time = Instant::now().duration_since(llvm_start_time);
1504             // This is the top-level timing for all of LLVM, set the time-depth
1505             // to zero.
1506             set_time_depth(0);
1507             print_time_passes_entry(cgcx.time_passes,
1508                                     "LLVM passes",
1509                                     total_llvm_time);
1510         }
1511
1512         let compiled_metadata_module = compiled_metadata_module
1513             .expect("Metadata module not compiled?");
1514
1515         CompiledModules {
1516             modules: compiled_modules,
1517             metadata_module: compiled_metadata_module,
1518             allocator_module: compiled_allocator_module,
1519         }
1520     });
1521
1522     // A heuristic that determines if we have enough LLVM WorkItems in the
1523     // queue so that the main thread can do LLVM work instead of translation
1524     fn queue_full_enough(items_in_queue: usize,
1525                          workers_running: usize,
1526                          max_workers: usize) -> bool {
1527         // Tune me, plz.
1528         items_in_queue > 0 &&
1529         items_in_queue >= max_workers.saturating_sub(workers_running / 2)
1530     }
1531
1532     fn maybe_start_llvm_timer(work_item: &WorkItem,
1533                               llvm_start_time: &mut Option<Instant>) {
1534         // We keep track of the -Ztime-passes output manually,
1535         // since the closure-based interface does not fit well here.
1536         if work_item.config.time_passes {
1537             if llvm_start_time.is_none() {
1538                 *llvm_start_time = Some(Instant::now());
1539             }
1540         }
1541     }
1542 }
1543
1544 pub const TRANS_WORKER_ID: usize = ::std::usize::MAX;
1545 pub const TRANS_WORKER_TIMELINE: time_graph::TimelineId =
1546     time_graph::TimelineId(TRANS_WORKER_ID);
1547 pub const TRANS_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
1548     time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]);
1549 const LLVM_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
1550     time_graph::WorkPackageKind(&["#7DB67A", "#C6EEC4", "#ACDAAA", "#579354", "#3E6F3C"]);
1551
1552 fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
1553     let depth = time_depth();
1554
1555     thread::spawn(move || {
1556         set_time_depth(depth);
1557
1558         // Set up a destructor which will fire off a message that we're done as
1559         // we exit.
1560         struct Bomb {
1561             coordinator_send: Sender<Message>,
1562             result: Option<CompiledModule>,
1563             worker_id: usize,
1564         }
1565         impl Drop for Bomb {
1566             fn drop(&mut self) {
1567                 let result = match self.result.take() {
1568                     Some(compiled_module) => Ok(compiled_module),
1569                     None => Err(())
1570                 };
1571
1572                 drop(self.coordinator_send.send(Message::Done {
1573                     result,
1574                     worker_id: self.worker_id,
1575                 }));
1576             }
1577         }
1578
1579         let mut bomb = Bomb {
1580             coordinator_send: cgcx.coordinator_send.clone(),
1581             result: None,
1582             worker_id: cgcx.worker,
1583         };
1584
1585         // Execute the work itself, and if it finishes successfully then flag
1586         // ourselves as a success as well.
1587         //
1588         // Note that we ignore the result coming out of `execute_work_item`
1589         // which will tell us if the worker failed with a `FatalError`. If that
1590         // has happened, however, then a diagnostic was sent off to the main
1591         // thread, along with an `AbortIfErrors` message. In that case the main
1592         // thread is already exiting anyway most likely.
1593         //
1594         // In any case, there's no need for us to take further action here, so
1595         // we just ignore the result and then send off our message saying that
1596         // we're done, which if `execute_work_item` failed is unlikely to be
1597         // seen by the main thread, but hey we might as well try anyway.
1598         bomb.result = {
1599             let _timing_guard = cgcx.time_graph
1600                                 .as_ref()
1601                                 .map(|tg| tg.start(time_graph::TimelineId(cgcx.worker),
1602                                                    LLVM_WORK_PACKAGE_KIND));
1603             Some(execute_work_item(&cgcx, work).unwrap())
1604         };
1605     });
1606 }
1607
1608 pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
1609     let (pname, mut cmd, _) = get_linker(sess);
1610
1611     for arg in &sess.target.target.options.asm_args {
1612         cmd.arg(arg);
1613     }
1614
1615     cmd.arg("-c").arg("-o").arg(&outputs.path(OutputType::Object))
1616                            .arg(&outputs.temp_path(OutputType::Assembly, None));
1617     debug!("{:?}", cmd);
1618
1619     match cmd.output() {
1620         Ok(prog) => {
1621             if !prog.status.success() {
1622                 let mut note = prog.stderr.clone();
1623                 note.extend_from_slice(&prog.stdout);
1624
1625                 sess.struct_err(&format!("linking with `{}` failed: {}",
1626                                          pname,
1627                                          prog.status))
1628                     .note(&format!("{:?}", &cmd))
1629                     .note(str::from_utf8(&note[..]).unwrap())
1630                     .emit();
1631                 sess.abort_if_errors();
1632             }
1633         },
1634         Err(e) => {
1635             sess.err(&format!("could not exec the linker `{}`: {}", pname, e));
1636             sess.abort_if_errors();
1637         }
1638     }
1639 }
1640
1641 pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
1642                             config: &ModuleConfig,
1643                             f: &mut FnMut(llvm::PassManagerBuilderRef)) {
1644     // Create the PassManagerBuilder for LLVM. We configure it with
1645     // reasonable defaults and prepare it to actually populate the pass
1646     // manager.
1647     let builder = llvm::LLVMPassManagerBuilderCreate();
1648     let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
1649     let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
1650     let inline_threshold = config.inline_threshold;
1651
1652     llvm::LLVMRustConfigurePassManagerBuilder(builder, opt_level,
1653                                               config.merge_functions,
1654                                               config.vectorize_slp,
1655                                               config.vectorize_loop);
1656     llvm::LLVMPassManagerBuilderSetSizeLevel(builder, opt_size as u32);
1657
1658     if opt_size != llvm::CodeGenOptSizeNone {
1659         llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(builder, 1);
1660     }
1661
1662     llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
1663
1664     // Here we match what clang does (kinda). For O0 we only inline
1665     // always-inline functions (but don't add lifetime intrinsics), at O1 we
1666     // inline with lifetime intrinsics, and O2+ we add an inliner with a
1667     // thresholds copied from clang.
1668     match (opt_level, opt_size, inline_threshold) {
1669         (.., Some(t)) => {
1670             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
1671         }
1672         (llvm::CodeGenOptLevel::Aggressive, ..) => {
1673             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
1674         }
1675         (_, llvm::CodeGenOptSizeDefault, _) => {
1676             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 75);
1677         }
1678         (_, llvm::CodeGenOptSizeAggressive, _) => {
1679             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25);
1680         }
1681         (llvm::CodeGenOptLevel::None, ..) => {
1682             llvm::LLVMRustAddAlwaysInlinePass(builder, false);
1683         }
1684         (llvm::CodeGenOptLevel::Less, ..) => {
1685             llvm::LLVMRustAddAlwaysInlinePass(builder, true);
1686         }
1687         (llvm::CodeGenOptLevel::Default, ..) => {
1688             llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
1689         }
1690         (llvm::CodeGenOptLevel::Other, ..) => {
1691             bug!("CodeGenOptLevel::Other selected")
1692         }
1693     }
1694
1695     f(builder);
1696     llvm::LLVMPassManagerBuilderDispose(builder);
1697 }
1698
1699
1700 enum SharedEmitterMessage {
1701     Diagnostic(Diagnostic),
1702     InlineAsmError(u32, String),
1703     AbortIfErrors,
1704     Fatal(String),
1705 }
1706
1707 #[derive(Clone)]
1708 pub struct SharedEmitter {
1709     sender: Sender<SharedEmitterMessage>,
1710 }
1711
1712 pub struct SharedEmitterMain {
1713     receiver: Receiver<SharedEmitterMessage>,
1714 }
1715
1716 impl SharedEmitter {
1717     pub fn new() -> (SharedEmitter, SharedEmitterMain) {
1718         let (sender, receiver) = channel();
1719
1720         (SharedEmitter { sender }, SharedEmitterMain { receiver })
1721     }
1722
1723     fn inline_asm_error(&self, cookie: u32, msg: String) {
1724         drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg)));
1725     }
1726
1727     fn fatal(&self, msg: &str) {
1728         drop(self.sender.send(SharedEmitterMessage::Fatal(msg.to_string())));
1729     }
1730 }
1731
1732 impl Emitter for SharedEmitter {
1733     fn emit(&mut self, db: &DiagnosticBuilder) {
1734         drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
1735             msg: db.message(),
1736             code: db.code.clone(),
1737             lvl: db.level,
1738         })));
1739         for child in &db.children {
1740             drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
1741                 msg: child.message(),
1742                 code: None,
1743                 lvl: child.level,
1744             })));
1745         }
1746         drop(self.sender.send(SharedEmitterMessage::AbortIfErrors));
1747     }
1748 }
1749
1750 impl SharedEmitterMain {
1751     pub fn check(&self, sess: &Session, blocking: bool) {
1752         loop {
1753             let message = if blocking {
1754                 match self.receiver.recv() {
1755                     Ok(message) => Ok(message),
1756                     Err(_) => Err(()),
1757                 }
1758             } else {
1759                 match self.receiver.try_recv() {
1760                     Ok(message) => Ok(message),
1761                     Err(_) => Err(()),
1762                 }
1763             };
1764
1765             match message {
1766                 Ok(SharedEmitterMessage::Diagnostic(diag)) => {
1767                     let handler = sess.diagnostic();
1768                     match diag.code {
1769                         Some(ref code) => {
1770                             handler.emit_with_code(&MultiSpan::new(),
1771                                                    &diag.msg,
1772                                                    &code,
1773                                                    diag.lvl);
1774                         }
1775                         None => {
1776                             handler.emit(&MultiSpan::new(),
1777                                          &diag.msg,
1778                                          diag.lvl);
1779                         }
1780                     }
1781                 }
1782                 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => {
1783                     match Mark::from_u32(cookie).expn_info() {
1784                         Some(ei) => sess.span_err(ei.call_site, &msg),
1785                         None     => sess.err(&msg),
1786                     }
1787                 }
1788                 Ok(SharedEmitterMessage::AbortIfErrors) => {
1789                     sess.abort_if_errors();
1790                 }
1791                 Ok(SharedEmitterMessage::Fatal(msg)) => {
1792                     sess.fatal(&msg);
1793                 }
1794                 Err(_) => {
1795                     break;
1796                 }
1797             }
1798
1799         }
1800     }
1801 }
1802
1803 pub struct OngoingCrateTranslation {
1804     crate_name: Symbol,
1805     link: LinkMeta,
1806     metadata: EncodedMetadata,
1807     windows_subsystem: Option<String>,
1808     linker_info: LinkerInfo,
1809     no_integrated_as: bool,
1810     crate_info: CrateInfo,
1811
1812     output_filenames: OutputFilenames,
1813     regular_module_config: ModuleConfig,
1814     metadata_module_config: ModuleConfig,
1815     allocator_module_config: ModuleConfig,
1816
1817     time_graph: Option<TimeGraph>,
1818     coordinator_send: Sender<Message>,
1819     trans_worker_receive: Receiver<Message>,
1820     shared_emitter_main: SharedEmitterMain,
1821     future: thread::JoinHandle<CompiledModules>,
1822 }
1823
1824 impl OngoingCrateTranslation {
1825     pub fn join(self, sess: &Session) -> CrateTranslation {
1826         self.shared_emitter_main.check(sess, true);
1827         let compiled_modules = match self.future.join() {
1828             Ok(compiled_modules) => compiled_modules,
1829             Err(_) => {
1830                 sess.fatal("Error during translation/LLVM phase.");
1831             }
1832         };
1833
1834         sess.abort_if_errors();
1835
1836         if let Some(time_graph) = self.time_graph {
1837             time_graph.dump(&format!("{}-timings", self.crate_name));
1838         }
1839
1840         copy_module_artifacts_into_incr_comp_cache(sess,
1841                                                    &compiled_modules,
1842                                                    &self.output_filenames);
1843         produce_final_output_artifacts(sess,
1844                                        &compiled_modules,
1845                                        &self.output_filenames);
1846
1847         // FIXME: time_llvm_passes support - does this use a global context or
1848         // something?
1849         if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
1850             unsafe { llvm::LLVMRustPrintPassTimings(); }
1851         }
1852
1853         let trans = CrateTranslation {
1854             crate_name: self.crate_name,
1855             link: self.link,
1856             metadata: self.metadata,
1857             windows_subsystem: self.windows_subsystem,
1858             linker_info: self.linker_info,
1859             crate_info: self.crate_info,
1860
1861             modules: compiled_modules.modules,
1862             allocator_module: compiled_modules.allocator_module,
1863         };
1864
1865         if self.no_integrated_as {
1866             run_assembler(sess,  &self.output_filenames);
1867
1868             // HACK the linker expects the object file to be named foo.0.o but
1869             // `run_assembler` produces an object named just foo.o. Rename it if we
1870             // are going to build an executable
1871             if sess.opts.output_types.contains_key(&OutputType::Exe) {
1872                 let f =  self.output_filenames.path(OutputType::Object);
1873                 rename_or_copy_remove(&f,
1874                     f.with_file_name(format!("{}.0.o",
1875                                              f.file_stem().unwrap().to_string_lossy()))).unwrap();
1876             }
1877
1878             // Remove assembly source, unless --save-temps was specified
1879             if !sess.opts.cg.save_temps {
1880                 fs::remove_file(&self.output_filenames
1881                                      .temp_path(OutputType::Assembly, None)).unwrap();
1882             }
1883         }
1884
1885         trans
1886     }
1887
1888     pub fn submit_translated_module_to_llvm(&self,
1889                                             sess: &Session,
1890                                             mtrans: ModuleTranslation,
1891                                             cost: u64,
1892                                             is_last: bool) {
1893         let module_config = match mtrans.kind {
1894             ModuleKind::Regular => self.regular_module_config.clone(sess),
1895             ModuleKind::Metadata => self.metadata_module_config.clone(sess),
1896             ModuleKind::Allocator => self.allocator_module_config.clone(sess),
1897         };
1898
1899         let llvm_work_item = build_work_item(mtrans,
1900                                              module_config,
1901                                              self.output_filenames.clone());
1902
1903         drop(self.coordinator_send.send(Message::TranslationDone {
1904             llvm_work_item,
1905             cost,
1906             is_last
1907         }));
1908     }
1909
1910     pub fn submit_pre_translated_module_to_llvm(&self,
1911                                                 sess: &Session,
1912                                                 mtrans: ModuleTranslation,
1913                                                 is_last: bool) {
1914         self.wait_for_signal_to_translate_item();
1915         self.check_for_errors(sess);
1916
1917         // These are generally cheap and won't through off scheduling.
1918         let cost = 0;
1919         self.submit_translated_module_to_llvm(sess, mtrans, cost, is_last);
1920     }
1921
1922     pub fn check_for_errors(&self, sess: &Session) {
1923         self.shared_emitter_main.check(sess, false);
1924     }
1925
1926     pub fn wait_for_signal_to_translate_item(&self) {
1927         match self.trans_worker_receive.recv() {
1928             Ok(Message::TranslateItem) => {
1929                 // Nothing to do
1930             }
1931             Ok(message) => {
1932                 panic!("unexpected message: {:?}", message)
1933             }
1934             Err(_) => {
1935                 // One of the LLVM threads must have panicked, fall through so
1936                 // error handling can be reached.
1937             }
1938         }
1939     }
1940 }