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.
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.
12 use back
::link
::{get_cc_prog, remove}
;
13 use session
::config
::{OutputFilenames, Passes, SomePasses, AllPasses}
;
17 use llvm
::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef}
;
18 use llvm
::SMDiagnosticRef
;
19 use trans
::{CrateTranslation, ModuleTranslation}
;
20 use util
::common
::time
;
21 use util
::common
::path2cstr
;
23 use syntax
::diagnostic
;
24 use syntax
::diagnostic
::{Emitter, Handler, Level}
;
26 use std
::ffi
::{CStr, CString}
;
30 use std
::process
::{Command, Stdio}
;
33 use std
::sync
::{Arc, Mutex}
;
34 use std
::sync
::mpsc
::channel
;
36 use libc
::{self, c_uint, c_int, c_void}
;
38 #[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
42 OutputTypeLlvmAssembly
,
47 pub fn llvm_err(handler
: &diagnostic
::Handler
, msg
: String
) -> ! {
49 let cstr
= llvm
::LLVMRustGetLastError();
50 if cstr
== ptr
::null() {
51 handler
.fatal(&msg
[..]);
53 let err
= CStr
::from_ptr(cstr
).to_bytes();
54 let err
= String
::from_utf8_lossy(err
).to_string();
55 libc
::free(cstr
as *mut _
);
56 handler
.fatal(&format
!("{}: {}",
63 pub fn write_output_file(
64 handler
: &diagnostic
::Handler
,
65 target
: llvm
::TargetMachineRef
,
66 pm
: llvm
::PassManagerRef
,
69 file_type
: llvm
::FileType
) {
71 let output_c
= path2cstr(output
);
72 let result
= llvm
::LLVMRustWriteOutputFile(
73 target
, pm
, m
, output_c
.as_ptr(), file_type
);
75 llvm_err(handler
, format
!("could not write output to {}", output
.display()));
87 // We use an Arc instead of just returning a list of diagnostics from the
88 // child thread because we need to make sure that the messages are seen even
89 // if the child thread panics (for example, when `fatal` is called).
91 struct SharedEmitter
{
92 buffer
: Arc
<Mutex
<Vec
<Diagnostic
>>>,
96 fn new() -> SharedEmitter
{
98 buffer
: Arc
::new(Mutex
::new(Vec
::new())),
102 fn dump(&mut self, handler
: &Handler
) {
103 let mut buffer
= self.buffer
.lock().unwrap();
104 for diag
in &*buffer
{
107 handler
.emit_with_code(None
,
123 impl Emitter
for SharedEmitter
{
124 fn emit(&mut self, cmsp
: Option
<(&codemap
::CodeMap
, codemap
::Span
)>,
125 msg
: &str, code
: Option
<&str>, lvl
: Level
) {
126 assert
!(cmsp
.is_none(), "SharedEmitter doesn't support spans");
128 self.buffer
.lock().unwrap().push(Diagnostic
{
129 msg
: msg
.to_string(),
130 code
: code
.map(|s
| s
.to_string()),
135 fn custom_emit(&mut self, _cm
: &codemap
::CodeMap
,
136 _sp
: diagnostic
::RenderSpan
, _msg
: &str, _lvl
: Level
) {
137 panic
!("SharedEmitter doesn't support custom_emit");
142 // On android, we by default compile for armv7 processors. This enables
143 // things like double word CAS instructions (rather than emulating them)
144 // which are *far* more efficient. This is obviously undesirable in some
145 // cases, so if any sort of target feature is specified we don't append v7
146 // to the feature list.
148 // On iOS only armv7 and newer are supported. So it is useful to
149 // get all hardware potential via VFP3 (hardware floating point)
150 // and NEON (SIMD) instructions supported by LLVM.
151 // Note that without those flags various linking errors might
152 // arise as some of intrinsics are converted into function calls
153 // and nobody provides implementations those functions
154 fn target_feature(sess
: &Session
) -> String
{
155 format
!("{},{}", sess
.target
.target
.options
.features
, sess
.opts
.cg
.target_feature
)
158 fn get_llvm_opt_level(optimize
: config
::OptLevel
) -> llvm
::CodeGenOptLevel
{
160 config
::No
=> llvm
::CodeGenLevelNone
,
161 config
::Less
=> llvm
::CodeGenLevelLess
,
162 config
::Default
=> llvm
::CodeGenLevelDefault
,
163 config
::Aggressive
=> llvm
::CodeGenLevelAggressive
,
167 fn create_target_machine(sess
: &Session
) -> TargetMachineRef
{
168 let reloc_model_arg
= match sess
.opts
.cg
.relocation_model
{
169 Some(ref s
) => &s
[..],
170 None
=> &sess
.target
.target
.options
.relocation_model
[..],
172 let reloc_model
= match reloc_model_arg
{
173 "pic" => llvm
::RelocPIC
,
174 "static" => llvm
::RelocStatic
,
175 "default" => llvm
::RelocDefault
,
176 "dynamic-no-pic" => llvm
::RelocDynamicNoPic
,
178 sess
.err(&format
!("{:?} is not a valid relocation mode",
182 sess
.abort_if_errors();
187 let opt_level
= get_llvm_opt_level(sess
.opts
.optimize
);
188 let use_softfp
= sess
.opts
.cg
.soft_float
;
190 let any_library
= sess
.crate_types
.borrow().iter().any(|ty
| {
191 *ty
!= config
::CrateTypeExecutable
194 let ffunction_sections
= sess
.target
.target
.options
.function_sections
;
195 let fdata_sections
= ffunction_sections
;
197 let code_model_arg
= match sess
.opts
.cg
.code_model
{
198 Some(ref s
) => &s
[..],
199 None
=> &sess
.target
.target
.options
.code_model
[..],
202 let code_model
= match code_model_arg
{
203 "default" => llvm
::CodeModelDefault
,
204 "small" => llvm
::CodeModelSmall
,
205 "kernel" => llvm
::CodeModelKernel
,
206 "medium" => llvm
::CodeModelMedium
,
207 "large" => llvm
::CodeModelLarge
,
209 sess
.err(&format
!("{:?} is not a valid code model",
213 sess
.abort_if_errors();
218 let triple
= &sess
.target
.target
.llvm_target
;
221 let triple
= CString
::new(triple
.as_bytes()).unwrap();
222 let cpu
= match sess
.opts
.cg
.target_cpu
{
224 None
=> &*sess
.target
.target
.options
.cpu
226 let cpu
= CString
::new(cpu
.as_bytes()).unwrap();
227 let features
= CString
::new(target_feature(sess
).as_bytes()).unwrap();
228 llvm
::LLVMRustCreateTargetMachine(
229 triple
.as_ptr(), cpu
.as_ptr(), features
.as_ptr(),
233 true /* EnableSegstk */,
235 !any_library
&& reloc_model
== llvm
::RelocPIC
,
242 llvm_err(sess
.diagnostic().handler(),
243 format
!("Could not create LLVM TargetMachine for triple: {}",
244 triple
).to_string());
251 /// Module-specific configuration for `optimize_and_codegen`.
253 struct ModuleConfig
{
254 /// LLVM TargetMachine to use for codegen.
255 tm
: TargetMachineRef
,
256 /// Names of additional optimization passes to run.
258 /// Some(level) to optimize at a certain level, or None to run
259 /// absolutely no optimizations (used for the metadata module).
260 opt_level
: Option
<llvm
::CodeGenOptLevel
>,
262 // Flags indicating which outputs to produce.
263 emit_no_opt_bc
: bool
,
270 // Miscellaneous flags. These are mostly copied from command-line
273 no_prepopulate_passes
: bool
,
276 vectorize_loop
: bool
,
278 merge_functions
: bool
,
281 unsafe impl Send
for ModuleConfig { }
284 fn new(tm
: TargetMachineRef
, passes
: Vec
<String
>) -> ModuleConfig
{
290 emit_no_opt_bc
: false,
298 no_prepopulate_passes
: false,
301 vectorize_loop
: false,
302 vectorize_slp
: false,
303 merge_functions
: false,
307 fn set_flags(&mut self, sess
: &Session
, trans
: &CrateTranslation
) {
308 self.no_verify
= sess
.no_verify();
309 self.no_prepopulate_passes
= sess
.opts
.cg
.no_prepopulate_passes
;
310 self.no_builtins
= trans
.no_builtins
;
311 self.time_passes
= sess
.time_passes();
313 // Copy what clang does by turning on loop vectorization at O2 and
314 // slp vectorization at O3. Otherwise configure other optimization aspects
315 // of this pass manager builder.
316 self.vectorize_loop
= !sess
.opts
.cg
.no_vectorize_loops
&&
317 (sess
.opts
.optimize
== config
::Default
||
318 sess
.opts
.optimize
== config
::Aggressive
);
319 self.vectorize_slp
= !sess
.opts
.cg
.no_vectorize_slp
&&
320 sess
.opts
.optimize
== config
::Aggressive
;
322 self.merge_functions
= sess
.opts
.optimize
== config
::Default
||
323 sess
.opts
.optimize
== config
::Aggressive
;
327 /// Additional resources used by optimize_and_codegen (not module specific)
328 struct CodegenContext
<'a
> {
329 // Extra resources used for LTO: (sess, reachable). This will be `None`
330 // when running in a worker thread.
331 lto_ctxt
: Option
<(&'a Session
, &'a
[String
])>,
332 // Handler to use for diagnostics produced during codegen.
333 handler
: &'a Handler
,
334 // LLVM passes added by plugins.
335 plugin_passes
: Vec
<String
>,
336 // LLVM optimizations for which we want to print remarks.
340 impl<'a
> CodegenContext
<'a
> {
341 fn new_with_session(sess
: &'a Session
, reachable
: &'a
[String
]) -> CodegenContext
<'a
> {
343 lto_ctxt
: Some((sess
, reachable
)),
344 handler
: sess
.diagnostic().handler(),
345 plugin_passes
: sess
.plugin_llvm_passes
.borrow().clone(),
346 remark
: sess
.opts
.cg
.remark
.clone(),
351 struct HandlerFreeVars
<'a
> {
353 cgcx
: &'a CodegenContext
<'a
>,
356 unsafe extern "C" fn report_inline_asm
<'a
, 'b
>(cgcx
: &'a CodegenContext
<'a
>,
359 use syntax
::codemap
::ExpnId
;
361 match cgcx
.lto_ctxt
{
363 sess
.codemap().with_expn_info(ExpnId
::from_u32(cookie
), |info
| match info
{
364 Some(ei
) => sess
.span_err(ei
.call_site
, msg
),
365 None
=> sess
.err(msg
),
370 cgcx
.handler
.err(msg
);
371 cgcx
.handler
.note("build without -C codegen-units for more exact errors");
376 unsafe extern "C" fn inline_asm_handler(diag
: SMDiagnosticRef
,
379 let HandlerFreeVars { cgcx, .. }
380 = *mem
::transmute
::<_
, *const HandlerFreeVars
>(user
);
382 let msg
= llvm
::build_string(|s
| llvm
::LLVMWriteSMDiagnosticToString(diag
, s
))
383 .expect("non-UTF8 SMDiagnostic");
385 report_inline_asm(cgcx
, &msg
[..], cookie
);
388 unsafe extern "C" fn diagnostic_handler(info
: DiagnosticInfoRef
, user
: *mut c_void
) {
389 let HandlerFreeVars { llcx, cgcx }
390 = *mem
::transmute
::<_
, *const HandlerFreeVars
>(user
);
392 match llvm
::diagnostic
::Diagnostic
::unpack(info
) {
393 llvm
::diagnostic
::InlineAsm(inline
) => {
394 report_inline_asm(cgcx
,
395 &*llvm
::twine_to_string(inline
.message
),
399 llvm
::diagnostic
::Optimization(opt
) => {
400 let pass_name
= str::from_utf8(CStr
::from_ptr(opt
.pass_name
).to_bytes())
402 .expect("got a non-UTF8 pass name from LLVM");
403 let enabled
= match cgcx
.remark
{
405 SomePasses(ref v
) => v
.iter().any(|s
| *s
== pass_name
),
409 let loc
= llvm
::debug_loc_to_string(llcx
, opt
.debug_loc
);
410 cgcx
.handler
.note(&format
!("optimization {} for {} at {}: {}",
413 if loc
.is_empty() { "[unknown]" }
else { &*loc }
,
414 llvm
::twine_to_string(opt
.message
)));
422 // Unsafe due to LLVM calls.
423 unsafe fn optimize_and_codegen(cgcx
: &CodegenContext
,
424 mtrans
: ModuleTranslation
,
425 config
: ModuleConfig
,
427 output_names
: OutputFilenames
) {
428 let ModuleTranslation { llmod, llcx }
= mtrans
;
431 // llcx doesn't outlive this function, so we can put this on the stack.
432 let fv
= HandlerFreeVars
{
436 let fv
= &fv
as *const HandlerFreeVars
as *mut c_void
;
438 llvm
::LLVMSetInlineAsmDiagnosticHandler(llcx
, inline_asm_handler
, fv
);
439 llvm
::LLVMContextSetDiagnosticHandler(llcx
, diagnostic_handler
, fv
);
441 if config
.emit_no_opt_bc
{
442 let ext
= format
!("{}.no-opt.bc", name_extra
);
443 let out
= output_names
.with_extension(&ext
);
444 let out
= path2cstr(&out
);
445 llvm
::LLVMWriteBitcodeToFile(llmod
, out
.as_ptr());
448 match config
.opt_level
{
450 // Create the two optimizing pass managers. These mirror what clang
451 // does, and are by populated by LLVM's default PassManagerBuilder.
452 // Each manager has a different set of passes, but they also share
453 // some common passes.
454 let fpm
= llvm
::LLVMCreateFunctionPassManagerForModule(llmod
);
455 let mpm
= llvm
::LLVMCreatePassManager();
457 // If we're verifying or linting, add them to the function pass
459 let addpass
= |pass
: &str| {
460 let pass
= CString
::new(pass
).unwrap();
461 llvm
::LLVMRustAddPass(fpm
, pass
.as_ptr())
464 if !config
.no_verify { assert!(addpass("verify")); }
465 if !config
.no_prepopulate_passes
{
466 llvm
::LLVMRustAddAnalysisPasses(tm
, fpm
, llmod
);
467 llvm
::LLVMRustAddAnalysisPasses(tm
, mpm
, llmod
);
468 populate_llvm_passes(fpm
, mpm
, llmod
, opt_level
, &config
);
471 for pass
in &config
.passes
{
473 cgcx
.handler
.warn(&format
!("unknown pass `{}`, ignoring",
478 for pass
in &cgcx
.plugin_passes
{
480 cgcx
.handler
.err(&format
!("a plugin asked for LLVM pass \
481 `{}` but LLVM does not \
482 recognize it", pass
));
486 cgcx
.handler
.abort_if_errors();
488 // Finally, run the actual optimization passes
489 time(config
.time_passes
, "llvm function passes", (), |()|
490 llvm
::LLVMRustRunFunctionPassManager(fpm
, llmod
));
491 time(config
.time_passes
, "llvm module passes", (), |()|
492 llvm
::LLVMRunPassManager(mpm
, llmod
));
494 // Deallocate managers that we're now done with
495 llvm
::LLVMDisposePassManager(fpm
);
496 llvm
::LLVMDisposePassManager(mpm
);
498 match cgcx
.lto_ctxt
{
499 Some((sess
, reachable
)) if sess
.lto() => {
500 time(sess
.time_passes(), "all lto passes", (), |()|
501 lto
::run(sess
, llmod
, tm
, reachable
));
503 if config
.emit_lto_bc
{
504 let name
= format
!("{}.lto.bc", name_extra
);
505 let out
= output_names
.with_extension(&name
);
506 let out
= path2cstr(&out
);
507 llvm
::LLVMWriteBitcodeToFile(llmod
, out
.as_ptr());
516 // A codegen-specific pass manager is used to generate object
517 // files for an LLVM module.
519 // Apparently each of these pass managers is a one-shot kind of
520 // thing, so we create a new one for each type of output. The
521 // pass manager passed to the closure should be ensured to not
522 // escape the closure itself, and the manager should only be
524 unsafe fn with_codegen
<F
>(tm
: TargetMachineRef
,
528 F
: FnOnce(PassManagerRef
),
530 let cpm
= llvm
::LLVMCreatePassManager();
531 llvm
::LLVMRustAddAnalysisPasses(tm
, cpm
, llmod
);
532 llvm
::LLVMRustAddLibraryInfo(cpm
, llmod
, no_builtins
);
537 let ext
= format
!("{}.bc", name_extra
);
538 let out
= output_names
.with_extension(&ext
);
539 let out
= path2cstr(&out
);
540 llvm
::LLVMWriteBitcodeToFile(llmod
, out
.as_ptr());
543 time(config
.time_passes
, "codegen passes", (), |()| {
545 let ext
= format
!("{}.ll", name_extra
);
546 let out
= output_names
.with_extension(&ext
);
547 let out
= path2cstr(&out
);
548 with_codegen(tm
, llmod
, config
.no_builtins
, |cpm
| {
549 llvm
::LLVMRustPrintModule(cpm
, llmod
, out
.as_ptr());
550 llvm
::LLVMDisposePassManager(cpm
);
555 let path
= output_names
.with_extension(&format
!("{}.s", name_extra
));
556 with_codegen(tm
, llmod
, config
.no_builtins
, |cpm
| {
557 write_output_file(cgcx
.handler
, tm
, cpm
, llmod
, &path
,
558 llvm
::AssemblyFileType
);
563 let path
= output_names
.with_extension(&format
!("{}.o", name_extra
));
564 with_codegen(tm
, llmod
, config
.no_builtins
, |cpm
| {
565 write_output_file(cgcx
.handler
, tm
, cpm
, llmod
, &path
, llvm
::ObjectFileType
);
570 llvm
::LLVMDisposeModule(llmod
);
571 llvm
::LLVMContextDispose(llcx
);
572 llvm
::LLVMRustDisposeTargetMachine(tm
);
575 pub fn run_passes(sess
: &Session
,
576 trans
: &CrateTranslation
,
577 output_types
: &[config
::OutputType
],
578 crate_output
: &OutputFilenames
) {
579 // It's possible that we have `codegen_units > 1` but only one item in
580 // `trans.modules`. We could theoretically proceed and do LTO in that
581 // case, but it would be confusing to have the validity of
582 // `-Z lto -C codegen-units=2` depend on details of the crate being
583 // compiled, so we complain regardless.
584 if sess
.lto() && sess
.opts
.cg
.codegen_units
> 1 {
585 // This case is impossible to handle because LTO expects to be able
586 // to combine the entire crate and all its dependencies into a
587 // single compilation unit, but each codegen unit is in a separate
588 // LLVM context, so they can't easily be combined.
589 sess
.fatal("can't perform LTO when using multiple codegen units");
593 assert
!(trans
.modules
.len() == sess
.opts
.cg
.codegen_units
);
596 configure_llvm(sess
);
599 let tm
= create_target_machine(sess
);
601 // Figure out what we actually need to build.
603 let mut modules_config
= ModuleConfig
::new(tm
, sess
.opts
.cg
.passes
.clone());
604 let mut metadata_config
= ModuleConfig
::new(tm
, vec
!());
606 modules_config
.opt_level
= Some(get_llvm_opt_level(sess
.opts
.optimize
));
608 // Save all versions of the bytecode if we're saving our temporaries.
609 if sess
.opts
.cg
.save_temps
{
610 modules_config
.emit_no_opt_bc
= true;
611 modules_config
.emit_bc
= true;
612 modules_config
.emit_lto_bc
= true;
613 metadata_config
.emit_bc
= true;
616 // Emit bitcode files for the crate if we're emitting an rlib.
617 // Whenever an rlib is created, the bitcode is inserted into the
618 // archive in order to allow LTO against it.
619 let needs_crate_bitcode
=
620 sess
.crate_types
.borrow().contains(&config
::CrateTypeRlib
) &&
621 sess
.opts
.output_types
.contains(&config
::OutputTypeExe
);
622 if needs_crate_bitcode
{
623 modules_config
.emit_bc
= true;
626 for output_type
in output_types
{
628 config
::OutputTypeBitcode
=> { modules_config.emit_bc = true; }
,
629 config
::OutputTypeLlvmAssembly
=> { modules_config.emit_ir = true; }
,
630 config
::OutputTypeAssembly
=> {
631 modules_config
.emit_asm
= true;
632 // If we're not using the LLVM assembler, this function
633 // could be invoked specially with output_type_assembly, so
634 // in this case we still want the metadata object file.
635 if !sess
.opts
.output_types
.contains(&config
::OutputTypeAssembly
) {
636 metadata_config
.emit_obj
= true;
639 config
::OutputTypeObject
=> { modules_config.emit_obj = true; }
,
640 config
::OutputTypeExe
=> {
641 modules_config
.emit_obj
= true;
642 metadata_config
.emit_obj
= true;
644 config
::OutputTypeDepInfo
=> {}
648 modules_config
.set_flags(sess
, trans
);
649 metadata_config
.set_flags(sess
, trans
);
652 // Populate a buffer with a list of codegen threads. Items are processed in
653 // LIFO order, just because it's a tiny bit simpler that way. (The order
654 // doesn't actually matter.)
655 let mut work_items
= Vec
::with_capacity(1 + trans
.modules
.len());
658 let work
= build_work_item(sess
,
659 trans
.metadata_module
,
660 metadata_config
.clone(),
661 crate_output
.clone(),
662 "metadata".to_string());
663 work_items
.push(work
);
666 for (index
, mtrans
) in trans
.modules
.iter().enumerate() {
667 let work
= build_work_item(sess
,
669 modules_config
.clone(),
670 crate_output
.clone(),
671 format
!("{}", index
));
672 work_items
.push(work
);
675 // Process the work items, optionally using worker threads.
676 if sess
.opts
.cg
.codegen_units
== 1 {
677 run_work_singlethreaded(sess
, &trans
.reachable
, work_items
);
679 run_work_multithreaded(sess
, work_items
, sess
.opts
.cg
.codegen_units
);
682 // All codegen is finished.
684 llvm
::LLVMRustDisposeTargetMachine(tm
);
687 // Produce final compile outputs.
688 let copy_gracefully
= |from
: &Path
, to
: &Path
| {
689 if let Err(e
) = fs
::copy(from
, to
) {
690 sess
.err(&format
!("could not copy {:?} to {:?}: {}", from
, to
, e
));
694 let copy_if_one_unit
= |ext
: &str, output_type
: config
::OutputType
, keep_numbered
: bool
| {
696 if sess
.opts
.cg
.codegen_units
== 1 {
697 // 1) Only one codegen unit. In this case it's no difficulty
698 // to copy `foo.0.x` to `foo.x`.
699 copy_gracefully(&crate_output
.with_extension(ext
), &crate_output
.path(output_type
));
700 if !sess
.opts
.cg
.save_temps
&& !keep_numbered
{
701 // The user just wants `foo.x`, not `foo.0.x`.
702 remove(sess
, &crate_output
.with_extension(ext
));
705 if crate_output
.single_output_file
.is_some() {
706 // 2) Multiple codegen units, with `-o some_name`. We have
707 // no good solution for this case, so warn the user.
708 sess
.warn(&format
!("ignoring -o because multiple .{} files were produced",
711 // 3) Multiple codegen units, but no `-o some_name`. We
712 // just leave the `foo.0.x` files in place.
713 // (We don't have to do any work in this case.)
718 let link_obj
= |output_path
: &Path
| {
719 // Running `ld -r` on a single input is kind of pointless.
720 if sess
.opts
.cg
.codegen_units
== 1 {
721 copy_gracefully(&crate_output
.with_extension("0.o"), output_path
);
722 // Leave the .0.o file around, to mimic the behavior of the normal
727 // Some builds of MinGW GCC will pass --force-exe-suffix to ld, which
728 // will automatically add a .exe extension if the extension is not
729 // already .exe or .dll. To ensure consistent behavior on Windows, we
730 // add the .exe suffix explicitly and then rename the output file to
731 // the desired path. This will give the correct behavior whether or
732 // not GCC adds --force-exe-suffix.
733 let windows_output_path
=
734 if sess
.target
.target
.options
.is_like_windows
{
735 Some(output_path
.with_extension("o.exe"))
740 let pname
= get_cc_prog(sess
);
741 let mut cmd
= Command
::new(&pname
[..]);
743 cmd
.args(&sess
.target
.target
.options
.pre_link_args
);
744 cmd
.arg("-nostdlib");
746 for index
in 0..trans
.modules
.len() {
747 cmd
.arg(&crate_output
.with_extension(&format
!("{}.o", index
)));
750 cmd
.arg("-r").arg("-o")
751 .arg(windows_output_path
.as_ref().map(|s
| &**s
).unwrap_or(output_path
));
753 cmd
.args(&sess
.target
.target
.options
.post_link_args
);
755 if sess
.opts
.debugging_opts
.print_link_args
{
756 println
!("{:?}", &cmd
);
759 cmd
.stdin(Stdio
::null());
762 if !status
.success() {
763 sess
.err(&format
!("linking of {} with `{:?}` failed",
764 output_path
.display(), cmd
));
765 sess
.abort_if_errors();
769 sess
.err(&format
!("could not exec the linker `{}`: {}",
772 sess
.abort_if_errors();
776 match windows_output_path
{
777 Some(ref windows_path
) => {
778 fs
::rename(windows_path
, output_path
).unwrap();
781 // The file is already named according to `output_path`.
786 // Flag to indicate whether the user explicitly requested bitcode.
787 // Otherwise, we produced it only as a temporary output, and will need
789 let mut user_wants_bitcode
= false;
790 for output_type
in output_types
{
792 config
::OutputTypeBitcode
=> {
793 user_wants_bitcode
= true;
794 // Copy to .bc, but always keep the .0.bc. There is a later
795 // check to figure out if we should delete .0.bc files, or keep
796 // them for making an rlib.
797 copy_if_one_unit("0.bc", config
::OutputTypeBitcode
, true);
799 config
::OutputTypeLlvmAssembly
=> {
800 copy_if_one_unit("0.ll", config
::OutputTypeLlvmAssembly
, false);
802 config
::OutputTypeAssembly
=> {
803 copy_if_one_unit("0.s", config
::OutputTypeAssembly
, false);
805 config
::OutputTypeObject
=> {
806 link_obj(&crate_output
.path(config
::OutputTypeObject
));
808 config
::OutputTypeExe
=> {
809 // If config::OutputTypeObject is already in the list, then
810 // `crate.o` will be handled by the config::OutputTypeObject case.
811 // Otherwise, we need to create the temporary object so we
812 // can run the linker.
813 if !sess
.opts
.output_types
.contains(&config
::OutputTypeObject
) {
814 link_obj(&crate_output
.temp_path(config
::OutputTypeObject
));
817 config
::OutputTypeDepInfo
=> {}
820 let user_wants_bitcode
= user_wants_bitcode
;
822 // Clean up unwanted temporary files.
824 // We create the following files by default:
827 // - crate.metadata.bc
828 // - crate.metadata.o
829 // - crate.o (linked from crate.##.o)
830 // - crate.bc (copied from crate.0.bc)
831 // We may create additional files if requested by the user (through
832 // `-C save-temps` or `--emit=` flags).
834 if !sess
.opts
.cg
.save_temps
{
835 // Remove the temporary .0.o objects. If the user didn't
836 // explicitly request bitcode (with --emit=bc), and the bitcode is not
837 // needed for building an rlib, then we must remove .0.bc as well.
839 // Specific rules for keeping .0.bc:
840 // - If we're building an rlib (`needs_crate_bitcode`), then keep
842 // - If the user requested bitcode (`user_wants_bitcode`), and
843 // codegen_units > 1, then keep it.
844 // - If the user requested bitcode but codegen_units == 1, then we
845 // can toss .0.bc because we copied it to .bc earlier.
846 // - If we're not building an rlib and the user didn't request
847 // bitcode, then delete .0.bc.
848 // If you change how this works, also update back::link::link_rlib,
849 // where .0.bc files are (maybe) deleted after making an rlib.
850 let keep_numbered_bitcode
= needs_crate_bitcode
||
851 (user_wants_bitcode
&& sess
.opts
.cg
.codegen_units
> 1);
853 for i
in 0..trans
.modules
.len() {
854 if modules_config
.emit_obj
{
855 let ext
= format
!("{}.o", i
);
856 remove(sess
, &crate_output
.with_extension(&ext
[..]));
859 if modules_config
.emit_bc
&& !keep_numbered_bitcode
{
860 let ext
= format
!("{}.bc", i
);
861 remove(sess
, &crate_output
.with_extension(&ext
[..]));
865 if metadata_config
.emit_bc
&& !user_wants_bitcode
{
866 remove(sess
, &crate_output
.with_extension("metadata.bc"));
870 // We leave the following files around by default:
872 // - crate.metadata.o
874 // These are used in linking steps and will be cleaned up afterward.
876 // FIXME: time_llvm_passes support - does this use a global context or
878 if sess
.opts
.cg
.codegen_units
== 1 && sess
.time_llvm_passes() {
879 unsafe { llvm::LLVMRustPrintPassTimings(); }
884 mtrans
: ModuleTranslation
,
885 config
: ModuleConfig
,
886 output_names
: OutputFilenames
,
890 fn build_work_item(sess
: &Session
,
891 mtrans
: ModuleTranslation
,
892 config
: ModuleConfig
,
893 output_names
: OutputFilenames
,
897 let mut config
= config
;
898 config
.tm
= create_target_machine(sess
);
899 WorkItem
{ mtrans
: mtrans
, config
: config
, output_names
: output_names
,
900 name_extra
: name_extra
}
903 fn execute_work_item(cgcx
: &CodegenContext
,
904 work_item
: WorkItem
) {
906 optimize_and_codegen(cgcx
, work_item
.mtrans
, work_item
.config
,
907 work_item
.name_extra
, work_item
.output_names
);
911 fn run_work_singlethreaded(sess
: &Session
,
912 reachable
: &[String
],
913 work_items
: Vec
<WorkItem
>) {
914 let cgcx
= CodegenContext
::new_with_session(sess
, reachable
);
916 // Since we're running single-threaded, we can pass the session to
917 // the proc, allowing `optimize_and_codegen` to perform LTO.
918 for work
in work_items
.into_iter().rev() {
919 execute_work_item(&cgcx
, work
);
923 fn run_work_multithreaded(sess
: &Session
,
924 work_items
: Vec
<WorkItem
>,
925 num_workers
: usize) {
926 // Run some workers to process the work items.
927 let work_items_arc
= Arc
::new(Mutex
::new(work_items
));
928 let mut diag_emitter
= SharedEmitter
::new();
929 let mut futures
= Vec
::with_capacity(num_workers
);
931 for i
in 0..num_workers
{
932 let work_items_arc
= work_items_arc
.clone();
933 let diag_emitter
= diag_emitter
.clone();
934 let plugin_passes
= sess
.plugin_llvm_passes
.borrow().clone();
935 let remark
= sess
.opts
.cg
.remark
.clone();
937 let (tx
, rx
) = channel();
938 let mut tx
= Some(tx
);
941 thread
::Builder
::new().name(format
!("codegen-{}", i
)).spawn(move || {
942 let diag_handler
= Handler
::with_emitter(true, box diag_emitter
);
944 // Must construct cgcx inside the proc because it has non-Send
946 let cgcx
= CodegenContext
{
948 handler
: &diag_handler
,
949 plugin_passes
: plugin_passes
,
954 // Avoid holding the lock for the entire duration of the match.
955 let maybe_work
= work_items_arc
.lock().unwrap().pop();
958 execute_work_item(&cgcx
, work
);
960 // Make sure to fail the worker so the main thread can
961 // tell that there were errors.
962 cgcx
.handler
.abort_if_errors();
968 tx
.take().unwrap().send(()).unwrap();
972 let mut panicked
= false;
980 // Display any new diagnostics.
981 diag_emitter
.dump(sess
.diagnostic().handler());
984 sess
.fatal("aborting due to worker thread panic");
988 pub fn run_assembler(sess
: &Session
, outputs
: &OutputFilenames
) {
989 let pname
= get_cc_prog(sess
);
990 let mut cmd
= Command
::new(&pname
[..]);
992 cmd
.arg("-c").arg("-o").arg(&outputs
.path(config
::OutputTypeObject
))
993 .arg(&outputs
.temp_path(config
::OutputTypeAssembly
));
998 if !prog
.status
.success() {
999 sess
.err(&format
!("linking with `{}` failed: {}",
1002 sess
.note(&format
!("{:?}", &cmd
));
1003 let mut note
= prog
.stderr
.clone();
1004 note
.push_all(&prog
.stdout
);
1005 sess
.note(str::from_utf8(¬e
[..]).unwrap());
1006 sess
.abort_if_errors();
1010 sess
.err(&format
!("could not exec the linker `{}`: {}",
1013 sess
.abort_if_errors();
1018 unsafe fn configure_llvm(sess
: &Session
) {
1019 use std
::sync
::Once
;
1020 static INIT
: Once
= Once
::new();
1022 let mut llvm_c_strs
= Vec
::new();
1023 let mut llvm_args
= Vec
::new();
1026 let mut add
= |arg
: &str| {
1027 let s
= CString
::new(arg
).unwrap();
1028 llvm_args
.push(s
.as_ptr());
1029 llvm_c_strs
.push(s
);
1031 add("rustc"); // fake program name
1032 if sess
.time_llvm_passes() { add("-time-passes"); }
1033 if sess
.print_llvm_passes() { add("-debug-pass=Structure"); }
1035 // FIXME #21627 disable faulty FastISel on AArch64 (even for -O0)
1036 if sess
.target
.target
.arch
== "aarch64" { add("-fast-isel=0"); }
1038 for arg
in &sess
.opts
.cg
.llvm_args
{
1044 llvm
::LLVMInitializePasses();
1046 // Only initialize the platforms supported by Rust here, because
1047 // using --llvm-root will have multiple platforms that rustllvm
1048 // doesn't actually link to and it's pointless to put target info
1049 // into the registry that Rust cannot generate machine code for.
1050 llvm
::LLVMInitializeX86TargetInfo();
1051 llvm
::LLVMInitializeX86Target();
1052 llvm
::LLVMInitializeX86TargetMC();
1053 llvm
::LLVMInitializeX86AsmPrinter();
1054 llvm
::LLVMInitializeX86AsmParser();
1056 llvm
::LLVMInitializeARMTargetInfo();
1057 llvm
::LLVMInitializeARMTarget();
1058 llvm
::LLVMInitializeARMTargetMC();
1059 llvm
::LLVMInitializeARMAsmPrinter();
1060 llvm
::LLVMInitializeARMAsmParser();
1062 llvm
::LLVMInitializeAArch64TargetInfo();
1063 llvm
::LLVMInitializeAArch64Target();
1064 llvm
::LLVMInitializeAArch64TargetMC();
1065 llvm
::LLVMInitializeAArch64AsmPrinter();
1066 llvm
::LLVMInitializeAArch64AsmParser();
1068 llvm
::LLVMInitializeMipsTargetInfo();
1069 llvm
::LLVMInitializeMipsTarget();
1070 llvm
::LLVMInitializeMipsTargetMC();
1071 llvm
::LLVMInitializeMipsAsmPrinter();
1072 llvm
::LLVMInitializeMipsAsmParser();
1074 llvm
::LLVMInitializePowerPCTargetInfo();
1075 llvm
::LLVMInitializePowerPCTarget();
1076 llvm
::LLVMInitializePowerPCTargetMC();
1077 llvm
::LLVMInitializePowerPCAsmPrinter();
1078 llvm
::LLVMInitializePowerPCAsmParser();
1080 llvm
::LLVMRustSetLLVMOptions(llvm_args
.len() as c_int
,
1081 llvm_args
.as_ptr());
1085 unsafe fn populate_llvm_passes(fpm
: llvm
::PassManagerRef
,
1086 mpm
: llvm
::PassManagerRef
,
1088 opt
: llvm
::CodeGenOptLevel
,
1089 config
: &ModuleConfig
) {
1090 // Create the PassManagerBuilder for LLVM. We configure it with
1091 // reasonable defaults and prepare it to actually populate the pass
1093 let builder
= llvm
::LLVMPassManagerBuilderCreate();
1095 llvm
::LLVMRustConfigurePassManagerBuilder(builder
, opt
,
1096 config
.merge_functions
,
1097 config
.vectorize_slp
,
1098 config
.vectorize_loop
);
1100 llvm
::LLVMRustAddBuilderLibraryInfo(builder
, llmod
, config
.no_builtins
);
1102 // Here we match what clang does (kinda). For O0 we only inline
1103 // always-inline functions (but don't add lifetime intrinsics), at O1 we
1104 // inline with lifetime intrinsics, and O2+ we add an inliner with a
1105 // thresholds copied from clang.
1107 llvm
::CodeGenLevelNone
=> {
1108 llvm
::LLVMRustAddAlwaysInlinePass(builder
, false);
1110 llvm
::CodeGenLevelLess
=> {
1111 llvm
::LLVMRustAddAlwaysInlinePass(builder
, true);
1113 llvm
::CodeGenLevelDefault
=> {
1114 llvm
::LLVMPassManagerBuilderUseInlinerWithThreshold(builder
, 225);
1116 llvm
::CodeGenLevelAggressive
=> {
1117 llvm
::LLVMPassManagerBuilderUseInlinerWithThreshold(builder
, 275);
1121 // Use the builder to populate the function/module pass managers.
1122 llvm
::LLVMPassManagerBuilderPopulateFunctionPassManager(builder
, fpm
);
1123 llvm
::LLVMPassManagerBuilderPopulateModulePassManager(builder
, mpm
);
1124 llvm
::LLVMPassManagerBuilderDispose(builder
);