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_errors 0.0.0",
|
||||||
"rustc_incremental 0.0.0",
|
"rustc_incremental 0.0.0",
|
||||||
"rustc_lint 0.0.0",
|
"rustc_lint 0.0.0",
|
||||||
"rustc_llvm 0.0.0",
|
|
||||||
"rustc_metadata 0.0.0",
|
"rustc_metadata 0.0.0",
|
||||||
"rustc_mir 0.0.0",
|
"rustc_mir 0.0.0",
|
||||||
"rustc_passes 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 {
|
pub enum PrintRequest {
|
||||||
FileNames,
|
FileNames,
|
||||||
Sysroot,
|
Sysroot,
|
||||||
|
|
|
@ -22,7 +22,6 @@ rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
rustc_errors = { path = "../librustc_errors" }
|
rustc_errors = { path = "../librustc_errors" }
|
||||||
rustc_incremental = { path = "../librustc_incremental" }
|
rustc_incremental = { path = "../librustc_incremental" }
|
||||||
rustc_lint = { path = "../librustc_lint" }
|
rustc_lint = { path = "../librustc_lint" }
|
||||||
rustc_llvm = { path = "../librustc_llvm" }
|
|
||||||
rustc_metadata = { path = "../librustc_metadata" }
|
rustc_metadata = { path = "../librustc_metadata" }
|
||||||
rustc_mir = { path = "../librustc_mir" }
|
rustc_mir = { path = "../librustc_mir" }
|
||||||
rustc_passes = { path = "../librustc_passes" }
|
rustc_passes = { path = "../librustc_passes" }
|
||||||
|
|
|
@ -56,7 +56,6 @@ extern crate rustc_save_analysis;
|
||||||
extern crate rustc_trans;
|
extern crate rustc_trans;
|
||||||
extern crate rustc_typeck;
|
extern crate rustc_typeck;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate rustc_llvm as llvm;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
@ -70,7 +69,7 @@ use rustc_resolve as resolve;
|
||||||
use rustc_save_analysis as save;
|
use rustc_save_analysis as save;
|
||||||
use rustc_save_analysis::DumpHandler;
|
use rustc_save_analysis::DumpHandler;
|
||||||
use rustc_trans::back::link;
|
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::dep_graph::DepGraph;
|
||||||
use rustc::session::{self, config, Session, build_session, CompileResult};
|
use rustc::session::{self, config, Session, build_session, CompileResult};
|
||||||
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
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);
|
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
|
||||||
|
|
||||||
if sopts.debugging_opts.debug_llvm {
|
if sopts.debugging_opts.debug_llvm {
|
||||||
unsafe { llvm::LLVMRustSetDebug(1); }
|
rustc_trans::enable_llvm_debug();
|
||||||
}
|
}
|
||||||
|
|
||||||
let descriptions = diagnostics_registry();
|
let descriptions = diagnostics_registry();
|
||||||
|
@ -671,14 +670,6 @@ impl RustcDefaultCalls {
|
||||||
println!("{}", cfg);
|
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 => {
|
PrintRequest::RelocationModels => {
|
||||||
println!("Available relocation models:");
|
println!("Available relocation models:");
|
||||||
for &(name, _) in RELOC_MODEL_ARGS.iter() {
|
for &(name, _) in RELOC_MODEL_ARGS.iter() {
|
||||||
|
@ -693,6 +684,9 @@ impl RustcDefaultCalls {
|
||||||
}
|
}
|
||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => {
|
||||||
|
rustc_trans::print(*req, sess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Compilation::Stop;
|
return Compilation::Stop;
|
||||||
|
@ -730,10 +724,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
|
||||||
println!("commit-date: {}", unw(commit_date_str()));
|
println!("commit-date: {}", unw(commit_date_str()));
|
||||||
println!("host: {}", config::host_triple());
|
println!("host: {}", config::host_triple());
|
||||||
println!("release: {}", unw(release_str()));
|
println!("release: {}", unw(release_str()));
|
||||||
unsafe {
|
rustc_trans::print_version();
|
||||||
println!("LLVM version: {}.{}",
|
|
||||||
llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,9 +1017,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cg_flags.contains(&"passes=list".to_string()) {
|
if cg_flags.contains(&"passes=list".to_string()) {
|
||||||
unsafe {
|
rustc_trans::print_passes();
|
||||||
::llvm::LLVMRustPrintPasses();
|
|
||||||
}
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,24 +9,9 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use llvm::LLVMRustHasFeature;
|
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc_trans::back::write::create_target_machine;
|
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use libc::c_char;
|
use rustc_trans;
|
||||||
|
|
||||||
// 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"];
|
|
||||||
|
|
||||||
/// Add `target_feature = "..."` cfgs for a variety of platform
|
/// Add `target_feature = "..."` cfgs for a variety of platform
|
||||||
/// specific features (SSE, NEON etc.).
|
/// 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
|
/// This is performed by checking whether a whitelisted set of
|
||||||
/// features is available on the target machine, by querying LLVM.
|
/// features is available on the target machine, by querying LLVM.
|
||||||
pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
|
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");
|
let tf = Symbol::intern("target_feature");
|
||||||
for feat in whitelist {
|
|
||||||
assert_eq!(feat.chars().last(), Some('\0'));
|
for feat in rustc_trans::target_features(sess) {
|
||||||
if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
|
cfg.insert((tf, Some(feat)));
|
||||||
cfg.insert((tf, Some(Symbol::intern(&feat[..feat.len() - 1]))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let requested_features = sess.opts.cg.target_feature.split(',');
|
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 back::symbol_names::provide;
|
||||||
|
|
||||||
pub use metadata::LlvmMetadataLoader;
|
pub use metadata::LlvmMetadataLoader;
|
||||||
|
pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
|
||||||
|
|
||||||
pub mod back {
|
pub mod back {
|
||||||
pub use rustc::hir::svh;
|
pub use rustc::hir::svh;
|
||||||
|
@ -122,6 +123,7 @@ mod debuginfo;
|
||||||
mod declare;
|
mod declare;
|
||||||
mod glue;
|
mod glue;
|
||||||
mod intrinsic;
|
mod intrinsic;
|
||||||
|
mod llvm_util;
|
||||||
mod machine;
|
mod machine;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
mod meth;
|
mod meth;
|
||||||
|
@ -178,55 +180,3 @@ pub struct CrateTranslation {
|
||||||
}
|
}
|
||||||
|
|
||||||
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
|
__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