2014-12-12 23:39:27 +00:00
|
|
|
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
2014-08-11 17:33:58 +00:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
use back::lto;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
use back::link::{get_cc_prog, remove};
|
2014-11-27 12:21:26 +00:00
|
|
|
use session::config::{OutputFilenames, NoDebugInfo, Passes, SomePasses, AllPasses};
|
2014-11-16 01:30:33 +00:00
|
|
|
use session::Session;
|
|
|
|
use session::config;
|
2014-08-11 17:33:58 +00:00
|
|
|
use llvm;
|
2014-09-12 15:17:58 +00:00
|
|
|
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
|
2014-09-27 08:33:36 +00:00
|
|
|
use llvm::SMDiagnosticRef;
|
2014-11-27 12:21:26 +00:00
|
|
|
use trans::{CrateTranslation, ModuleTranslation};
|
2014-08-11 17:33:58 +00:00
|
|
|
use util::common::time;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
use syntax::codemap;
|
|
|
|
use syntax::diagnostic;
|
|
|
|
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-01-06 03:13:38 +00:00
|
|
|
use std::ffi::{self, CString};
|
2014-08-11 17:33:58 +00:00
|
|
|
use std::io::Command;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
use std::io::fs;
|
|
|
|
use std::iter::Unfold;
|
2014-08-11 17:33:58 +00:00
|
|
|
use std::ptr;
|
|
|
|
use std::str;
|
2014-09-12 15:17:58 +00:00
|
|
|
use std::mem;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
2014-12-23 19:53:35 +00:00
|
|
|
use std::sync::mpsc::channel;
|
2014-12-07 02:34:37 +00:00
|
|
|
use std::thread;
|
2015-01-06 03:13:38 +00:00
|
|
|
use libc::{self, c_uint, c_int, c_void};
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-01-04 03:54:18 +00:00
|
|
|
#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-06 01:01:33 +00:00
|
|
|
pub enum OutputType {
|
|
|
|
OutputTypeBitcode,
|
|
|
|
OutputTypeAssembly,
|
|
|
|
OutputTypeLlvmAssembly,
|
|
|
|
OutputTypeObject,
|
|
|
|
OutputTypeExe,
|
|
|
|
}
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
|
2014-08-11 17:33:58 +00:00
|
|
|
unsafe {
|
|
|
|
let cstr = llvm::LLVMRustGetLastError();
|
|
|
|
if cstr == ptr::null() {
|
2015-01-07 16:58:31 +00:00
|
|
|
handler.fatal(&msg[]);
|
2014-08-11 17:33:58 +00:00
|
|
|
} else {
|
2014-11-25 21:28:35 +00:00
|
|
|
let err = ffi::c_str_to_bytes(&cstr);
|
|
|
|
let err = String::from_utf8_lossy(err.as_slice()).to_string();
|
|
|
|
libc::free(cstr as *mut _);
|
2015-01-07 16:58:31 +00:00
|
|
|
handler.fatal(&format!("{}: {}",
|
|
|
|
&msg[],
|
|
|
|
&err[])[]);
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write_output_file(
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
handler: &diagnostic::Handler,
|
2014-08-11 17:33:58 +00:00
|
|
|
target: llvm::TargetMachineRef,
|
|
|
|
pm: llvm::PassManagerRef,
|
|
|
|
m: ModuleRef,
|
|
|
|
output: &Path,
|
|
|
|
file_type: llvm::FileType) {
|
|
|
|
unsafe {
|
2015-01-18 00:32:11 +00:00
|
|
|
let output_c = CString::from_slice(output.as_vec());
|
2014-11-25 21:28:35 +00:00
|
|
|
let result = llvm::LLVMRustWriteOutputFile(
|
2015-01-18 00:32:11 +00:00
|
|
|
target, pm, m, output_c.as_ptr(), file_type);
|
2014-11-25 21:28:35 +00:00
|
|
|
if !result {
|
2015-01-18 00:32:11 +00:00
|
|
|
llvm_err(handler, format!("could not write output to {}", output.display()));
|
2014-11-25 21:28:35 +00:00
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
struct Diagnostic {
|
|
|
|
msg: String,
|
|
|
|
code: Option<String>,
|
|
|
|
lvl: Level,
|
|
|
|
}
|
|
|
|
|
|
|
|
// We use an Arc instead of just returning a list of diagnostics from the
|
|
|
|
// child task because we need to make sure that the messages are seen even
|
2014-10-09 19:17:22 +00:00
|
|
|
// if the child task panics (for example, when `fatal` is called).
|
2015-01-04 03:54:18 +00:00
|
|
|
#[derive(Clone)]
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
struct SharedEmitter {
|
|
|
|
buffer: Arc<Mutex<Vec<Diagnostic>>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SharedEmitter {
|
|
|
|
fn new() -> SharedEmitter {
|
|
|
|
SharedEmitter {
|
|
|
|
buffer: Arc::new(Mutex::new(Vec::new())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn dump(&mut self, handler: &Handler) {
|
2014-12-09 04:20:03 +00:00
|
|
|
let mut buffer = self.buffer.lock().unwrap();
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
for diag in buffer.iter() {
|
|
|
|
match diag.code {
|
|
|
|
Some(ref code) => {
|
|
|
|
handler.emit_with_code(None,
|
2015-01-07 16:58:31 +00:00
|
|
|
&diag.msg[],
|
|
|
|
&code[],
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
diag.lvl);
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
handler.emit(None,
|
2015-01-07 16:58:31 +00:00
|
|
|
&diag.msg[],
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
diag.lvl);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buffer.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Emitter for SharedEmitter {
|
|
|
|
fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, codemap::Span)>,
|
|
|
|
msg: &str, code: Option<&str>, lvl: Level) {
|
|
|
|
assert!(cmsp.is_none(), "SharedEmitter doesn't support spans");
|
|
|
|
|
2014-12-09 04:20:03 +00:00
|
|
|
self.buffer.lock().unwrap().push(Diagnostic {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
msg: msg.to_string(),
|
|
|
|
code: code.map(|s| s.to_string()),
|
|
|
|
lvl: lvl,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn custom_emit(&mut self, _cm: &codemap::CodeMap,
|
|
|
|
_sp: diagnostic::RenderSpan, _msg: &str, _lvl: Level) {
|
2014-10-09 19:17:22 +00:00
|
|
|
panic!("SharedEmitter doesn't support custom_emit");
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 17:33:58 +00:00
|
|
|
// On android, we by default compile for armv7 processors. This enables
|
|
|
|
// things like double word CAS instructions (rather than emulating them)
|
|
|
|
// which are *far* more efficient. This is obviously undesirable in some
|
|
|
|
// cases, so if any sort of target feature is specified we don't append v7
|
|
|
|
// to the feature list.
|
|
|
|
//
|
|
|
|
// On iOS only armv7 and newer are supported. So it is useful to
|
|
|
|
// get all hardware potential via VFP3 (hardware floating point)
|
|
|
|
// and NEON (SIMD) instructions supported by LLVM.
|
|
|
|
// Note that without those flags various linking errors might
|
|
|
|
// arise as some of intrinsics are converted into function calls
|
|
|
|
// and nobody provides implementations those functions
|
2014-07-23 18:56:36 +00:00
|
|
|
fn target_feature(sess: &Session) -> String {
|
|
|
|
format!("{},{}", sess.target.target.options.features, sess.opts.cg.target_feature)
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
|
|
|
|
match optimize {
|
|
|
|
config::No => llvm::CodeGenLevelNone,
|
|
|
|
config::Less => llvm::CodeGenLevelLess,
|
|
|
|
config::Default => llvm::CodeGenLevelDefault,
|
|
|
|
config::Aggressive => llvm::CodeGenLevelAggressive,
|
|
|
|
}
|
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
fn create_target_machine(sess: &Session) -> TargetMachineRef {
|
2014-07-23 18:56:36 +00:00
|
|
|
let reloc_model_arg = match sess.opts.cg.relocation_model {
|
2015-01-07 16:58:31 +00:00
|
|
|
Some(ref s) => &s[],
|
|
|
|
None => &sess.target.target.options.relocation_model[]
|
2014-07-23 18:56:36 +00:00
|
|
|
};
|
|
|
|
let reloc_model = match reloc_model_arg {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
"pic" => llvm::RelocPIC,
|
|
|
|
"static" => llvm::RelocStatic,
|
|
|
|
"default" => llvm::RelocDefault,
|
|
|
|
"dynamic-no-pic" => llvm::RelocDynamicNoPic,
|
|
|
|
_ => {
|
2015-01-07 16:58:31 +00:00
|
|
|
sess.err(&format!("{:?} is not a valid relocation mode",
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
sess.opts
|
|
|
|
.cg
|
2015-01-07 16:58:31 +00:00
|
|
|
.relocation_model)[]);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
unreachable!();
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
};
|
2014-08-11 17:33:58 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
let opt_level = get_llvm_opt_level(sess.opts.optimize);
|
|
|
|
let use_softfp = sess.opts.cg.soft_float;
|
|
|
|
|
|
|
|
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
|
|
|
|
let no_fp_elim = (sess.opts.debuginfo != NoDebugInfo) ||
|
2014-07-23 18:56:36 +00:00
|
|
|
!sess.target.target.options.eliminate_frame_pointer;
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2014-08-09 16:43:45 +00:00
|
|
|
let any_library = sess.crate_types.borrow().iter().any(|ty| {
|
|
|
|
*ty != config::CrateTypeExecutable
|
|
|
|
});
|
|
|
|
|
2014-07-23 18:56:36 +00:00
|
|
|
let ffunction_sections = sess.target.target.options.function_sections;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
let fdata_sections = ffunction_sections;
|
|
|
|
|
2014-07-23 18:56:36 +00:00
|
|
|
let code_model_arg = match sess.opts.cg.code_model {
|
2015-01-07 16:58:31 +00:00
|
|
|
Some(ref s) => &s[],
|
|
|
|
None => &sess.target.target.options.code_model[]
|
2014-07-23 18:56:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let code_model = match code_model_arg {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
"default" => llvm::CodeModelDefault,
|
|
|
|
"small" => llvm::CodeModelSmall,
|
|
|
|
"kernel" => llvm::CodeModelKernel,
|
|
|
|
"medium" => llvm::CodeModelMedium,
|
|
|
|
"large" => llvm::CodeModelLarge,
|
|
|
|
_ => {
|
2015-01-07 16:58:31 +00:00
|
|
|
sess.err(&format!("{:?} is not a valid code model",
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
sess.opts
|
|
|
|
.cg
|
2015-01-07 16:58:31 +00:00
|
|
|
.code_model)[]);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
unreachable!();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-01-07 16:58:31 +00:00
|
|
|
let triple = &sess.target.target.llvm_target[];
|
2014-10-29 01:58:46 +00:00
|
|
|
|
|
|
|
let tm = unsafe {
|
2014-11-25 21:28:35 +00:00
|
|
|
let triple = CString::from_slice(triple.as_bytes());
|
|
|
|
let cpu = match sess.opts.cg.target_cpu {
|
|
|
|
Some(ref s) => s.as_slice(),
|
|
|
|
None => sess.target.target.options.cpu.as_slice()
|
|
|
|
};
|
|
|
|
let cpu = CString::from_slice(cpu.as_bytes());
|
|
|
|
let features = CString::from_slice(target_feature(sess).as_bytes());
|
|
|
|
llvm::LLVMRustCreateTargetMachine(
|
|
|
|
triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
|
|
|
|
code_model,
|
|
|
|
reloc_model,
|
|
|
|
opt_level,
|
|
|
|
true /* EnableSegstk */,
|
|
|
|
use_softfp,
|
|
|
|
no_fp_elim,
|
|
|
|
!any_library && reloc_model == llvm::RelocPIC,
|
|
|
|
ffunction_sections,
|
|
|
|
fdata_sections,
|
|
|
|
)
|
2014-10-29 01:58:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if tm.is_null() {
|
|
|
|
llvm_err(sess.diagnostic().handler(),
|
|
|
|
format!("Could not create LLVM TargetMachine for triple: {}",
|
|
|
|
triple).to_string());
|
|
|
|
} else {
|
|
|
|
return tm;
|
|
|
|
};
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Module-specific configuration for `optimize_and_codegen`.
|
2015-01-04 03:54:18 +00:00
|
|
|
#[derive(Clone)]
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
struct ModuleConfig {
|
|
|
|
/// LLVM TargetMachine to use for codegen.
|
|
|
|
tm: TargetMachineRef,
|
|
|
|
/// Names of additional optimization passes to run.
|
|
|
|
passes: Vec<String>,
|
|
|
|
/// Some(level) to optimize at a certain level, or None to run
|
|
|
|
/// absolutely no optimizations (used for the metadata module).
|
|
|
|
opt_level: Option<llvm::CodeGenOptLevel>,
|
2014-08-11 17:33:58 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
// Flags indicating which outputs to produce.
|
|
|
|
emit_no_opt_bc: bool,
|
|
|
|
emit_bc: bool,
|
|
|
|
emit_lto_bc: bool,
|
|
|
|
emit_ir: bool,
|
|
|
|
emit_asm: bool,
|
|
|
|
emit_obj: bool,
|
|
|
|
|
|
|
|
// Miscellaneous flags. These are mostly copied from command-line
|
|
|
|
// options.
|
|
|
|
no_verify: bool,
|
|
|
|
no_prepopulate_passes: bool,
|
|
|
|
no_builtins: bool,
|
|
|
|
time_passes: bool,
|
|
|
|
}
|
|
|
|
|
2014-12-21 23:49:42 +00:00
|
|
|
unsafe impl Send for ModuleConfig { }
|
2014-12-06 16:39:25 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
impl ModuleConfig {
|
|
|
|
fn new(tm: TargetMachineRef, passes: Vec<String>) -> ModuleConfig {
|
|
|
|
ModuleConfig {
|
|
|
|
tm: tm,
|
|
|
|
passes: passes,
|
|
|
|
opt_level: None,
|
|
|
|
|
|
|
|
emit_no_opt_bc: false,
|
|
|
|
emit_bc: false,
|
|
|
|
emit_lto_bc: false,
|
|
|
|
emit_ir: false,
|
|
|
|
emit_asm: false,
|
|
|
|
emit_obj: false,
|
|
|
|
|
|
|
|
no_verify: false,
|
|
|
|
no_prepopulate_passes: false,
|
|
|
|
no_builtins: false,
|
|
|
|
time_passes: false,
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
fn set_flags(&mut self, sess: &Session, trans: &CrateTranslation) {
|
|
|
|
self.no_verify = sess.no_verify();
|
|
|
|
self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
|
|
|
|
self.no_builtins = trans.no_builtins;
|
|
|
|
self.time_passes = sess.time_passes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Additional resources used by optimize_and_codegen (not module specific)
|
|
|
|
struct CodegenContext<'a> {
|
|
|
|
// Extra resources used for LTO: (sess, reachable). This will be `None`
|
|
|
|
// when running in a worker thread.
|
|
|
|
lto_ctxt: Option<(&'a Session, &'a [String])>,
|
|
|
|
// Handler to use for diagnostics produced during codegen.
|
|
|
|
handler: &'a Handler,
|
2014-09-12 15:17:58 +00:00
|
|
|
// LLVM optimizations for which we want to print remarks.
|
|
|
|
remark: Passes,
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> CodegenContext<'a> {
|
|
|
|
fn new_with_session(sess: &'a Session, reachable: &'a [String]) -> CodegenContext<'a> {
|
|
|
|
CodegenContext {
|
|
|
|
lto_ctxt: Some((sess, reachable)),
|
|
|
|
handler: sess.diagnostic().handler(),
|
2014-09-12 15:17:58 +00:00
|
|
|
remark: sess.opts.cg.remark.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-27 08:33:36 +00:00
|
|
|
struct HandlerFreeVars<'a> {
|
2014-09-12 15:17:58 +00:00
|
|
|
llcx: ContextRef,
|
|
|
|
cgcx: &'a CodegenContext<'a>,
|
|
|
|
}
|
|
|
|
|
2014-09-27 08:33:36 +00:00
|
|
|
unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
|
|
|
|
user: *const c_void,
|
|
|
|
cookie: c_uint) {
|
|
|
|
use syntax::codemap::ExpnId;
|
|
|
|
|
|
|
|
let HandlerFreeVars { cgcx, .. }
|
|
|
|
= *mem::transmute::<_, *const HandlerFreeVars>(user);
|
|
|
|
|
|
|
|
let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
|
|
|
|
.expect("non-UTF8 SMDiagnostic");
|
|
|
|
|
|
|
|
match cgcx.lto_ctxt {
|
|
|
|
Some((sess, _)) => {
|
2014-09-28 16:25:48 +00:00
|
|
|
sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info {
|
2015-01-07 16:58:31 +00:00
|
|
|
Some(ei) => sess.span_err(ei.call_site, &msg[]),
|
|
|
|
None => sess.err(&msg[]),
|
2014-09-27 08:33:36 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
None => {
|
2015-01-07 16:58:31 +00:00
|
|
|
cgcx.handler.err(&msg[]);
|
2014-09-27 08:33:36 +00:00
|
|
|
cgcx.handler.note("build without -C codegen-units for more exact errors");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-12 15:17:58 +00:00
|
|
|
unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
|
2014-09-27 08:33:36 +00:00
|
|
|
let HandlerFreeVars { llcx, cgcx }
|
|
|
|
= *mem::transmute::<_, *const HandlerFreeVars>(user);
|
2014-09-12 15:17:58 +00:00
|
|
|
|
|
|
|
match llvm::diagnostic::Diagnostic::unpack(info) {
|
|
|
|
llvm::diagnostic::Optimization(opt) => {
|
2014-11-25 21:28:35 +00:00
|
|
|
let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
|
|
|
|
.ok()
|
|
|
|
.expect("got a non-UTF8 pass name from LLVM");
|
2014-09-12 15:17:58 +00:00
|
|
|
let enabled = match cgcx.remark {
|
|
|
|
AllPasses => true,
|
2014-11-27 19:10:25 +00:00
|
|
|
SomePasses(ref v) => v.iter().any(|s| *s == pass_name),
|
2014-09-12 15:17:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if enabled {
|
|
|
|
let loc = llvm::debug_loc_to_string(llcx, opt.debug_loc);
|
2014-11-17 19:29:38 +00:00
|
|
|
cgcx.handler.note(format!("optimization {} for {} at {}: {}",
|
2014-09-12 15:17:58 +00:00
|
|
|
opt.kind.describe(),
|
|
|
|
pass_name,
|
2015-01-04 04:43:24 +00:00
|
|
|
if loc.is_empty() { "[unknown]" } else { loc.as_slice() },
|
|
|
|
llvm::twine_to_string(opt.message)).as_slice());
|
2014-09-12 15:17:58 +00:00
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
2014-09-12 15:17:58 +00:00
|
|
|
|
|
|
|
_ => (),
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unsafe due to LLVM calls.
|
|
|
|
unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
|
|
|
mtrans: ModuleTranslation,
|
|
|
|
config: ModuleConfig,
|
|
|
|
name_extra: String,
|
|
|
|
output_names: OutputFilenames) {
|
|
|
|
let ModuleTranslation { llmod, llcx } = mtrans;
|
|
|
|
let tm = config.tm;
|
|
|
|
|
2014-09-12 15:17:58 +00:00
|
|
|
// llcx doesn't outlive this function, so we can put this on the stack.
|
2014-09-27 08:33:36 +00:00
|
|
|
let fv = HandlerFreeVars {
|
2014-09-12 15:17:58 +00:00
|
|
|
llcx: llcx,
|
|
|
|
cgcx: cgcx,
|
|
|
|
};
|
2014-09-27 08:33:36 +00:00
|
|
|
let fv = &fv as *const HandlerFreeVars as *mut c_void;
|
|
|
|
|
|
|
|
llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
|
|
|
|
|
2014-09-12 15:17:58 +00:00
|
|
|
if !cgcx.remark.is_empty() {
|
2014-09-27 08:33:36 +00:00
|
|
|
llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
|
2014-09-12 15:17:58 +00:00
|
|
|
}
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
if config.emit_no_opt_bc {
|
|
|
|
let ext = format!("{}.no-opt.bc", name_extra);
|
2014-11-25 21:28:35 +00:00
|
|
|
let out = output_names.with_extension(ext.as_slice());
|
|
|
|
let out = CString::from_slice(out.as_vec());
|
|
|
|
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
match config.opt_level {
|
|
|
|
Some(opt_level) => {
|
|
|
|
// Create the two optimizing pass managers. These mirror what clang
|
|
|
|
// does, and are by populated by LLVM's default PassManagerBuilder.
|
|
|
|
// Each manager has a different set of passes, but they also share
|
|
|
|
// some common passes.
|
|
|
|
let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod);
|
|
|
|
let mpm = llvm::LLVMCreatePassManager();
|
|
|
|
|
|
|
|
// If we're verifying or linting, add them to the function pass
|
|
|
|
// manager.
|
2014-12-31 01:58:47 +00:00
|
|
|
let addpass = |&: pass: &str| {
|
2014-11-25 21:28:35 +00:00
|
|
|
let pass = CString::from_slice(pass.as_bytes());
|
|
|
|
llvm::LLVMRustAddPass(fpm, pass.as_ptr())
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
};
|
|
|
|
if !config.no_verify { assert!(addpass("verify")); }
|
2014-08-11 17:33:58 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
if !config.no_prepopulate_passes {
|
|
|
|
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
|
|
|
|
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
|
|
|
|
populate_llvm_passes(fpm, mpm, llmod, opt_level,
|
|
|
|
config.no_builtins);
|
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
for pass in config.passes.iter() {
|
2014-11-25 21:28:35 +00:00
|
|
|
let pass = CString::from_slice(pass.as_bytes());
|
|
|
|
if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
|
2015-01-07 00:16:35 +00:00
|
|
|
cgcx.handler.warn(format!("unknown pass {:?}, ignoring",
|
2014-11-25 21:28:35 +00:00
|
|
|
pass).as_slice());
|
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
// Finally, run the actual optimization passes
|
|
|
|
time(config.time_passes, "llvm function passes", (), |()|
|
|
|
|
llvm::LLVMRustRunFunctionPassManager(fpm, llmod));
|
|
|
|
time(config.time_passes, "llvm module passes", (), |()|
|
|
|
|
llvm::LLVMRunPassManager(mpm, llmod));
|
|
|
|
|
|
|
|
// Deallocate managers that we're now done with
|
|
|
|
llvm::LLVMDisposePassManager(fpm);
|
|
|
|
llvm::LLVMDisposePassManager(mpm);
|
|
|
|
|
|
|
|
match cgcx.lto_ctxt {
|
|
|
|
Some((sess, reachable)) if sess.lto() => {
|
|
|
|
time(sess.time_passes(), "all lto passes", (), |()|
|
|
|
|
lto::run(sess, llmod, tm, reachable));
|
|
|
|
|
|
|
|
if config.emit_lto_bc {
|
|
|
|
let name = format!("{}.lto.bc", name_extra);
|
2014-11-25 21:28:35 +00:00
|
|
|
let out = output_names.with_extension(name.as_slice());
|
|
|
|
let out = CString::from_slice(out.as_vec());
|
|
|
|
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {},
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
},
|
|
|
|
None => {},
|
|
|
|
}
|
|
|
|
|
|
|
|
// A codegen-specific pass manager is used to generate object
|
|
|
|
// files for an LLVM module.
|
|
|
|
//
|
|
|
|
// Apparently each of these pass managers is a one-shot kind of
|
|
|
|
// thing, so we create a new one for each type of output. The
|
|
|
|
// pass manager passed to the closure should be ensured to not
|
|
|
|
// escape the closure itself, and the manager should only be
|
|
|
|
// used once.
|
2014-12-09 18:44:51 +00:00
|
|
|
unsafe fn with_codegen<F>(tm: TargetMachineRef,
|
|
|
|
llmod: ModuleRef,
|
|
|
|
no_builtins: bool,
|
|
|
|
f: F) where
|
|
|
|
F: FnOnce(PassManagerRef),
|
|
|
|
{
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
let cpm = llvm::LLVMCreatePassManager();
|
|
|
|
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
|
|
|
|
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
|
|
|
|
f(cpm);
|
|
|
|
llvm::LLVMDisposePassManager(cpm);
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.emit_bc {
|
|
|
|
let ext = format!("{}.bc", name_extra);
|
2014-11-25 21:28:35 +00:00
|
|
|
let out = output_names.with_extension(ext.as_slice());
|
|
|
|
let out = CString::from_slice(out.as_vec());
|
|
|
|
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
time(config.time_passes, "codegen passes", (), |()| {
|
|
|
|
if config.emit_ir {
|
|
|
|
let ext = format!("{}.ll", name_extra);
|
2014-11-25 21:28:35 +00:00
|
|
|
let out = output_names.with_extension(ext.as_slice());
|
|
|
|
let out = CString::from_slice(out.as_vec());
|
|
|
|
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
|
|
|
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
})
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
if config.emit_asm {
|
2015-01-07 16:58:31 +00:00
|
|
|
let path = output_names.with_extension(&format!("{}.s", name_extra)[]);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
2014-09-11 05:07:49 +00:00
|
|
|
write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFileType);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.emit_obj {
|
2015-01-07 16:58:31 +00:00
|
|
|
let path = output_names.with_extension(&format!("{}.o", name_extra)[]);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
2014-09-11 05:07:49 +00:00
|
|
|
write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFileType);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
llvm::LLVMDisposeModule(llmod);
|
|
|
|
llvm::LLVMContextDispose(llcx);
|
|
|
|
llvm::LLVMRustDisposeTargetMachine(tm);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn run_passes(sess: &Session,
|
|
|
|
trans: &CrateTranslation,
|
2014-11-16 01:30:33 +00:00
|
|
|
output_types: &[config::OutputType],
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
crate_output: &OutputFilenames) {
|
|
|
|
// It's possible that we have `codegen_units > 1` but only one item in
|
|
|
|
// `trans.modules`. We could theoretically proceed and do LTO in that
|
|
|
|
// case, but it would be confusing to have the validity of
|
|
|
|
// `-Z lto -C codegen-units=2` depend on details of the crate being
|
|
|
|
// compiled, so we complain regardless.
|
|
|
|
if sess.lto() && sess.opts.cg.codegen_units > 1 {
|
|
|
|
// This case is impossible to handle because LTO expects to be able
|
|
|
|
// to combine the entire crate and all its dependencies into a
|
|
|
|
// single compilation unit, but each codegen unit is in a separate
|
|
|
|
// LLVM context, so they can't easily be combined.
|
|
|
|
sess.fatal("can't perform LTO when using multiple codegen units");
|
|
|
|
}
|
|
|
|
|
2014-09-05 21:30:36 +00:00
|
|
|
// Sanity check
|
|
|
|
assert!(trans.modules.len() == sess.opts.cg.codegen_units);
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
unsafe {
|
|
|
|
configure_llvm(sess);
|
|
|
|
}
|
|
|
|
|
|
|
|
let tm = create_target_machine(sess);
|
|
|
|
|
|
|
|
// Figure out what we actually need to build.
|
|
|
|
|
|
|
|
let mut modules_config = ModuleConfig::new(tm, sess.opts.cg.passes.clone());
|
|
|
|
let mut metadata_config = ModuleConfig::new(tm, vec!());
|
|
|
|
|
|
|
|
modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize));
|
|
|
|
|
|
|
|
// Save all versions of the bytecode if we're saving our temporaries.
|
|
|
|
if sess.opts.cg.save_temps {
|
|
|
|
modules_config.emit_no_opt_bc = true;
|
|
|
|
modules_config.emit_bc = true;
|
|
|
|
modules_config.emit_lto_bc = true;
|
|
|
|
metadata_config.emit_bc = true;
|
|
|
|
}
|
|
|
|
|
2014-09-17 23:18:12 +00:00
|
|
|
// Emit bitcode files for the crate if we're emitting an rlib.
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
// Whenever an rlib is created, the bitcode is inserted into the
|
|
|
|
// archive in order to allow LTO against it.
|
|
|
|
let needs_crate_bitcode =
|
|
|
|
sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
|
2014-11-16 01:30:33 +00:00
|
|
|
sess.opts.output_types.contains(&config::OutputTypeExe);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
if needs_crate_bitcode {
|
|
|
|
modules_config.emit_bc = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for output_type in output_types.iter() {
|
|
|
|
match *output_type {
|
2014-11-16 01:30:33 +00:00
|
|
|
config::OutputTypeBitcode => { modules_config.emit_bc = true; },
|
|
|
|
config::OutputTypeLlvmAssembly => { modules_config.emit_ir = true; },
|
|
|
|
config::OutputTypeAssembly => {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
modules_config.emit_asm = true;
|
|
|
|
// If we're not using the LLVM assembler, this function
|
|
|
|
// could be invoked specially with output_type_assembly, so
|
|
|
|
// in this case we still want the metadata object file.
|
2014-11-16 01:30:33 +00:00
|
|
|
if !sess.opts.output_types.contains(&config::OutputTypeAssembly) {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
metadata_config.emit_obj = true;
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
},
|
2014-11-16 01:30:33 +00:00
|
|
|
config::OutputTypeObject => { modules_config.emit_obj = true; },
|
|
|
|
config::OutputTypeExe => {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
modules_config.emit_obj = true;
|
|
|
|
metadata_config.emit_obj = true;
|
|
|
|
},
|
2014-12-16 00:03:39 +00:00
|
|
|
config::OutputTypeDepInfo => {}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
modules_config.set_flags(sess, trans);
|
|
|
|
metadata_config.set_flags(sess, trans);
|
|
|
|
|
|
|
|
|
|
|
|
// Populate a buffer with a list of codegen tasks. Items are processed in
|
|
|
|
// LIFO order, just because it's a tiny bit simpler that way. (The order
|
|
|
|
// doesn't actually matter.)
|
|
|
|
let mut work_items = Vec::with_capacity(1 + trans.modules.len());
|
|
|
|
|
|
|
|
{
|
|
|
|
let work = build_work_item(sess,
|
|
|
|
trans.metadata_module,
|
|
|
|
metadata_config.clone(),
|
|
|
|
crate_output.clone(),
|
|
|
|
"metadata".to_string());
|
|
|
|
work_items.push(work);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (index, mtrans) in trans.modules.iter().enumerate() {
|
|
|
|
let work = build_work_item(sess,
|
|
|
|
*mtrans,
|
|
|
|
modules_config.clone(),
|
|
|
|
crate_output.clone(),
|
|
|
|
format!("{}", index));
|
|
|
|
work_items.push(work);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the work items, optionally using worker threads.
|
|
|
|
if sess.opts.cg.codegen_units == 1 {
|
2015-01-07 16:58:31 +00:00
|
|
|
run_work_singlethreaded(sess, &trans.reachable[], work_items);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
} else {
|
|
|
|
run_work_multithreaded(sess, work_items, sess.opts.cg.codegen_units);
|
|
|
|
}
|
|
|
|
|
|
|
|
// All codegen is finished.
|
|
|
|
unsafe {
|
|
|
|
llvm::LLVMRustDisposeTargetMachine(tm);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Produce final compile outputs.
|
|
|
|
|
2014-12-31 01:58:47 +00:00
|
|
|
let copy_if_one_unit = |&: ext: &str, output_type: config::OutputType, keep_numbered: bool| {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
// Three cases:
|
|
|
|
if sess.opts.cg.codegen_units == 1 {
|
|
|
|
// 1) Only one codegen unit. In this case it's no difficulty
|
|
|
|
// to copy `foo.0.x` to `foo.x`.
|
|
|
|
fs::copy(&crate_output.with_extension(ext),
|
|
|
|
&crate_output.path(output_type)).unwrap();
|
2014-09-17 23:18:12 +00:00
|
|
|
if !sess.opts.cg.save_temps && !keep_numbered {
|
2014-08-27 21:49:17 +00:00
|
|
|
// The user just wants `foo.x`, not `foo.0.x`.
|
|
|
|
remove(sess, &crate_output.with_extension(ext));
|
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
} else {
|
|
|
|
if crate_output.single_output_file.is_some() {
|
|
|
|
// 2) Multiple codegen units, with `-o some_name`. We have
|
|
|
|
// no good solution for this case, so warn the user.
|
2015-01-07 16:58:31 +00:00
|
|
|
sess.warn(&format!("ignoring -o because multiple .{} files were produced",
|
|
|
|
ext)[]);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
} else {
|
|
|
|
// 3) Multiple codegen units, but no `-o some_name`. We
|
|
|
|
// just leave the `foo.0.x` files in place.
|
|
|
|
// (We don't have to do any work in this case.)
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
};
|
|
|
|
|
2014-12-31 01:58:47 +00:00
|
|
|
let link_obj = |&: output_path: &Path| {
|
2014-09-05 21:30:36 +00:00
|
|
|
// Running `ld -r` on a single input is kind of pointless.
|
|
|
|
if sess.opts.cg.codegen_units == 1 {
|
|
|
|
fs::copy(&crate_output.with_extension("0.o"),
|
|
|
|
output_path).unwrap();
|
|
|
|
// Leave the .0.o file around, to mimic the behavior of the normal
|
|
|
|
// code path.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-29 19:46:04 +00:00
|
|
|
// Some builds of MinGW GCC will pass --force-exe-suffix to ld, which
|
|
|
|
// will automatically add a .exe extension if the extension is not
|
|
|
|
// already .exe or .dll. To ensure consistent behavior on Windows, we
|
|
|
|
// add the .exe suffix explicitly and then rename the output file to
|
|
|
|
// the desired path. This will give the correct behavior whether or
|
|
|
|
// not GCC adds --force-exe-suffix.
|
|
|
|
let windows_output_path =
|
2014-07-23 18:56:36 +00:00
|
|
|
if sess.target.target.options.is_like_windows {
|
2014-08-29 19:46:04 +00:00
|
|
|
Some(output_path.with_extension("o.exe"))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
2014-08-26 22:53:56 +00:00
|
|
|
let pname = get_cc_prog(sess);
|
2015-01-07 16:58:31 +00:00
|
|
|
let mut cmd = Command::new(&pname[]);
|
2014-08-26 22:53:56 +00:00
|
|
|
|
2015-01-07 16:58:31 +00:00
|
|
|
cmd.args(&sess.target.target.options.pre_link_args[]);
|
2014-08-26 22:53:56 +00:00
|
|
|
cmd.arg("-nostdlib");
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
|
|
|
for index in range(0, trans.modules.len()) {
|
2015-01-07 16:58:31 +00:00
|
|
|
cmd.arg(crate_output.with_extension(&format!("{}.o", index)[]));
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2014-08-29 19:46:04 +00:00
|
|
|
cmd.arg("-r")
|
|
|
|
.arg("-o")
|
|
|
|
.arg(windows_output_path.as_ref().unwrap_or(output_path));
|
2014-08-26 22:53:56 +00:00
|
|
|
|
2015-01-07 16:58:31 +00:00
|
|
|
cmd.args(&sess.target.target.options.post_link_args[]);
|
2014-07-23 18:56:36 +00:00
|
|
|
|
2014-12-09 09:55:49 +00:00
|
|
|
if sess.opts.debugging_opts.print_link_args {
|
2015-01-20 23:45:07 +00:00
|
|
|
println!("{:?}", &cmd);
|
2014-08-26 22:53:56 +00:00
|
|
|
}
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
cmd.stdin(::std::io::process::Ignored)
|
|
|
|
.stdout(::std::io::process::InheritFd(1))
|
|
|
|
.stderr(::std::io::process::InheritFd(2));
|
2014-08-26 22:53:56 +00:00
|
|
|
match cmd.status() {
|
2014-10-22 20:23:22 +00:00
|
|
|
Ok(status) => {
|
|
|
|
if !status.success() {
|
2015-01-20 23:45:07 +00:00
|
|
|
sess.err(&format!("linking of {} with `{:?}` failed",
|
2015-01-07 16:58:31 +00:00
|
|
|
output_path.display(), cmd)[]);
|
2014-10-22 20:23:22 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
}
|
|
|
|
},
|
2014-08-26 22:53:56 +00:00
|
|
|
Err(e) => {
|
2015-01-07 16:58:31 +00:00
|
|
|
sess.err(&format!("could not exec the linker `{}`: {}",
|
2014-08-26 22:53:56 +00:00
|
|
|
pname,
|
2015-01-07 16:58:31 +00:00
|
|
|
e)[]);
|
2014-08-26 22:53:56 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
},
|
|
|
|
}
|
2014-08-29 19:46:04 +00:00
|
|
|
|
|
|
|
match windows_output_path {
|
|
|
|
Some(ref windows_path) => {
|
|
|
|
fs::rename(windows_path, output_path).unwrap();
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
// The file is already named according to `output_path`.
|
|
|
|
}
|
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Flag to indicate whether the user explicitly requested bitcode.
|
|
|
|
// Otherwise, we produced it only as a temporary output, and will need
|
|
|
|
// to get rid of it.
|
2014-09-17 23:18:12 +00:00
|
|
|
let mut user_wants_bitcode = false;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
for output_type in output_types.iter() {
|
|
|
|
match *output_type {
|
2014-11-16 01:30:33 +00:00
|
|
|
config::OutputTypeBitcode => {
|
2014-09-17 23:18:12 +00:00
|
|
|
user_wants_bitcode = true;
|
|
|
|
// Copy to .bc, but always keep the .0.bc. There is a later
|
|
|
|
// check to figure out if we should delete .0.bc files, or keep
|
|
|
|
// them for making an rlib.
|
2014-11-16 01:30:33 +00:00
|
|
|
copy_if_one_unit("0.bc", config::OutputTypeBitcode, true);
|
|
|
|
}
|
|
|
|
config::OutputTypeLlvmAssembly => {
|
|
|
|
copy_if_one_unit("0.ll", config::OutputTypeLlvmAssembly, false);
|
|
|
|
}
|
|
|
|
config::OutputTypeAssembly => {
|
|
|
|
copy_if_one_unit("0.s", config::OutputTypeAssembly, false);
|
|
|
|
}
|
|
|
|
config::OutputTypeObject => {
|
|
|
|
link_obj(&crate_output.path(config::OutputTypeObject));
|
|
|
|
}
|
|
|
|
config::OutputTypeExe => {
|
|
|
|
// If config::OutputTypeObject is already in the list, then
|
|
|
|
// `crate.o` will be handled by the config::OutputTypeObject case.
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
// Otherwise, we need to create the temporary object so we
|
|
|
|
// can run the linker.
|
2014-11-16 01:30:33 +00:00
|
|
|
if !sess.opts.output_types.contains(&config::OutputTypeObject) {
|
|
|
|
link_obj(&crate_output.temp_path(config::OutputTypeObject));
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
2014-11-16 01:30:33 +00:00
|
|
|
}
|
2014-12-16 00:03:39 +00:00
|
|
|
config::OutputTypeDepInfo => {}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
2014-09-17 23:18:12 +00:00
|
|
|
let user_wants_bitcode = user_wants_bitcode;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
|
|
|
// Clean up unwanted temporary files.
|
|
|
|
|
|
|
|
// We create the following files by default:
|
|
|
|
// - crate.0.bc
|
|
|
|
// - crate.0.o
|
|
|
|
// - crate.metadata.bc
|
|
|
|
// - crate.metadata.o
|
|
|
|
// - crate.o (linked from crate.##.o)
|
2014-08-27 21:49:17 +00:00
|
|
|
// - crate.bc (copied from crate.0.bc)
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
// We may create additional files if requested by the user (through
|
|
|
|
// `-C save-temps` or `--emit=` flags).
|
|
|
|
|
|
|
|
if !sess.opts.cg.save_temps {
|
|
|
|
// Remove the temporary .0.o objects. If the user didn't
|
2014-09-17 23:18:12 +00:00
|
|
|
// explicitly request bitcode (with --emit=bc), and the bitcode is not
|
|
|
|
// needed for building an rlib, then we must remove .0.bc as well.
|
|
|
|
|
|
|
|
// Specific rules for keeping .0.bc:
|
|
|
|
// - If we're building an rlib (`needs_crate_bitcode`), then keep
|
|
|
|
// it.
|
|
|
|
// - If the user requested bitcode (`user_wants_bitcode`), and
|
|
|
|
// codegen_units > 1, then keep it.
|
|
|
|
// - If the user requested bitcode but codegen_units == 1, then we
|
|
|
|
// can toss .0.bc because we copied it to .bc earlier.
|
|
|
|
// - If we're not building an rlib and the user didn't request
|
|
|
|
// bitcode, then delete .0.bc.
|
|
|
|
// If you change how this works, also update back::link::link_rlib,
|
|
|
|
// where .0.bc files are (maybe) deleted after making an rlib.
|
|
|
|
let keep_numbered_bitcode = needs_crate_bitcode ||
|
|
|
|
(user_wants_bitcode && sess.opts.cg.codegen_units > 1);
|
|
|
|
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
for i in range(0, trans.modules.len()) {
|
|
|
|
if modules_config.emit_obj {
|
|
|
|
let ext = format!("{}.o", i);
|
2015-01-07 16:58:31 +00:00
|
|
|
remove(sess, &crate_output.with_extension(&ext[]));
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
2014-09-17 23:18:12 +00:00
|
|
|
if modules_config.emit_bc && !keep_numbered_bitcode {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
let ext = format!("{}.bc", i);
|
2015-01-07 16:58:31 +00:00
|
|
|
remove(sess, &crate_output.with_extension(&ext[]));
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-17 23:18:12 +00:00
|
|
|
if metadata_config.emit_bc && !user_wants_bitcode {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
remove(sess, &crate_output.with_extension("metadata.bc"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We leave the following files around by default:
|
|
|
|
// - crate.o
|
|
|
|
// - crate.metadata.o
|
|
|
|
// - crate.bc
|
|
|
|
// These are used in linking steps and will be cleaned up afterward.
|
|
|
|
|
|
|
|
// FIXME: time_llvm_passes support - does this use a global context or
|
|
|
|
// something?
|
|
|
|
//if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
|
|
|
|
}
|
|
|
|
|
2014-11-26 15:07:58 +00:00
|
|
|
struct WorkItem {
|
|
|
|
mtrans: ModuleTranslation,
|
|
|
|
config: ModuleConfig,
|
|
|
|
output_names: OutputFilenames,
|
|
|
|
name_extra: String
|
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
|
|
|
fn build_work_item(sess: &Session,
|
|
|
|
mtrans: ModuleTranslation,
|
|
|
|
config: ModuleConfig,
|
|
|
|
output_names: OutputFilenames,
|
2014-11-26 15:07:58 +00:00
|
|
|
name_extra: String)
|
|
|
|
-> WorkItem
|
|
|
|
{
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
let mut config = config;
|
|
|
|
config.tm = create_target_machine(sess);
|
2014-11-26 15:07:58 +00:00
|
|
|
WorkItem { mtrans: mtrans, config: config, output_names: output_names,
|
|
|
|
name_extra: name_extra }
|
|
|
|
}
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
2014-11-26 15:07:58 +00:00
|
|
|
fn execute_work_item(cgcx: &CodegenContext,
|
|
|
|
work_item: WorkItem) {
|
|
|
|
unsafe {
|
|
|
|
optimize_and_codegen(cgcx, work_item.mtrans, work_item.config,
|
|
|
|
work_item.name_extra, work_item.output_names);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run_work_singlethreaded(sess: &Session,
|
|
|
|
reachable: &[String],
|
|
|
|
work_items: Vec<WorkItem>) {
|
|
|
|
let cgcx = CodegenContext::new_with_session(sess, reachable);
|
|
|
|
let mut work_items = work_items;
|
|
|
|
|
|
|
|
// Since we're running single-threaded, we can pass the session to
|
|
|
|
// the proc, allowing `optimize_and_codegen` to perform LTO.
|
|
|
|
for work in Unfold::new((), |_| work_items.pop()) {
|
2014-11-26 15:07:58 +00:00
|
|
|
execute_work_item(&cgcx, work);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run_work_multithreaded(sess: &Session,
|
|
|
|
work_items: Vec<WorkItem>,
|
|
|
|
num_workers: uint) {
|
|
|
|
// Run some workers to process the work items.
|
|
|
|
let work_items_arc = Arc::new(Mutex::new(work_items));
|
|
|
|
let mut diag_emitter = SharedEmitter::new();
|
|
|
|
let mut futures = Vec::with_capacity(num_workers);
|
|
|
|
|
|
|
|
for i in range(0, num_workers) {
|
|
|
|
let work_items_arc = work_items_arc.clone();
|
|
|
|
let diag_emitter = diag_emitter.clone();
|
2014-09-12 15:17:58 +00:00
|
|
|
let remark = sess.opts.cg.remark.clone();
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
2014-12-07 02:34:37 +00:00
|
|
|
let (tx, rx) = channel();
|
|
|
|
let mut tx = Some(tx);
|
|
|
|
futures.push(rx);
|
|
|
|
|
2014-12-14 08:05:32 +00:00
|
|
|
thread::Builder::new().name(format!("codegen-{}", i)).spawn(move |:| {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
let diag_handler = mk_handler(box diag_emitter);
|
|
|
|
|
|
|
|
// Must construct cgcx inside the proc because it has non-Send
|
|
|
|
// fields.
|
2014-09-12 15:17:58 +00:00
|
|
|
let cgcx = CodegenContext {
|
|
|
|
lto_ctxt: None,
|
|
|
|
handler: &diag_handler,
|
|
|
|
remark: remark,
|
|
|
|
};
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
|
|
|
loop {
|
|
|
|
// Avoid holding the lock for the entire duration of the match.
|
2014-12-09 04:20:03 +00:00
|
|
|
let maybe_work = work_items_arc.lock().unwrap().pop();
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
match maybe_work {
|
|
|
|
Some(work) => {
|
2014-11-26 15:07:58 +00:00
|
|
|
execute_work_item(&cgcx, work);
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
|
|
|
|
// Make sure to fail the worker so the main thread can
|
|
|
|
// tell that there were errors.
|
|
|
|
cgcx.handler.abort_if_errors();
|
|
|
|
}
|
|
|
|
None => break,
|
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
2014-12-07 02:34:37 +00:00
|
|
|
|
2014-12-23 19:53:35 +00:00
|
|
|
tx.take().unwrap().send(()).unwrap();
|
2015-01-06 05:59:45 +00:00
|
|
|
});
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2014-10-09 19:17:22 +00:00
|
|
|
let mut panicked = false;
|
2014-12-07 02:34:37 +00:00
|
|
|
for rx in futures.into_iter() {
|
2014-12-23 19:53:35 +00:00
|
|
|
match rx.recv() {
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
Ok(()) => {},
|
|
|
|
Err(_) => {
|
2014-10-09 19:17:22 +00:00
|
|
|
panicked = true;
|
run optimization and codegen on worker threads
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
2014-07-17 17:52:52 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
// Display any new diagnostics.
|
|
|
|
diag_emitter.dump(sess.diagnostic().handler());
|
|
|
|
}
|
2014-10-09 19:17:22 +00:00
|
|
|
if panicked {
|
|
|
|
sess.fatal("aborting due to worker thread panic");
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
|
|
|
|
let pname = get_cc_prog(sess);
|
2015-01-07 16:58:31 +00:00
|
|
|
let mut cmd = Command::new(&pname[]);
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2014-11-16 01:30:33 +00:00
|
|
|
cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject))
|
|
|
|
.arg(outputs.temp_path(config::OutputTypeAssembly));
|
2015-01-20 23:45:07 +00:00
|
|
|
debug!("{:?}", &cmd);
|
2014-08-11 17:33:58 +00:00
|
|
|
|
|
|
|
match cmd.output() {
|
|
|
|
Ok(prog) => {
|
|
|
|
if !prog.status.success() {
|
2015-01-07 16:58:31 +00:00
|
|
|
sess.err(&format!("linking with `{}` failed: {}",
|
2014-08-11 17:33:58 +00:00
|
|
|
pname,
|
2015-01-07 16:58:31 +00:00
|
|
|
prog.status)[]);
|
2015-01-20 23:45:07 +00:00
|
|
|
sess.note(&format!("{:?}", &cmd)[]);
|
2014-08-11 17:33:58 +00:00
|
|
|
let mut note = prog.error.clone();
|
2015-01-07 16:58:31 +00:00
|
|
|
note.push_all(&prog.output[]);
|
|
|
|
sess.note(str::from_utf8(¬e[]).unwrap());
|
2014-08-11 17:33:58 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(e) => {
|
2015-01-07 16:58:31 +00:00
|
|
|
sess.err(&format!("could not exec the linker `{}`: {}",
|
2014-08-11 17:33:58 +00:00
|
|
|
pname,
|
2015-01-07 16:58:31 +00:00
|
|
|
e)[]);
|
2014-08-11 17:33:58 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn configure_llvm(sess: &Session) {
|
|
|
|
use std::sync::{Once, ONCE_INIT};
|
2014-10-11 04:59:10 +00:00
|
|
|
static INIT: Once = ONCE_INIT;
|
2014-08-11 17:33:58 +00:00
|
|
|
|
|
|
|
// Copy what clang does by turning on loop vectorization at O2 and
|
|
|
|
// slp vectorization at O3
|
|
|
|
let vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
|
|
|
|
(sess.opts.optimize == config::Default ||
|
|
|
|
sess.opts.optimize == config::Aggressive);
|
|
|
|
let vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
|
|
|
|
sess.opts.optimize == config::Aggressive;
|
|
|
|
|
|
|
|
let mut llvm_c_strs = Vec::new();
|
|
|
|
let mut llvm_args = Vec::new();
|
|
|
|
{
|
2014-12-31 01:58:47 +00:00
|
|
|
let mut add = |&mut : arg: &str| {
|
2014-11-25 21:28:35 +00:00
|
|
|
let s = CString::from_slice(arg.as_bytes());
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm_args.push(s.as_ptr());
|
|
|
|
llvm_c_strs.push(s);
|
|
|
|
};
|
|
|
|
add("rustc"); // fake program name
|
|
|
|
if vectorize_loop { add("-vectorize-loops"); }
|
|
|
|
if vectorize_slp { add("-vectorize-slp"); }
|
|
|
|
if sess.time_llvm_passes() { add("-time-passes"); }
|
|
|
|
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
|
|
|
|
|
|
|
|
for arg in sess.opts.cg.llvm_args.iter() {
|
2015-01-07 16:58:31 +00:00
|
|
|
add(&(*arg)[]);
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-29 23:03:01 +00:00
|
|
|
INIT.call_once(|| {
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm::LLVMInitializePasses();
|
|
|
|
|
|
|
|
// Only initialize the platforms supported by Rust here, because
|
|
|
|
// using --llvm-root will have multiple platforms that rustllvm
|
|
|
|
// doesn't actually link to and it's pointless to put target info
|
|
|
|
// into the registry that Rust cannot generate machine code for.
|
|
|
|
llvm::LLVMInitializeX86TargetInfo();
|
|
|
|
llvm::LLVMInitializeX86Target();
|
|
|
|
llvm::LLVMInitializeX86TargetMC();
|
|
|
|
llvm::LLVMInitializeX86AsmPrinter();
|
|
|
|
llvm::LLVMInitializeX86AsmParser();
|
|
|
|
|
|
|
|
llvm::LLVMInitializeARMTargetInfo();
|
|
|
|
llvm::LLVMInitializeARMTarget();
|
|
|
|
llvm::LLVMInitializeARMTargetMC();
|
|
|
|
llvm::LLVMInitializeARMAsmPrinter();
|
|
|
|
llvm::LLVMInitializeARMAsmParser();
|
|
|
|
|
2014-12-12 23:39:27 +00:00
|
|
|
llvm::LLVMInitializeAArch64TargetInfo();
|
|
|
|
llvm::LLVMInitializeAArch64Target();
|
|
|
|
llvm::LLVMInitializeAArch64TargetMC();
|
|
|
|
llvm::LLVMInitializeAArch64AsmPrinter();
|
|
|
|
llvm::LLVMInitializeAArch64AsmParser();
|
|
|
|
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm::LLVMInitializeMipsTargetInfo();
|
|
|
|
llvm::LLVMInitializeMipsTarget();
|
|
|
|
llvm::LLVMInitializeMipsTargetMC();
|
|
|
|
llvm::LLVMInitializeMipsAsmPrinter();
|
|
|
|
llvm::LLVMInitializeMipsAsmParser();
|
|
|
|
|
2015-01-10 04:03:37 +00:00
|
|
|
llvm::LLVMInitializePowerPCTargetInfo();
|
|
|
|
llvm::LLVMInitializePowerPCTarget();
|
|
|
|
llvm::LLVMInitializePowerPCTargetMC();
|
|
|
|
llvm::LLVMInitializePowerPCAsmPrinter();
|
|
|
|
llvm::LLVMInitializePowerPCAsmParser();
|
|
|
|
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
|
|
|
llvm_args.as_ptr());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
|
|
|
|
mpm: llvm::PassManagerRef,
|
|
|
|
llmod: ModuleRef,
|
|
|
|
opt: llvm::CodeGenOptLevel,
|
|
|
|
no_builtins: bool) {
|
|
|
|
// Create the PassManagerBuilder for LLVM. We configure it with
|
|
|
|
// reasonable defaults and prepare it to actually populate the pass
|
|
|
|
// manager.
|
|
|
|
let builder = llvm::LLVMPassManagerBuilderCreate();
|
|
|
|
match opt {
|
|
|
|
llvm::CodeGenLevelNone => {
|
|
|
|
// Don't add lifetime intrinsics at O0
|
|
|
|
llvm::LLVMRustAddAlwaysInlinePass(builder, false);
|
|
|
|
}
|
|
|
|
llvm::CodeGenLevelLess => {
|
|
|
|
llvm::LLVMRustAddAlwaysInlinePass(builder, true);
|
|
|
|
}
|
|
|
|
// numeric values copied from clang
|
|
|
|
llvm::CodeGenLevelDefault => {
|
|
|
|
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
|
|
|
|
225);
|
|
|
|
}
|
|
|
|
llvm::CodeGenLevelAggressive => {
|
|
|
|
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
|
|
|
|
275);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
llvm::LLVMPassManagerBuilderSetOptLevel(builder, opt as c_uint);
|
|
|
|
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, no_builtins);
|
|
|
|
|
|
|
|
// Use the builder to populate the function/module pass managers.
|
|
|
|
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(builder, fpm);
|
|
|
|
llvm::LLVMPassManagerBuilderPopulateModulePassManager(builder, mpm);
|
|
|
|
llvm::LLVMPassManagerBuilderDispose(builder);
|
|
|
|
|
|
|
|
match opt {
|
|
|
|
llvm::CodeGenLevelDefault | llvm::CodeGenLevelAggressive => {
|
2014-11-25 21:28:35 +00:00
|
|
|
llvm::LLVMRustAddPass(mpm, "mergefunc\0".as_ptr() as *const _);
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
};
|
|
|
|
}
|