Remove (direct) rustc_llvm dependency from rustc_driver
This does not actually improve build times, since it still depends on rustc_trans, but is better layering and fits the multi-backend future slightly better.
This commit is contained in:
parent
8e4f315116
commit
e3f6e68d63
7 changed files with 139 additions and 103 deletions
1
src/Cargo.lock
generated
1
src/Cargo.lock
generated
|
@ -560,7 +560,6 @@ dependencies = [
|
|||
"rustc_errors 0.0.0",
|
||||
"rustc_incremental 0.0.0",
|
||||
"rustc_lint 0.0.0",
|
||||
"rustc_llvm 0.0.0",
|
||||
"rustc_metadata 0.0.0",
|
||||
"rustc_mir 0.0.0",
|
||||
"rustc_passes 0.0.0",
|
||||
|
|
|
@ -328,7 +328,7 @@ top_level_options!(
|
|||
}
|
||||
);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum PrintRequest {
|
||||
FileNames,
|
||||
Sysroot,
|
||||
|
|
|
@ -22,7 +22,6 @@ rustc_data_structures = { path = "../librustc_data_structures" }
|
|||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_lint = { path = "../librustc_lint" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
rustc_metadata = { path = "../librustc_metadata" }
|
||||
rustc_mir = { path = "../librustc_mir" }
|
||||
rustc_passes = { path = "../librustc_passes" }
|
||||
|
|
|
@ -56,7 +56,6 @@ extern crate rustc_save_analysis;
|
|||
extern crate rustc_trans;
|
||||
extern crate rustc_typeck;
|
||||
extern crate serialize;
|
||||
extern crate rustc_llvm as llvm;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate syntax;
|
||||
|
@ -70,7 +69,7 @@ use rustc_resolve as resolve;
|
|||
use rustc_save_analysis as save;
|
||||
use rustc_save_analysis::DumpHandler;
|
||||
use rustc_trans::back::link;
|
||||
use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
|
||||
use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::session::{self, config, Session, build_session, CompileResult};
|
||||
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
||||
|
@ -182,7 +181,7 @@ pub fn run_compiler<'a>(args: &[String],
|
|||
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
|
||||
|
||||
if sopts.debugging_opts.debug_llvm {
|
||||
unsafe { llvm::LLVMRustSetDebug(1); }
|
||||
rustc_trans::enable_llvm_debug();
|
||||
}
|
||||
|
||||
let descriptions = diagnostics_registry();
|
||||
|
@ -671,14 +670,6 @@ impl RustcDefaultCalls {
|
|||
println!("{}", cfg);
|
||||
}
|
||||
}
|
||||
PrintRequest::TargetCPUs => {
|
||||
let tm = create_target_machine(sess);
|
||||
unsafe { llvm::LLVMRustPrintTargetCPUs(tm); }
|
||||
}
|
||||
PrintRequest::TargetFeatures => {
|
||||
let tm = create_target_machine(sess);
|
||||
unsafe { llvm::LLVMRustPrintTargetFeatures(tm); }
|
||||
}
|
||||
PrintRequest::RelocationModels => {
|
||||
println!("Available relocation models:");
|
||||
for &(name, _) in RELOC_MODEL_ARGS.iter() {
|
||||
|
@ -693,6 +684,9 @@ impl RustcDefaultCalls {
|
|||
}
|
||||
println!("");
|
||||
}
|
||||
PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => {
|
||||
rustc_trans::print(*req, sess);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Compilation::Stop;
|
||||
|
@ -730,10 +724,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
|
|||
println!("commit-date: {}", unw(commit_date_str()));
|
||||
println!("host: {}", config::host_triple());
|
||||
println!("release: {}", unw(release_str()));
|
||||
unsafe {
|
||||
println!("LLVM version: {}.{}",
|
||||
llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
|
||||
}
|
||||
rustc_trans::print_version();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1026,9 +1017,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
|||
}
|
||||
|
||||
if cg_flags.contains(&"passes=list".to_string()) {
|
||||
unsafe {
|
||||
::llvm::LLVMRustPrintPasses();
|
||||
}
|
||||
rustc_trans::print_passes();
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,24 +9,9 @@
|
|||
// except according to those terms.
|
||||
|
||||
use syntax::ast;
|
||||
use llvm::LLVMRustHasFeature;
|
||||
use rustc::session::Session;
|
||||
use rustc_trans::back::write::create_target_machine;
|
||||
use syntax::symbol::Symbol;
|
||||
use libc::c_char;
|
||||
|
||||
// WARNING: the features must be known to LLVM or the feature
|
||||
// detection code will walk past the end of the feature array,
|
||||
// leading to crashes.
|
||||
|
||||
const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];
|
||||
|
||||
const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
|
||||
"sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
|
||||
"ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
|
||||
"sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"];
|
||||
|
||||
const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];
|
||||
use rustc_trans;
|
||||
|
||||
/// Add `target_feature = "..."` cfgs for a variety of platform
|
||||
/// specific features (SSE, NEON etc.).
|
||||
|
@ -34,21 +19,10 @@ const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];
|
|||
/// This is performed by checking whether a whitelisted set of
|
||||
/// features is available on the target machine, by querying LLVM.
|
||||
pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
|
||||
let target_machine = create_target_machine(sess);
|
||||
|
||||
let whitelist = match &*sess.target.target.arch {
|
||||
"arm" => ARM_WHITELIST,
|
||||
"x86" | "x86_64" => X86_WHITELIST,
|
||||
"hexagon" => HEXAGON_WHITELIST,
|
||||
_ => &[],
|
||||
};
|
||||
|
||||
let tf = Symbol::intern("target_feature");
|
||||
for feat in whitelist {
|
||||
assert_eq!(feat.chars().last(), Some('\0'));
|
||||
if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
|
||||
cfg.insert((tf, Some(Symbol::intern(&feat[..feat.len() - 1]))));
|
||||
}
|
||||
|
||||
for feat in rustc_trans::target_features(sess) {
|
||||
cfg.insert((tf, Some(feat)));
|
||||
}
|
||||
|
||||
let requested_features = sess.opts.cg.target_feature.split(',');
|
||||
|
|
|
@ -72,6 +72,7 @@ pub use base::trans_crate;
|
|||
pub use back::symbol_names::provide;
|
||||
|
||||
pub use metadata::LlvmMetadataLoader;
|
||||
pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
|
||||
|
||||
pub mod back {
|
||||
pub use rustc::hir::svh;
|
||||
|
@ -122,6 +123,7 @@ mod debuginfo;
|
|||
mod declare;
|
||||
mod glue;
|
||||
mod intrinsic;
|
||||
mod llvm_util;
|
||||
mod machine;
|
||||
mod metadata;
|
||||
mod meth;
|
||||
|
@ -178,55 +180,3 @@ pub struct CrateTranslation {
|
|||
}
|
||||
|
||||
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
|
||||
|
||||
use rustc::session::Session;
|
||||
pub fn init(sess: &Session) {
|
||||
unsafe {
|
||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||
use std::sync::Once;
|
||||
static INIT: Once = Once::new();
|
||||
static mut POISONED: bool = false;
|
||||
INIT.call_once(|| {
|
||||
if llvm::LLVMStartMultithreaded() != 1 {
|
||||
// use an extra bool to make sure that all future usage of LLVM
|
||||
// cannot proceed despite the Once not running more than once.
|
||||
POISONED = true;
|
||||
}
|
||||
|
||||
configure_llvm(sess);
|
||||
});
|
||||
|
||||
if POISONED {
|
||||
bug!("couldn't enable multi-threaded LLVM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use std::ffi::CString;
|
||||
use libc::c_int;
|
||||
unsafe fn configure_llvm(sess: &Session) {
|
||||
let mut llvm_c_strs = Vec::new();
|
||||
let mut llvm_args = Vec::new();
|
||||
|
||||
{
|
||||
let mut add = |arg: &str| {
|
||||
let s = CString::new(arg).unwrap();
|
||||
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"); }
|
||||
|
||||
for arg in &sess.opts.cg.llvm_args {
|
||||
add(&(*arg));
|
||||
}
|
||||
}
|
||||
|
||||
llvm::LLVMInitializePasses();
|
||||
|
||||
llvm::initialize_available_targets();
|
||||
|
||||
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
||||
llvm_args.as_ptr());
|
||||
}
|
||||
|
|
125
src/librustc_trans/llvm_util.rs
Normal file
125
src/librustc_trans/llvm_util.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// 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 syntax_pos::symbol::Symbol;
|
||||
use back::write::create_target_machine;
|
||||
use llvm;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::PrintRequest;
|
||||
use libc::{c_int, c_char};
|
||||
use std::ffi::CString;
|
||||
|
||||
pub fn init(sess: &Session) {
|
||||
unsafe {
|
||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||
use std::sync::Once;
|
||||
static INIT: Once = Once::new();
|
||||
static mut POISONED: bool = false;
|
||||
INIT.call_once(|| {
|
||||
if llvm::LLVMStartMultithreaded() != 1 {
|
||||
// use an extra bool to make sure that all future usage of LLVM
|
||||
// cannot proceed despite the Once not running more than once.
|
||||
POISONED = true;
|
||||
}
|
||||
|
||||
configure_llvm(sess);
|
||||
});
|
||||
|
||||
if POISONED {
|
||||
bug!("couldn't enable multi-threaded LLVM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn configure_llvm(sess: &Session) {
|
||||
let mut llvm_c_strs = Vec::new();
|
||||
let mut llvm_args = Vec::new();
|
||||
|
||||
{
|
||||
let mut add = |arg: &str| {
|
||||
let s = CString::new(arg).unwrap();
|
||||
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"); }
|
||||
|
||||
for arg in &sess.opts.cg.llvm_args {
|
||||
add(&(*arg));
|
||||
}
|
||||
}
|
||||
|
||||
llvm::LLVMInitializePasses();
|
||||
|
||||
llvm::initialize_available_targets();
|
||||
|
||||
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
||||
llvm_args.as_ptr());
|
||||
}
|
||||
|
||||
// WARNING: the features must be known to LLVM or the feature
|
||||
// detection code will walk past the end of the feature array,
|
||||
// leading to crashes.
|
||||
|
||||
const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];
|
||||
|
||||
const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
|
||||
"sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
|
||||
"ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
|
||||
"sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"];
|
||||
|
||||
const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];
|
||||
|
||||
pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
||||
let target_machine = create_target_machine(sess);
|
||||
|
||||
let whitelist = match &*sess.target.target.arch {
|
||||
"arm" => ARM_WHITELIST,
|
||||
"x86" | "x86_64" => X86_WHITELIST,
|
||||
"hexagon" => HEXAGON_WHITELIST,
|
||||
_ => &[],
|
||||
};
|
||||
|
||||
let mut features = Vec::new();
|
||||
for feat in whitelist {
|
||||
assert_eq!(feat.chars().last(), Some('\0'));
|
||||
if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
|
||||
features.push(Symbol::intern(&feat[..feat.len() - 1]));
|
||||
}
|
||||
}
|
||||
features
|
||||
}
|
||||
|
||||
pub fn print_version() {
|
||||
unsafe {
|
||||
println!("LLVM version: {}.{}",
|
||||
llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_passes() {
|
||||
unsafe { llvm::LLVMRustPrintPasses(); }
|
||||
}
|
||||
|
||||
pub fn print(req: PrintRequest, sess: &Session) {
|
||||
let tm = create_target_machine(sess);
|
||||
unsafe {
|
||||
match req {
|
||||
PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
|
||||
PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
|
||||
_ => bug!("rustc_trans can't handle print request: {:?}", req),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_llvm_debug() {
|
||||
unsafe { llvm::LLVMRustSetDebug(1); }
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue