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;
|
2015-06-30 06:16:24 +00:00
|
|
|
use back::link::{get_linker, remove};
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
use session::config::{OutputFilenames, Passes, SomePasses, AllPasses};
|
2014-11-16 01:30:33 +00:00
|
|
|
use session::Session;
|
2015-09-30 17:08:37 +00:00
|
|
|
use session::config::{self, OutputType};
|
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;
|
2015-02-27 05:00:43 +00:00
|
|
|
use util::common::path2cstr;
|
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;
|
2015-05-13 20:00:17 +00:00
|
|
|
use syntax::diagnostic::{Emitter, Handler, Level};
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-09-30 17:08:37 +00:00
|
|
|
use std::collections::HashMap;
|
2015-02-18 06:47:40 +00:00
|
|
|
use std::ffi::{CStr, CString};
|
2015-02-27 05:00:43 +00:00
|
|
|
use std::fs;
|
2015-09-30 17:08:37 +00:00
|
|
|
use std::path::{Path, PathBuf};
|
2014-08-11 17:33:58 +00:00
|
|
|
use std::ptr;
|
|
|
|
use std::str;
|
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
|
|
|
|
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-10-24 02:42:42 +00:00
|
|
|
panic!(handler.fatal(&msg[..]));
|
2014-08-11 17:33:58 +00:00
|
|
|
} else {
|
2015-02-18 06:47:40 +00:00
|
|
|
let err = CStr::from_ptr(cstr).to_bytes();
|
2015-02-02 02:53:25 +00:00
|
|
|
let err = String::from_utf8_lossy(err).to_string();
|
2014-11-25 21:28:35 +00:00
|
|
|
libc::free(cstr as *mut _);
|
2015-10-24 02:42:42 +00:00
|
|
|
panic!(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-02-27 05:00:43 +00:00
|
|
|
let output_c = path2cstr(output);
|
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
|
2015-05-08 15:12:29 +00:00
|
|
|
// child thread because we need to make sure that the messages are seen even
|
|
|
|
// if the child thread 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();
|
2015-01-31 17:20:46 +00:00
|
|
|
for diag in &*buffer {
|
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 diag.code {
|
|
|
|
Some(ref code) => {
|
|
|
|
handler.emit_with_code(None,
|
2015-02-20 19:08:14 +00:00
|
|
|
&diag.msg,
|
2015-02-18 19:48:57 +00:00
|
|
|
&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-02-20 19:08:14 +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
|
|
|
|
2015-07-16 22:48:16 +00:00
|
|
|
pub 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-02-18 19:48:57 +00:00
|
|
|
Some(ref s) => &s[..],
|
2015-02-20 19:08:14 +00:00
|
|
|
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-02-20 19:08:14 +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;
|
|
|
|
|
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-02-18 19:48:57 +00:00
|
|
|
Some(ref s) => &s[..],
|
2015-02-20 19:08:14 +00:00
|
|
|
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-02-20 19:08:14 +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-02-20 19:08:14 +00:00
|
|
|
let triple = &sess.target.target.llvm_target;
|
2014-10-29 01:58:46 +00:00
|
|
|
|
|
|
|
let tm = unsafe {
|
2015-02-18 06:47:40 +00:00
|
|
|
let triple = CString::new(triple.as_bytes()).unwrap();
|
2014-11-25 21:28:35 +00:00
|
|
|
let cpu = match sess.opts.cg.target_cpu {
|
2015-02-02 02:53:25 +00:00
|
|
|
Some(ref s) => &**s,
|
|
|
|
None => &*sess.target.target.options.cpu
|
2014-11-25 21:28:35 +00:00
|
|
|
};
|
2015-02-18 06:47:40 +00:00
|
|
|
let cpu = CString::new(cpu.as_bytes()).unwrap();
|
|
|
|
let features = CString::new(target_feature(sess).as_bytes()).unwrap();
|
2014-11-25 21:28:35 +00:00
|
|
|
llvm::LLVMRustCreateTargetMachine(
|
|
|
|
triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
|
|
|
|
code_model,
|
|
|
|
reloc_model,
|
|
|
|
opt_level,
|
|
|
|
use_softfp,
|
|
|
|
!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)]
|
2015-07-22 23:22:51 +00:00
|
|
|
pub struct ModuleConfig {
|
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 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,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
vectorize_loop: bool,
|
|
|
|
vectorize_slp: bool,
|
|
|
|
merge_functions: bool,
|
2015-11-20 00:07:09 +00:00
|
|
|
inline_threshold: Option<usize>
|
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-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,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
vectorize_loop: false,
|
|
|
|
vectorize_slp: false,
|
|
|
|
merge_functions: false,
|
2015-11-20 00:07:09 +00:00
|
|
|
inline_threshold: None
|
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();
|
2015-11-20 00:07:09 +00:00
|
|
|
self.inline_threshold = sess.opts.cg.inline_threshold;
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
|
|
|
|
// Copy what clang does by turning on loop vectorization at O2 and
|
|
|
|
// slp vectorization at O3. Otherwise configure other optimization aspects
|
|
|
|
// of this pass manager builder.
|
|
|
|
self.vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
|
|
|
|
(sess.opts.optimize == config::Default ||
|
|
|
|
sess.opts.optimize == config::Aggressive);
|
|
|
|
self.vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
|
|
|
|
sess.opts.optimize == config::Aggressive;
|
|
|
|
|
|
|
|
self.merge_functions = sess.opts.optimize == config::Default ||
|
|
|
|
sess.opts.optimize == config::Aggressive;
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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,
|
2015-04-08 19:52:58 +00:00
|
|
|
// LLVM passes added by plugins.
|
|
|
|
plugin_passes: Vec<String>,
|
2014-09-12 15:17:58 +00:00
|
|
|
// LLVM optimizations for which we want to print remarks.
|
|
|
|
remark: Passes,
|
2015-10-26 20:03:03 +00:00
|
|
|
// Worker thread number
|
|
|
|
worker: usize,
|
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(),
|
2015-04-08 19:52:58 +00:00
|
|
|
plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
|
2014-09-12 15:17:58 +00:00
|
|
|
remark: sess.opts.cg.remark.clone(),
|
2015-10-26 20:03:03 +00:00
|
|
|
worker: 0,
|
2014-09-12 15:17:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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>,
|
|
|
|
}
|
|
|
|
|
2015-01-22 18:43:39 +00:00
|
|
|
unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>,
|
2015-05-26 08:34:50 +00:00
|
|
|
msg: &'b str,
|
|
|
|
cookie: c_uint) {
|
2014-09-27 08:33:36 +00:00
|
|
|
use syntax::codemap::ExpnId;
|
|
|
|
|
|
|
|
match cgcx.lto_ctxt {
|
|
|
|
Some((sess, _)) => {
|
2015-04-21 00:51:10 +00:00
|
|
|
sess.codemap().with_expn_info(ExpnId::from_u32(cookie), |info| match info {
|
2015-01-22 18:43:39 +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-22 18:43:39 +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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 18:43:39 +00:00
|
|
|
unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
|
|
|
|
user: *const c_void,
|
|
|
|
cookie: c_uint) {
|
2015-07-24 01:04:55 +00:00
|
|
|
let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars);
|
2015-01-22 18:43:39 +00:00
|
|
|
|
|
|
|
let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
|
|
|
|
.expect("non-UTF8 SMDiagnostic");
|
|
|
|
|
2015-02-18 19:48:57 +00:00
|
|
|
report_inline_asm(cgcx, &msg[..], cookie);
|
2015-01-22 18:43:39 +00:00
|
|
|
}
|
|
|
|
|
2014-09-12 15:17:58 +00:00
|
|
|
unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
|
2015-07-24 01:04:55 +00:00
|
|
|
let HandlerFreeVars { llcx, cgcx } = *(user as *const HandlerFreeVars);
|
2014-09-12 15:17:58 +00:00
|
|
|
|
|
|
|
match llvm::diagnostic::Diagnostic::unpack(info) {
|
2015-01-22 18:43:39 +00:00
|
|
|
llvm::diagnostic::InlineAsm(inline) => {
|
|
|
|
report_inline_asm(cgcx,
|
2015-02-02 02:53:25 +00:00
|
|
|
&*llvm::twine_to_string(inline.message),
|
2015-01-22 18:43:39 +00:00
|
|
|
inline.cookie);
|
|
|
|
}
|
|
|
|
|
2014-09-12 15:17:58 +00:00
|
|
|
llvm::diagnostic::Optimization(opt) => {
|
2015-02-18 06:47:40 +00:00
|
|
|
let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes())
|
2014-11-25 21:28:35 +00:00
|
|
|
.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);
|
2015-02-02 02:53:25 +00:00
|
|
|
cgcx.handler.note(&format!("optimization {} for {} at {}: {}",
|
|
|
|
opt.kind.describe(),
|
|
|
|
pass_name,
|
|
|
|
if loc.is_empty() { "[unknown]" } else { &*loc },
|
|
|
|
llvm::twine_to_string(opt.message)));
|
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);
|
2015-01-22 18:43:39 +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);
|
2015-02-02 02:53:25 +00:00
|
|
|
let out = output_names.with_extension(&ext);
|
2015-02-27 05:00:43 +00:00
|
|
|
let out = path2cstr(&out);
|
2014-11-25 21:28:35 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
if config.opt_level.is_some() {
|
|
|
|
// 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.
|
|
|
|
let addpass = |pass: &str| {
|
|
|
|
let pass = CString::new(pass).unwrap();
|
|
|
|
llvm::LLVMRustAddPass(fpm, pass.as_ptr())
|
|
|
|
};
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
if !config.no_verify { assert!(addpass("verify")); }
|
|
|
|
if !config.no_prepopulate_passes {
|
|
|
|
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
|
|
|
|
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
|
|
|
|
with_llvm_pmb(llmod, &config, &mut |b| {
|
|
|
|
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
|
|
|
|
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
|
|
|
|
})
|
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
for pass in &config.passes {
|
|
|
|
if !addpass(pass) {
|
|
|
|
cgcx.handler.warn(&format!("unknown pass `{}`, ignoring",
|
|
|
|
pass));
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
2015-07-22 23:22:51 +00:00
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
for pass in &cgcx.plugin_passes {
|
|
|
|
if !addpass(pass) {
|
|
|
|
cgcx.handler.err(&format!("a plugin asked for LLVM pass \
|
|
|
|
`{}` but LLVM does not \
|
|
|
|
recognize it", pass));
|
2015-04-08 19:52:58 +00:00
|
|
|
}
|
2015-07-22 23:22:51 +00:00
|
|
|
}
|
2015-04-08 19:52:58 +00:00
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
cgcx.handler.abort_if_errors();
|
2015-04-08 19:52:58 +00:00
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
// Finally, run the actual optimization passes
|
2015-10-26 20:03:03 +00:00
|
|
|
time(config.time_passes, &format!("llvm function passes [{}]", cgcx.worker), ||
|
2015-07-22 23:22:51 +00:00
|
|
|
llvm::LLVMRustRunFunctionPassManager(fpm, llmod));
|
2015-10-26 20:03:03 +00:00
|
|
|
time(config.time_passes, &format!("llvm module passes [{}]", cgcx.worker), ||
|
2015-07-22 23:22:51 +00:00
|
|
|
llvm::LLVMRunPassManager(mpm, llmod));
|
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
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
// Deallocate managers that we're now done with
|
|
|
|
llvm::LLVMDisposePassManager(fpm);
|
|
|
|
llvm::LLVMDisposePassManager(mpm);
|
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
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
match cgcx.lto_ctxt {
|
|
|
|
Some((sess, reachable)) if sess.lto() => {
|
2015-06-25 17:07:01 +00:00
|
|
|
time(sess.time_passes(), "all lto passes", ||
|
2015-09-21 15:33:17 +00:00
|
|
|
lto::run(sess, llmod, tm, reachable, &config,
|
|
|
|
&name_extra, &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
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
if config.emit_lto_bc {
|
|
|
|
let name = format!("{}.lto.bc", name_extra);
|
|
|
|
let out = output_names.with_extension(&name);
|
|
|
|
let out = path2cstr(&out);
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.emit_bc {
|
|
|
|
let ext = format!("{}.bc", name_extra);
|
2015-02-02 02:53:25 +00:00
|
|
|
let out = output_names.with_extension(&ext);
|
2015-02-27 05:00:43 +00:00
|
|
|
let out = path2cstr(&out);
|
2014-11-25 21:28:35 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-10-26 20:03:03 +00:00
|
|
|
time(config.time_passes, &format!("codegen passes [{}]", cgcx.worker), || {
|
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_ir {
|
|
|
|
let ext = format!("{}.ll", name_extra);
|
2015-02-02 02:53:25 +00:00
|
|
|
let out = output_names.with_extension(&ext);
|
2015-02-27 05:00:43 +00:00
|
|
|
let out = path2cstr(&out);
|
2014-11-25 21:28:35 +00:00
|
|
|
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
|
|
|
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
llvm::LLVMDisposePassManager(cpm);
|
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-02-20 19:08:14 +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| {
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +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-02-20 19:08:14 +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,
|
2015-09-30 17:08:37 +00:00
|
|
|
output_types: &HashMap<OutputType, Option<PathBuf>>,
|
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
|
|
|
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) &&
|
2015-09-30 17:08:37 +00:00
|
|
|
sess.opts.output_types.contains_key(&OutputType::Exe);
|
2015-07-07 01:21:57 +00:00
|
|
|
let needs_crate_object =
|
2015-09-30 17:08:37 +00:00
|
|
|
sess.opts.output_types.contains_key(&OutputType::Exe);
|
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;
|
|
|
|
}
|
|
|
|
|
2015-09-30 17:08:37 +00:00
|
|
|
for output_type in output_types.keys() {
|
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 *output_type {
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::Bitcode => { modules_config.emit_bc = true; },
|
|
|
|
OutputType::LlvmAssembly => { modules_config.emit_ir = true; },
|
|
|
|
OutputType::Assembly => {
|
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.
|
2015-09-30 17:08:37 +00:00
|
|
|
if !sess.opts.output_types.contains_key(&OutputType::Assembly) {
|
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
|
|
|
},
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::Object => { modules_config.emit_obj = true; },
|
|
|
|
OutputType::Exe => {
|
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;
|
|
|
|
},
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::DepInfo => {}
|
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);
|
|
|
|
|
|
|
|
|
2015-05-08 15:12:29 +00:00
|
|
|
// Populate a buffer with a list of codegen threads. Items are processed in
|
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
|
|
|
// 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-02-20 19:08:14 +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.
|
2015-02-10 18:02:09 +00:00
|
|
|
let copy_gracefully = |from: &Path, to: &Path| {
|
|
|
|
if let Err(e) = fs::copy(from, to) {
|
|
|
|
sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e));
|
|
|
|
}
|
|
|
|
};
|
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
|
|
|
|
2015-09-30 17:08:37 +00:00
|
|
|
let copy_if_one_unit = |ext: &str,
|
|
|
|
output_type: 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
|
|
|
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`.
|
2015-07-07 01:21:57 +00:00
|
|
|
copy_gracefully(&crate_output.with_extension(ext),
|
|
|
|
&crate_output.path(output_type));
|
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));
|
|
|
|
}
|
2015-09-30 17:08:37 +00:00
|
|
|
} else if crate_output.outputs.contains_key(&output_type) {
|
|
|
|
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
|
|
|
// no good solution for this case, so warn the user.
|
|
|
|
sess.warn(&format!("ignoring emit path because multiple .{} files \
|
|
|
|
were produced", ext));
|
|
|
|
} else if crate_output.single_output_file.is_some() {
|
|
|
|
// 3) Multiple codegen units, with `-o some_name`. We have
|
|
|
|
// no good solution for this case, so warn the user.
|
|
|
|
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 {
|
2015-09-30 17:08:37 +00:00
|
|
|
// 4) Multiple codegen units, but no explicit 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
|
|
|
};
|
|
|
|
|
|
|
|
// 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;
|
2015-07-07 01:21:57 +00:00
|
|
|
let mut user_wants_objects = false;
|
2015-09-30 17:08:37 +00:00
|
|
|
for output_type in output_types.keys() {
|
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 *output_type {
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::Bitcode => {
|
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.
|
2015-09-30 17:08:37 +00:00
|
|
|
copy_if_one_unit("0.bc", OutputType::Bitcode, true);
|
2014-11-16 01:30:33 +00:00
|
|
|
}
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::LlvmAssembly => {
|
|
|
|
copy_if_one_unit("0.ll", OutputType::LlvmAssembly, false);
|
2014-11-16 01:30:33 +00:00
|
|
|
}
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::Assembly => {
|
|
|
|
copy_if_one_unit("0.s", OutputType::Assembly, false);
|
2014-11-16 01:30:33 +00:00
|
|
|
}
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::Object => {
|
2015-07-07 01:21:57 +00:00
|
|
|
user_wants_objects = true;
|
2015-09-30 17:08:37 +00:00
|
|
|
copy_if_one_unit("0.o", OutputType::Object, true);
|
2014-11-16 01:30:33 +00:00
|
|
|
}
|
2015-09-30 17:08:37 +00:00
|
|
|
OutputType::Exe |
|
|
|
|
OutputType::DepInfo => {}
|
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);
|
|
|
|
|
2015-07-07 01:21:57 +00:00
|
|
|
let keep_numbered_objects = needs_crate_object ||
|
|
|
|
(user_wants_objects && sess.opts.cg.codegen_units > 1);
|
|
|
|
|
2015-01-26 21:05:07 +00:00
|
|
|
for i in 0..trans.modules.len() {
|
2015-07-07 01:21:57 +00:00
|
|
|
if modules_config.emit_obj && !keep_numbered_objects {
|
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!("{}.o", i);
|
2015-07-07 01:21:57 +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-07-07 01:21:57 +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?
|
2015-02-28 21:40:39 +00:00
|
|
|
if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
|
|
|
|
unsafe { llvm::LLVMRustPrintPassTimings(); }
|
|
|
|
}
|
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
|
|
|
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);
|
|
|
|
|
|
|
|
// Since we're running single-threaded, we can pass the session to
|
|
|
|
// the proc, allowing `optimize_and_codegen` to perform LTO.
|
2015-06-11 02:33:04 +00:00
|
|
|
for work in work_items.into_iter().rev() {
|
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>,
|
2015-03-26 00:06:52 +00:00
|
|
|
num_workers: usize) {
|
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
|
|
|
// 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);
|
|
|
|
|
2015-01-26 20:46:12 +00:00
|
|
|
for i in 0..num_workers {
|
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 work_items_arc = work_items_arc.clone();
|
|
|
|
let diag_emitter = diag_emitter.clone();
|
2015-04-08 19:52:58 +00:00
|
|
|
let plugin_passes = sess.plugin_llvm_passes.borrow().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);
|
|
|
|
|
2015-02-01 17:44:15 +00:00
|
|
|
thread::Builder::new().name(format!("codegen-{}", i)).spawn(move || {
|
2015-05-13 20:00:17 +00:00
|
|
|
let diag_handler = Handler::with_emitter(true, box diag_emitter);
|
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
|
|
|
|
|
|
|
// 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,
|
2015-04-08 19:52:58 +00:00
|
|
|
plugin_passes: plugin_passes,
|
2014-09-12 15:17:58 +00:00
|
|
|
remark: remark,
|
2015-10-26 20:03:03 +00:00
|
|
|
worker: i,
|
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
|
|
|
|
|
|
|
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-02-17 23:24:34 +00:00
|
|
|
}).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
|
|
|
}
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2014-10-09 19:17:22 +00:00
|
|
|
let mut panicked = false;
|
2015-02-01 01:03:04 +00:00
|
|
|
for rx in futures {
|
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) {
|
2015-06-30 06:16:24 +00:00
|
|
|
let (pname, mut cmd) = get_linker(sess);
|
2014-08-11 17:33:58 +00:00
|
|
|
|
2015-09-30 17:08:37 +00:00
|
|
|
cmd.arg("-c").arg("-o").arg(&outputs.path(OutputType::Object))
|
|
|
|
.arg(&outputs.temp_path(OutputType::Assembly));
|
2015-02-27 05:00:43 +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-02-20 19:08:14 +00:00
|
|
|
prog.status));
|
|
|
|
sess.note(&format!("{:?}", &cmd));
|
2015-02-27 05:00:43 +00:00
|
|
|
let mut note = prog.stderr.clone();
|
2015-12-03 01:31:49 +00:00
|
|
|
note.extend_from_slice(&prog.stdout);
|
2015-02-18 19:48:57 +00:00
|
|
|
sess.note(str::from_utf8(¬e[..]).unwrap());
|
2014-08-11 17:33:58 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(e) => {
|
2015-06-30 06:16:24 +00:00
|
|
|
sess.err(&format!("could not exec the linker `{}`: {}", pname, e));
|
2014-08-11 17:33:58 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-16 22:48:16 +00:00
|
|
|
pub unsafe fn configure_llvm(sess: &Session) {
|
2014-08-11 17:33:58 +00:00
|
|
|
let mut llvm_c_strs = Vec::new();
|
|
|
|
let mut llvm_args = Vec::new();
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
|
2014-08-11 17:33:58 +00:00
|
|
|
{
|
2015-02-01 17:44:15 +00:00
|
|
|
let mut add = |arg: &str| {
|
2015-02-18 06:47:40 +00:00
|
|
|
let s = CString::new(arg).unwrap();
|
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 sess.time_llvm_passes() { add("-time-passes"); }
|
|
|
|
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
|
|
|
|
|
2015-01-26 21:39:51 +00:00
|
|
|
// FIXME #21627 disable faulty FastISel on AArch64 (even for -O0)
|
2015-02-02 02:53:25 +00:00
|
|
|
if sess.target.target.arch == "aarch64" { add("-fast-isel=0"); }
|
2015-01-26 21:39:51 +00:00
|
|
|
|
2015-01-31 17:20:46 +00:00
|
|
|
for arg in &sess.opts.cg.llvm_args {
|
2015-02-20 19:08:14 +00:00
|
|
|
add(&(*arg));
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-16 22:48:16 +00:00
|
|
|
llvm::LLVMInitializePasses();
|
|
|
|
|
2015-08-22 04:43:56 +00:00
|
|
|
llvm::initialize_available_targets();
|
2015-07-16 22:48:16 +00:00
|
|
|
|
|
|
|
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
|
|
|
llvm_args.as_ptr());
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
|
|
|
|
config: &ModuleConfig,
|
|
|
|
f: &mut FnMut(llvm::PassManagerBuilderRef)) {
|
2014-08-11 17:33:58 +00:00
|
|
|
// Create the PassManagerBuilder for LLVM. We configure it with
|
|
|
|
// reasonable defaults and prepare it to actually populate the pass
|
|
|
|
// manager.
|
|
|
|
let builder = llvm::LLVMPassManagerBuilderCreate();
|
2015-07-22 23:22:51 +00:00
|
|
|
let opt = config.opt_level.unwrap_or(llvm::CodeGenLevelNone);
|
2015-11-20 00:07:09 +00:00
|
|
|
let inline_threshold = config.inline_threshold;
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
|
|
|
|
llvm::LLVMRustConfigurePassManagerBuilder(builder, opt,
|
|
|
|
config.merge_functions,
|
|
|
|
config.vectorize_slp,
|
|
|
|
config.vectorize_loop);
|
|
|
|
|
|
|
|
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
|
|
|
|
|
|
|
|
// Here we match what clang does (kinda). For O0 we only inline
|
|
|
|
// always-inline functions (but don't add lifetime intrinsics), at O1 we
|
|
|
|
// inline with lifetime intrinsics, and O2+ we add an inliner with a
|
|
|
|
// thresholds copied from clang.
|
2015-11-20 00:07:09 +00:00
|
|
|
match (opt, inline_threshold) {
|
|
|
|
(_, Some(t)) => {
|
|
|
|
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
|
|
|
|
}
|
|
|
|
(llvm::CodeGenLevelNone, _) => {
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm::LLVMRustAddAlwaysInlinePass(builder, false);
|
|
|
|
}
|
2015-11-20 00:07:09 +00:00
|
|
|
(llvm::CodeGenLevelLess, _) => {
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm::LLVMRustAddAlwaysInlinePass(builder, true);
|
|
|
|
}
|
2015-11-20 00:07:09 +00:00
|
|
|
(llvm::CodeGenLevelDefault, _) => {
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
2015-11-20 00:07:09 +00:00
|
|
|
(llvm::CodeGenLevelAggressive, _) => {
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
|
2014-08-11 17:33:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-22 23:22:51 +00:00
|
|
|
f(builder);
|
2014-08-11 17:33:58 +00:00
|
|
|
llvm::LLVMPassManagerBuilderDispose(builder);
|
|
|
|
}
|