-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #41565 - rkruppe:llvm-sys, r=eddyb
Make only rustc_trans depend on rustc_llvm With these changes, only rustc_trans depends directly on rustc_llvm (and no crate gained a new dependency on trans). This means changing LLVM doesn't rebuild librustc or rustc_metadata, only rustc_trans, rustc_driver and the rustc executable Also, rustc_driver technically doesn't know about LLVM any more (of course, it still handles a ton of options that conceptually refer to LLVM, but it delegates their implementation to trans). What I *didn't* implement was merging most or all of rustc_llvm into rustc_trans. I ran into a nasty bug, which was probably just a silly typo somewhere but I probably won't have the time to figure it out in the next week or two. I opened #41699 for that step. Fixes #41473
- 1.85.0
- 1.84.1
- 1.84.0
- 1.83.0
- 1.82.0
- 1.81.0
- 1.80.1
- 1.80.0
- 1.79.0
- 1.78.0
- 1.77.2
- 1.77.1
- 1.77.0
- 1.76.0
- 1.75.0
- 1.74.1
- 1.74.0
- 1.73.0
- 1.72.1
- 1.72.0
- 1.71.1
- 1.71.0
- 1.70.0
- 1.69.0
- 1.68.2
- 1.68.1
- 1.68.0
- 1.67.1
- 1.67.0
- 1.66.1
- 1.66.0
- 1.65.0
- 1.64.0
- 1.63.0
- 1.62.1
- 1.62.0
- 1.61.0
- 1.60.0
- 1.59.0
- 1.58.1
- 1.58.0
- 1.57.0
- 1.56.1
- 1.56.0
- 1.55.0
- 1.54.0
- 1.53.0
- 1.52.1
- 1.52.0
- 1.51.0
- 1.50.0
- 1.49.0
- 1.48.0
- 1.47.0
- 1.46.0
- 1.45.2
- 1.45.1
- 1.45.0
- 1.44.1
- 1.44.0
- 1.43.1
- 1.43.0
- 1.42.0
- 1.41.1
- 1.41.0
- 1.40.0
- 1.39.0
- 1.38.0
- 1.37.0
- 1.36.0
- 1.35.0
- 1.34.2
- 1.34.1
- 1.34.0
- 1.33.0
- 1.32.0
- 1.31.1
- 1.31.0
- 1.30.1
- 1.30.0
- 1.29.2
- 1.29.1
- 1.29.0
- 1.28.0
- 1.27.2
- 1.27.1
- 1.27.0
- 1.26.2
- 1.26.1
- 1.26.0
- 1.25.0
- 1.24.1
- 1.24.0
- 1.23.0
- 1.22.1
- 1.22.0
- 1.21.0
- 1.20.0
- 1.19.0
Showing
28 changed files
with
425 additions
and
327 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// 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; | ||
|
||
use std::sync::atomic::{AtomicBool, Ordering}; | ||
use std::sync::Once; | ||
|
||
pub fn init(sess: &Session) { | ||
unsafe { | ||
// Before we touch LLVM, make sure that multithreading is enabled. | ||
static POISONED: AtomicBool = AtomicBool::new(false); | ||
static INIT: Once = Once::new(); | ||
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.store(true, Ordering::SeqCst); | ||
} | ||
|
||
configure_llvm(sess); | ||
}); | ||
|
||
if POISONED.load(Ordering::SeqCst) { | ||
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); } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// 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 rustc::util::common; | ||
use rustc::middle::cstore::MetadataLoader; | ||
use rustc_back::target::Target; | ||
use llvm; | ||
use llvm::{False, ObjectFile, mk_section_iter}; | ||
use llvm::archive_ro::ArchiveRO; | ||
|
||
use owning_ref::{ErasedBoxRef, OwningRef}; | ||
use std::path::Path; | ||
use std::ptr; | ||
use std::slice; | ||
|
||
pub const METADATA_FILENAME: &str = "rust.metadata.bin"; | ||
|
||
pub struct LlvmMetadataLoader; | ||
|
||
impl MetadataLoader for LlvmMetadataLoader { | ||
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> { | ||
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap | ||
// internally to read the file. We also avoid even using a memcpy by | ||
// just keeping the archive along while the metadata is in use. | ||
let archive = ArchiveRO::open(filename) | ||
.map(|ar| OwningRef::new(box ar)) | ||
.ok_or_else(|| { | ||
debug!("llvm didn't like `{}`", filename.display()); | ||
format!("failed to read rlib metadata: '{}'", filename.display()) | ||
})?; | ||
let buf: OwningRef<_, [u8]> = archive | ||
.try_map(|ar| { | ||
ar.iter() | ||
.filter_map(|s| s.ok()) | ||
.find(|sect| sect.name() == Some(METADATA_FILENAME)) | ||
.map(|s| s.data()) | ||
.ok_or_else(|| { | ||
debug!("didn't find '{}' in the archive", METADATA_FILENAME); | ||
format!("failed to read rlib metadata: '{}'", | ||
filename.display()) | ||
}) | ||
})?; | ||
Ok(buf.erase_owner()) | ||
} | ||
|
||
fn get_dylib_metadata(&self, | ||
target: &Target, | ||
filename: &Path) | ||
-> Result<ErasedBoxRef<[u8]>, String> { | ||
unsafe { | ||
let buf = common::path2cstr(filename); | ||
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); | ||
if mb as isize == 0 { | ||
return Err(format!("error reading library: '{}'", filename.display())); | ||
} | ||
let of = ObjectFile::new(mb) | ||
.map(|of| OwningRef::new(box of)) | ||
.ok_or_else(|| format!("provided path not an object file: '{}'", | ||
filename.display()))?; | ||
let buf = of.try_map(|of| search_meta_section(of, target, filename))?; | ||
Ok(buf.erase_owner()) | ||
} | ||
} | ||
} | ||
|
||
fn search_meta_section<'a>(of: &'a ObjectFile, | ||
target: &Target, | ||
filename: &Path) | ||
-> Result<&'a [u8], String> { | ||
unsafe { | ||
let si = mk_section_iter(of.llof); | ||
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { | ||
let mut name_buf = ptr::null(); | ||
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); | ||
let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); | ||
let name = String::from_utf8(name).unwrap(); | ||
debug!("get_metadata_section: name {}", name); | ||
if read_metadata_section_name(target) == name { | ||
let cbuf = llvm::LLVMGetSectionContents(si.llsi); | ||
let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; | ||
// The buffer is valid while the object file is around | ||
let buf: &'a [u8] = slice::from_raw_parts(cbuf as *const u8, csz); | ||
return Ok(buf); | ||
} | ||
llvm::LLVMMoveToNextSection(si.llsi); | ||
} | ||
} | ||
Err(format!("metadata not found: '{}'", filename.display())) | ||
} | ||
|
||
pub fn metadata_section_name(target: &Target) -> &'static str { | ||
// Historical note: | ||
// | ||
// When using link.exe it was seen that the section name `.note.rustc` | ||
// was getting shortened to `.note.ru`, and according to the PE and COFF | ||
// specification: | ||
// | ||
// > Executable images do not use a string table and do not support | ||
// > section names longer than 8 characters | ||
// | ||
// https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx | ||
// | ||
// As a result, we choose a slightly shorter name! As to why | ||
// `.note.rustc` works on MinGW, that's another good question... | ||
|
||
if target.options.is_like_osx { | ||
"__DATA,.rustc" | ||
} else { | ||
".rustc" | ||
} | ||
} | ||
|
||
fn read_metadata_section_name(_target: &Target) -> &'static str { | ||
".rustc" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters