Auto merge of #54864 - ljedrz:cleanup_codegen_llvm_back, r=Mark-Simulacrum
Cleanup codegen_llvm/back - improve allocations - use `Cow<'static, str>` where applicable - use `to_owned` instead of `to_string` with string literals - remove a redundant `continue` - possible minor speedup in logic - use `mem::replace` instead of `swap` where more concise - remove `'static` from consts - improve common patterns - remove explicit `return`s - whitespace & formatting fixes
This commit is contained in:
commit
6408162ea1
9 changed files with 133 additions and 175 deletions
|
@ -83,15 +83,16 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
if self.src_archive().is_none() {
|
||||
return Vec::new()
|
||||
}
|
||||
|
||||
let archive = self.src_archive.as_ref().unwrap().as_ref().unwrap();
|
||||
let ret = archive.iter()
|
||||
.filter_map(|child| child.ok())
|
||||
.filter(is_relevant_child)
|
||||
.filter_map(|child| child.name())
|
||||
.filter(|name| !self.removals.iter().any(|x| x == name))
|
||||
.map(|name| name.to_string())
|
||||
.collect();
|
||||
return ret;
|
||||
|
||||
archive.iter()
|
||||
.filter_map(|child| child.ok())
|
||||
.filter(is_relevant_child)
|
||||
.filter_map(|child| child.name())
|
||||
.filter(|name| !self.removals.iter().any(|x| x == name))
|
||||
.map(|name| name.to_owned())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn src_archive(&mut self) -> Option<&ArchiveRO> {
|
||||
|
@ -171,7 +172,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
let name = file.file_name().unwrap().to_str().unwrap();
|
||||
self.additions.push(Addition::File {
|
||||
path: file.to_path_buf(),
|
||||
name_in_archive: name.to_string(),
|
||||
name_in_archive: name.to_owned(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -184,13 +185,8 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
/// Combine the provided files, rlibs, and native libraries into a single
|
||||
/// `Archive`.
|
||||
pub fn build(&mut self) {
|
||||
let kind = match self.llvm_archive_kind() {
|
||||
Ok(kind) => kind,
|
||||
Err(kind) => {
|
||||
self.config.sess.fatal(&format!("Don't know how to build archive of type: {}",
|
||||
kind));
|
||||
}
|
||||
};
|
||||
let kind = self.llvm_archive_kind().unwrap_or_else(|kind|
|
||||
self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)));
|
||||
|
||||
if let Err(e) = self.build_with_llvm(kind) {
|
||||
self.config.sess.fatal(&format!("failed to build archive: {}", e));
|
||||
|
@ -281,10 +277,9 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
let ret = if r.into_result().is_err() {
|
||||
let err = llvm::LLVMRustGetLastError();
|
||||
let msg = if err.is_null() {
|
||||
"failed to write archive".to_string()
|
||||
"failed to write archive".into()
|
||||
} else {
|
||||
String::from_utf8_lossy(CStr::from_ptr(err).to_bytes())
|
||||
.into_owned()
|
||||
};
|
||||
Err(io::Error::new(io::ErrorKind::Other, msg))
|
||||
} else {
|
||||
|
@ -293,7 +288,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
for member in members {
|
||||
llvm::LLVMRustArchiveMemberFree(member);
|
||||
}
|
||||
return ret
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ use flate2::write::DeflateEncoder;
|
|||
|
||||
// This is the "magic number" expected at the beginning of a LLVM bytecode
|
||||
// object in an rlib.
|
||||
pub const RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
|
||||
pub const RLIB_BYTECODE_OBJECT_MAGIC: &[u8] = b"RUST_OBJECT";
|
||||
|
||||
// The version number this compiler will write to bytecode objects in rlibs
|
||||
pub const RLIB_BYTECODE_OBJECT_VERSION: u8 = 2;
|
||||
|
@ -106,39 +106,39 @@ pub struct DecodedBytecode<'a> {
|
|||
}
|
||||
|
||||
impl<'a> DecodedBytecode<'a> {
|
||||
pub fn new(data: &'a [u8]) -> Result<DecodedBytecode<'a>, String> {
|
||||
pub fn new(data: &'a [u8]) -> Result<DecodedBytecode<'a>, &'static str> {
|
||||
if !data.starts_with(RLIB_BYTECODE_OBJECT_MAGIC) {
|
||||
return Err("magic bytecode prefix not found".to_string())
|
||||
return Err("magic bytecode prefix not found")
|
||||
}
|
||||
let data = &data[RLIB_BYTECODE_OBJECT_MAGIC.len()..];
|
||||
if !data.starts_with(&[RLIB_BYTECODE_OBJECT_VERSION, 0, 0, 0]) {
|
||||
return Err("wrong version prefix found in bytecode".to_string())
|
||||
return Err("wrong version prefix found in bytecode")
|
||||
}
|
||||
let data = &data[4..];
|
||||
if data.len() < 4 {
|
||||
return Err("bytecode corrupted".to_string())
|
||||
return Err("bytecode corrupted")
|
||||
}
|
||||
let identifier_len = unsafe {
|
||||
u32::from_le(ptr::read_unaligned(data.as_ptr() as *const u32)) as usize
|
||||
};
|
||||
let data = &data[4..];
|
||||
if data.len() < identifier_len {
|
||||
return Err("bytecode corrupted".to_string())
|
||||
return Err("bytecode corrupted")
|
||||
}
|
||||
let identifier = match str::from_utf8(&data[..identifier_len]) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Err("bytecode corrupted".to_string())
|
||||
Err(_) => return Err("bytecode corrupted")
|
||||
};
|
||||
let data = &data[identifier_len..];
|
||||
if data.len() < 8 {
|
||||
return Err("bytecode corrupted".to_string())
|
||||
return Err("bytecode corrupted")
|
||||
}
|
||||
let bytecode_len = unsafe {
|
||||
u64::from_le(ptr::read_unaligned(data.as_ptr() as *const u64)) as usize
|
||||
};
|
||||
let data = &data[8..];
|
||||
if data.len() < bytecode_len {
|
||||
return Err("bytecode corrupted".to_string())
|
||||
return Err("bytecode corrupted")
|
||||
}
|
||||
let encoded_bytecode = &data[..bytecode_len];
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ use std::str;
|
|||
use syntax::attr;
|
||||
|
||||
pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default_output_for_target,
|
||||
invalid_output_for_target, out_filename, check_file_is_writeable,
|
||||
filename_for_metadata};
|
||||
invalid_output_for_target, filename_for_metadata,
|
||||
out_filename, check_file_is_writeable};
|
||||
|
||||
// The third parameter is for env vars, used on windows to set up the
|
||||
// path for MSVC to find its DLLs, and gcc to find its bundled
|
||||
|
@ -107,13 +107,10 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
|
|||
}
|
||||
|
||||
pub fn remove(sess: &Session, path: &Path) {
|
||||
match fs::remove_file(path) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(&format!("failed to remove {}: {}",
|
||||
path.display(),
|
||||
e));
|
||||
}
|
||||
if let Err(e) = fs::remove_file(path) {
|
||||
sess.err(&format!("failed to remove {}: {}",
|
||||
path.display(),
|
||||
e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,9 +144,7 @@ pub(crate) fn link_binary(sess: &Session,
|
|||
|
||||
// Remove the temporary object file and metadata if we aren't saving temps
|
||||
if !sess.opts.cg.save_temps {
|
||||
if sess.opts.output_types.should_codegen() &&
|
||||
!preserve_objects_for_their_debuginfo(sess)
|
||||
{
|
||||
if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) {
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
|
||||
remove(sess, obj);
|
||||
}
|
||||
|
@ -186,7 +181,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
|
|||
// the objects as they're losslessly contained inside the archives.
|
||||
let output_linked = sess.crate_types.borrow()
|
||||
.iter()
|
||||
.any(|x| *x != config::CrateType::Rlib && *x != config::CrateType::Staticlib);
|
||||
.any(|&x| x != config::CrateType::Rlib && x != config::CrateType::Staticlib);
|
||||
if !output_linked {
|
||||
return false
|
||||
}
|
||||
|
@ -270,7 +265,7 @@ pub(crate) fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum)
|
|||
// crates providing these functions don't participate in LTO (e.g.
|
||||
// no_builtins or compiler builtins crates).
|
||||
!sess.target.target.options.no_builtins &&
|
||||
(info.is_no_builtins.contains(&cnum) || info.compiler_builtins == Some(cnum))
|
||||
(info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
|
||||
}
|
||||
|
||||
fn link_binary_output(sess: &Session,
|
||||
|
@ -291,13 +286,10 @@ fn link_binary_output(sess: &Session,
|
|||
// final destination, with a `fs::rename` call. In order for the rename to
|
||||
// always succeed, the temporary file needs to be on the same filesystem,
|
||||
// which is why we create it inside the output directory specifically.
|
||||
let metadata_tmpdir = match TempFileBuilder::new()
|
||||
let metadata_tmpdir = TempFileBuilder::new()
|
||||
.prefix("rmeta")
|
||||
.tempdir_in(out_filename.parent().unwrap())
|
||||
{
|
||||
Ok(tmpdir) => tmpdir,
|
||||
Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
|
||||
};
|
||||
.unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err)));
|
||||
let metadata = emit_metadata(sess, codegen_results, &metadata_tmpdir);
|
||||
if let Err(e) = fs::rename(metadata, &out_filename) {
|
||||
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
|
||||
|
@ -305,10 +297,8 @@ fn link_binary_output(sess: &Session,
|
|||
out_filenames.push(out_filename);
|
||||
}
|
||||
|
||||
let tmpdir = match TempFileBuilder::new().prefix("rustc").tempdir() {
|
||||
Ok(tmpdir) => tmpdir,
|
||||
Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
|
||||
};
|
||||
let tmpdir = TempFileBuilder::new().prefix("rustc").tempdir().unwrap_or_else(|err|
|
||||
sess.fatal(&format!("couldn't create a temp dir: {}", err)));
|
||||
|
||||
if outputs.outputs.should_codegen() {
|
||||
let out_filename = out_filename(sess, crate_type, outputs, crate_name);
|
||||
|
@ -342,7 +332,8 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
|
|||
sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
|
||||
search.push(path.to_path_buf());
|
||||
});
|
||||
return search;
|
||||
|
||||
search
|
||||
}
|
||||
|
||||
fn archive_config<'a>(sess: &'a Session,
|
||||
|
@ -814,8 +805,8 @@ fn link_natively(sess: &Session,
|
|||
.unwrap_or_else(|_| {
|
||||
let mut x = "Non-UTF-8 output: ".to_string();
|
||||
x.extend(s.iter()
|
||||
.flat_map(|&b| ascii::escape_default(b))
|
||||
.map(|b| char::from_u32(b as u32).unwrap()));
|
||||
.flat_map(|&b| ascii::escape_default(b))
|
||||
.map(char::from));
|
||||
x
|
||||
})
|
||||
}
|
||||
|
@ -870,9 +861,8 @@ fn link_natively(sess: &Session,
|
|||
sess.opts.debuginfo != DebugInfo::None &&
|
||||
!preserve_objects_for_their_debuginfo(sess)
|
||||
{
|
||||
match Command::new("dsymutil").arg(out_filename).output() {
|
||||
Ok(..) => {}
|
||||
Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
|
||||
if let Err(e) = Command::new("dsymutil").arg(out_filename).output() {
|
||||
sess.fatal(&format!("failed to run dsymutil: {}", e))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,8 +1002,7 @@ fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: &
|
|||
// ensure the line is interpreted as one whole argument.
|
||||
for c in self.arg.chars() {
|
||||
match c {
|
||||
'\\' |
|
||||
' ' => write!(f, "\\{}", c)?,
|
||||
'\\' | ' ' => write!(f, "\\{}", c)?,
|
||||
c => write!(f, "{}", c)?,
|
||||
}
|
||||
}
|
||||
|
@ -1426,7 +1415,6 @@ fn add_upstream_rust_crates(cmd: &mut dyn Linker,
|
|||
for f in archive.src_files() {
|
||||
if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
|
||||
archive.remove_file(&f);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -205,11 +205,11 @@ pub(crate) fn run(cgcx: &CodegenContext,
|
|||
Lto::Fat => {
|
||||
assert!(cached_modules.is_empty());
|
||||
let opt_jobs = fat_lto(cgcx,
|
||||
&diag_handler,
|
||||
modules,
|
||||
upstream_modules,
|
||||
&symbol_white_list,
|
||||
timeline);
|
||||
&diag_handler,
|
||||
modules,
|
||||
upstream_modules,
|
||||
&symbol_white_list,
|
||||
timeline);
|
||||
opt_jobs.map(|opt_jobs| (opt_jobs, vec![]))
|
||||
}
|
||||
Lto::Thin |
|
||||
|
@ -296,7 +296,7 @@ fn fat_lto(cgcx: &CodegenContext,
|
|||
let data = bc_decoded.data();
|
||||
linker.add(&data).map_err(|()| {
|
||||
let msg = format!("failed to load bc of {:?}", name);
|
||||
write::llvm_err(&diag_handler, msg)
|
||||
write::llvm_err(&diag_handler, &msg)
|
||||
})
|
||||
})?;
|
||||
timeline.record(&format!("link {:?}", name));
|
||||
|
@ -310,8 +310,8 @@ fn fat_lto(cgcx: &CodegenContext,
|
|||
unsafe {
|
||||
let ptr = symbol_white_list.as_ptr();
|
||||
llvm::LLVMRustRunRestrictionPass(llmod,
|
||||
ptr as *const *const libc::c_char,
|
||||
symbol_white_list.len() as libc::size_t);
|
||||
ptr as *const *const libc::c_char,
|
||||
symbol_white_list.len() as libc::size_t);
|
||||
cgcx.save_temp_bitcode(&module, "lto.after-restriction");
|
||||
}
|
||||
|
||||
|
@ -490,7 +490,7 @@ fn thin_lto(cgcx: &CodegenContext,
|
|||
symbol_white_list.as_ptr(),
|
||||
symbol_white_list.len() as u32,
|
||||
).ok_or_else(|| {
|
||||
write::llvm_err(&diag_handler, "failed to prepare thin LTO context".to_string())
|
||||
write::llvm_err(&diag_handler, "failed to prepare thin LTO context")
|
||||
})?;
|
||||
|
||||
info!("thin LTO data created");
|
||||
|
@ -617,8 +617,7 @@ fn run_pass_manager(cgcx: &CodegenContext,
|
|||
llvm::LLVMRustAddPass(pm, pass.unwrap());
|
||||
}
|
||||
|
||||
time_ext(cgcx.time_passes, None, "LTO passes", ||
|
||||
llvm::LLVMRunPassManager(pm, llmod));
|
||||
time_ext(cgcx.time_passes, None, "LTO passes", || llvm::LLVMRunPassManager(pm, llmod));
|
||||
|
||||
llvm::LLVMDisposePassManager(pm);
|
||||
}
|
||||
|
@ -747,7 +746,7 @@ impl ThinModule {
|
|||
{
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let tm = (cgcx.tm_factory)().map_err(|e| {
|
||||
write::llvm_err(&diag_handler, e)
|
||||
write::llvm_err(&diag_handler, &e)
|
||||
})?;
|
||||
|
||||
// Right now the implementation we've got only works over serialized
|
||||
|
@ -762,7 +761,7 @@ impl ThinModule {
|
|||
self.data().len(),
|
||||
self.shared.module_names[self.idx].as_ptr(),
|
||||
).ok_or_else(|| {
|
||||
let msg = "failed to parse bitcode for thin LTO module".to_string();
|
||||
let msg = "failed to parse bitcode for thin LTO module";
|
||||
write::llvm_err(&diag_handler, msg)
|
||||
})? as *const _;
|
||||
let module = ModuleCodegen {
|
||||
|
@ -786,7 +785,7 @@ impl ThinModule {
|
|||
let mut cu2 = ptr::null_mut();
|
||||
llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
|
||||
if !cu2.is_null() {
|
||||
let msg = "multiple source DICompileUnits found".to_string();
|
||||
let msg = "multiple source DICompileUnits found";
|
||||
return Err(write::llvm_err(&diag_handler, msg))
|
||||
}
|
||||
|
||||
|
@ -807,25 +806,25 @@ impl ThinModule {
|
|||
// You can find some more comments about these functions in the LLVM
|
||||
// bindings we've got (currently `PassWrapper.cpp`)
|
||||
if !llvm::LLVMRustPrepareThinLTORename(self.shared.data.0, llmod) {
|
||||
let msg = "failed to prepare thin LTO module".to_string();
|
||||
let msg = "failed to prepare thin LTO module";
|
||||
return Err(write::llvm_err(&diag_handler, msg))
|
||||
}
|
||||
cgcx.save_temp_bitcode(&module, "thin-lto-after-rename");
|
||||
timeline.record("rename");
|
||||
if !llvm::LLVMRustPrepareThinLTOResolveWeak(self.shared.data.0, llmod) {
|
||||
let msg = "failed to prepare thin LTO module".to_string();
|
||||
let msg = "failed to prepare thin LTO module";
|
||||
return Err(write::llvm_err(&diag_handler, msg))
|
||||
}
|
||||
cgcx.save_temp_bitcode(&module, "thin-lto-after-resolve");
|
||||
timeline.record("resolve");
|
||||
if !llvm::LLVMRustPrepareThinLTOInternalize(self.shared.data.0, llmod) {
|
||||
let msg = "failed to prepare thin LTO module".to_string();
|
||||
let msg = "failed to prepare thin LTO module";
|
||||
return Err(write::llvm_err(&diag_handler, msg))
|
||||
}
|
||||
cgcx.save_temp_bitcode(&module, "thin-lto-after-internalize");
|
||||
timeline.record("internalize");
|
||||
if !llvm::LLVMRustPrepareThinLTOImport(self.shared.data.0, llmod) {
|
||||
let msg = "failed to prepare thin LTO module".to_string();
|
||||
let msg = "failed to prepare thin LTO module";
|
||||
return Err(write::llvm_err(&diag_handler, msg))
|
||||
}
|
||||
cgcx.save_temp_bitcode(&module, "thin-lto-after-import");
|
||||
|
@ -920,12 +919,6 @@ impl ThinLTOImports {
|
|||
}
|
||||
|
||||
fn module_name_to_str(c_str: &CStr) -> &str {
|
||||
match c_str.to_str() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
bug!("Encountered non-utf8 LLVM module name `{}`: {}",
|
||||
c_str.to_string_lossy(),
|
||||
e)
|
||||
}
|
||||
}
|
||||
c_str.to_str().unwrap_or_else(|e|
|
||||
bug!("Encountered non-utf8 LLVM module name `{}`: {}", c_str.to_string_lossy(), e))
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
|
|||
|
||||
// Use DT_RUNPATH instead of DT_RPATH if available
|
||||
if config.linker_is_gnu {
|
||||
flags.push("-Wl,--enable-new-dtags".to_string());
|
||||
flags.push("-Wl,--enable-new-dtags".to_owned());
|
||||
}
|
||||
|
||||
flags
|
||||
|
@ -59,7 +59,8 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
|
|||
ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
|
||||
|
@ -92,7 +93,8 @@ fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
|
|||
|
||||
// Remove duplicates
|
||||
let rpaths = minimize_rpaths(&rpaths);
|
||||
return rpaths;
|
||||
|
||||
rpaths
|
||||
}
|
||||
|
||||
fn get_rpaths_relative_to_output(config: &mut RPathConfig,
|
||||
|
@ -117,8 +119,7 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
|
|||
let relative = path_relative_from(&lib, &output).unwrap_or_else(||
|
||||
panic!("couldn't create relative path from {:?} to {:?}", output, lib));
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
format!("{}/{}", prefix,
|
||||
relative.to_str().expect("non-utf8 component in path"))
|
||||
format!("{}/{}", prefix, relative.to_str().expect("non-utf8 component in path"))
|
||||
}
|
||||
|
||||
// This routine is adapted from the *old* Path's `path_relative_from`
|
||||
|
@ -168,7 +169,7 @@ fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
|
|||
let path = (config.get_install_prefix_lib_path)();
|
||||
let path = env::current_dir().unwrap().join(&path);
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
path.to_str().expect("non-utf8 component in rpath").to_string()
|
||||
path.to_str().expect("non-utf8 component in rpath").to_owned()
|
||||
}
|
||||
|
||||
fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
|
||||
|
|
|
@ -42,7 +42,7 @@ const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3;
|
|||
/// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still
|
||||
/// needs to be added, tracked at https://bugs.llvm.org/show_bug.cgi?id=37168
|
||||
pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
|
||||
if import_map.len() == 0 {
|
||||
if import_map.is_empty() {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ impl<'a> Iterator for WasmSections<'a> {
|
|||
type Item = (u8, &'a [u8]);
|
||||
|
||||
fn next(&mut self) -> Option<(u8, &'a [u8])> {
|
||||
if self.0.data.len() == 0 {
|
||||
if self.0.data.is_empty() {
|
||||
return None
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ use std::time::Instant;
|
|||
use std::thread;
|
||||
use libc::{c_uint, c_void, c_char, size_t};
|
||||
|
||||
pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [
|
||||
pub const RELOC_MODEL_ARGS : [(&str, llvm::RelocMode); 7] = [
|
||||
("pic", llvm::RelocMode::PIC),
|
||||
("static", llvm::RelocMode::Static),
|
||||
("default", llvm::RelocMode::Default),
|
||||
|
@ -81,7 +81,7 @@ pub const CODE_GEN_MODEL_ARGS: &[(&str, llvm::CodeModel)] = &[
|
|||
("large", llvm::CodeModel::Large),
|
||||
];
|
||||
|
||||
pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
|
||||
pub const TLS_MODEL_ARGS : [(&str, llvm::ThreadLocalMode); 4] = [
|
||||
("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
|
||||
("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
|
||||
("initial-exec", llvm::ThreadLocalMode::InitialExec),
|
||||
|
@ -90,7 +90,7 @@ pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
|
|||
|
||||
const PRE_THIN_LTO_BC_EXT: &str = "pre-thin-lto.bc";
|
||||
|
||||
pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
|
||||
pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
|
||||
match llvm::last_error() {
|
||||
Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
|
||||
None => handler.fatal(&msg),
|
||||
|
@ -106,11 +106,10 @@ pub fn write_output_file(
|
|||
file_type: llvm::FileType) -> Result<(), FatalError> {
|
||||
unsafe {
|
||||
let output_c = path2cstr(output);
|
||||
let result = llvm::LLVMRustWriteOutputFile(
|
||||
target, pm, m, output_c.as_ptr(), file_type);
|
||||
let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
|
||||
if result.into_result().is_err() {
|
||||
let msg = format!("could not write output to {}", output.display());
|
||||
Err(llvm_err(handler, msg))
|
||||
Err(llvm_err(handler, &msg))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ pub fn create_target_machine(
|
|||
find_features: bool,
|
||||
) -> &'static mut llvm::TargetMachine {
|
||||
target_machine_factory(sess, find_features)().unwrap_or_else(|err| {
|
||||
llvm_err(sess.diagnostic(), err).raise()
|
||||
llvm_err(sess.diagnostic(), &err).raise()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -456,7 +455,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
|
|||
unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext,
|
||||
msg: &'b str,
|
||||
cookie: c_uint) {
|
||||
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string());
|
||||
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
|
||||
}
|
||||
|
||||
unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic,
|
||||
|
@ -590,8 +589,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
|||
|
||||
for pass in &config.passes {
|
||||
if !addpass(pass) {
|
||||
diag_handler.warn(&format!("unknown pass `{}`, ignoring",
|
||||
pass));
|
||||
diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass));
|
||||
}
|
||||
if pass == "name-anon-globals" {
|
||||
have_name_anon_globals_pass = true;
|
||||
|
@ -601,8 +599,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
|||
for pass in &cgcx.plugin_passes {
|
||||
if !addpass(pass) {
|
||||
diag_handler.err(&format!("a plugin asked for LLVM pass \
|
||||
`{}` but LLVM does not \
|
||||
recognize it", pass));
|
||||
`{}` but LLVM does not \
|
||||
recognize it", pass));
|
||||
}
|
||||
if pass == "name-anon-globals" {
|
||||
have_name_anon_globals_pass = true;
|
||||
|
@ -613,12 +611,12 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
|||
// As described above, this will probably cause an error in LLVM
|
||||
if config.no_prepopulate_passes {
|
||||
diag_handler.err("The current compilation is going to use thin LTO buffers \
|
||||
without running LLVM's NameAnonGlobals pass. \
|
||||
This will likely cause errors in LLVM. Consider adding \
|
||||
-C passes=name-anon-globals to the compiler command line.");
|
||||
without running LLVM's NameAnonGlobals pass. \
|
||||
This will likely cause errors in LLVM. Consider adding \
|
||||
-C passes=name-anon-globals to the compiler command line.");
|
||||
} else {
|
||||
bug!("We are using thin LTO buffers without running the NameAnonGlobals pass. \
|
||||
This will likely cause errors in LLVM and should never happen.");
|
||||
This will likely cause errors in LLVM and should never happen.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -704,9 +702,9 @@ unsafe fn codegen(cgcx: &CodegenContext,
|
|||
// escape the closure itself, and the manager should only be
|
||||
// used once.
|
||||
unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
|
||||
llmod: &'ll llvm::Module,
|
||||
no_builtins: bool,
|
||||
f: F) -> R
|
||||
llmod: &'ll llvm::Module,
|
||||
no_builtins: bool,
|
||||
f: F) -> R
|
||||
where F: FnOnce(&'ll mut PassManager<'ll>) -> R,
|
||||
{
|
||||
let cpm = llvm::LLVMCreatePassManager();
|
||||
|
@ -818,7 +816,7 @@ unsafe fn codegen(cgcx: &CodegenContext,
|
|||
};
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(diag_handler, tm, cpm, llmod, &path,
|
||||
llvm::FileType::AssemblyFile)
|
||||
llvm::FileType::AssemblyFile)
|
||||
})?;
|
||||
timeline.record("asm");
|
||||
}
|
||||
|
@ -826,7 +824,7 @@ unsafe fn codegen(cgcx: &CodegenContext,
|
|||
if write_obj {
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
|
||||
llvm::FileType::ObjectFile)
|
||||
llvm::FileType::ObjectFile)
|
||||
})?;
|
||||
timeline.record("obj");
|
||||
} else if asm_to_obj {
|
||||
|
@ -947,11 +945,11 @@ fn need_pre_thin_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
|
|||
}
|
||||
|
||||
pub fn start_async_codegen(tcx: TyCtxt,
|
||||
time_graph: Option<TimeGraph>,
|
||||
metadata: EncodedMetadata,
|
||||
coordinator_receive: Receiver<Box<dyn Any + Send>>,
|
||||
total_cgus: usize)
|
||||
-> OngoingCodegen {
|
||||
time_graph: Option<TimeGraph>,
|
||||
metadata: EncodedMetadata,
|
||||
coordinator_receive: Receiver<Box<dyn Any + Send>>,
|
||||
total_cgus: usize)
|
||||
-> OngoingCodegen {
|
||||
let sess = tcx.sess;
|
||||
let crate_name = tcx.crate_name(LOCAL_CRATE);
|
||||
let crate_hash = tcx.crate_hash(LOCAL_CRATE);
|
||||
|
@ -1116,7 +1114,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
|
|||
}
|
||||
|
||||
if let Some((id, product)) =
|
||||
copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) {
|
||||
copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files)
|
||||
{
|
||||
work_products.insert(id, product);
|
||||
}
|
||||
}
|
||||
|
@ -1441,15 +1440,12 @@ fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
|
|||
module.name,
|
||||
source_file,
|
||||
obj_out.display());
|
||||
match link_or_copy(&source_file, &obj_out) {
|
||||
Ok(_) => { }
|
||||
Err(err) => {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
diag_handler.err(&format!("unable to copy {} to {}: {}",
|
||||
source_file.display(),
|
||||
obj_out.display(),
|
||||
err));
|
||||
}
|
||||
if let Err(err) = link_or_copy(&source_file, &obj_out) {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
diag_handler.err(&format!("unable to copy {} to {}: {}",
|
||||
source_file.display(),
|
||||
obj_out.display(),
|
||||
err));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1584,10 +1580,8 @@ fn start_executing_work(tcx: TyCtxt,
|
|||
|
||||
let (name, mut cmd) = get_linker(sess, &linker, flavor);
|
||||
cmd.args(&sess.target.target.options.asm_args);
|
||||
Some(Arc::new(AssemblerCommand {
|
||||
name,
|
||||
cmd,
|
||||
}))
|
||||
|
||||
Some(Arc::new(AssemblerCommand { name, cmd }))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -2186,9 +2180,9 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path,
|
|||
handler.struct_err(&format!("linking with `{}` failed: {}",
|
||||
pname.display(),
|
||||
prog.status))
|
||||
.note(&format!("{:?}", &cmd))
|
||||
.note(str::from_utf8(¬e[..]).unwrap())
|
||||
.emit();
|
||||
.note(&format!("{:?}", &cmd))
|
||||
.note(str::from_utf8(¬e[..]).unwrap())
|
||||
.emit();
|
||||
handler.abort_if_errors();
|
||||
}
|
||||
},
|
||||
|
@ -2450,8 +2444,8 @@ impl OngoingCodegen {
|
|||
}
|
||||
|
||||
pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
|
||||
tcx: TyCtxt,
|
||||
module: ModuleCodegen) {
|
||||
tcx: TyCtxt,
|
||||
module: ModuleCodegen) {
|
||||
self.wait_for_signal_to_codegen_item();
|
||||
self.check_for_errors(tcx.sess);
|
||||
|
||||
|
|
|
@ -224,9 +224,9 @@ impl<'a> GccLinker<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Linker for GccLinker<'a> {
|
||||
fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}",lib)); }
|
||||
fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}", lib)); }
|
||||
fn link_staticlib(&mut self, lib: &str) {
|
||||
self.hint_static(); self.cmd.arg(format!("-l{}",lib));
|
||||
self.hint_static(); self.cmd.arg(format!("-l{}", lib));
|
||||
}
|
||||
fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
|
||||
fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
|
||||
|
@ -243,7 +243,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
|
||||
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
|
||||
self.hint_dynamic();
|
||||
self.cmd.arg(format!("-l{}",lib));
|
||||
self.cmd.arg(format!("-l{}", lib));
|
||||
}
|
||||
|
||||
fn link_framework(&mut self, framework: &str) {
|
||||
|
@ -261,7 +261,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
self.hint_static();
|
||||
let target = &self.sess.target.target;
|
||||
if !target.options.is_like_osx {
|
||||
self.linker_arg("--whole-archive").cmd.arg(format!("-l{}",lib));
|
||||
self.linker_arg("--whole-archive").cmd.arg(format!("-l{}", lib));
|
||||
self.linker_arg("--no-whole-archive");
|
||||
} else {
|
||||
// -force_load is the macOS equivalent of --whole-archive, but it
|
||||
|
@ -343,17 +343,13 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
}
|
||||
|
||||
fn debuginfo(&mut self) {
|
||||
match self.sess.opts.debuginfo {
|
||||
DebugInfo::None => {
|
||||
// If we are building without debuginfo enabled and we were called with
|
||||
// `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
|
||||
// found when linking to get rid of symbols from libstd.
|
||||
match self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
|
||||
Some(true) => { self.linker_arg("-S"); },
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
if let DebugInfo::None = self.sess.opts.debuginfo {
|
||||
// If we are building without debuginfo enabled and we were called with
|
||||
// `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
|
||||
// found when linking to get rid of symbols from libstd.
|
||||
if let Some(true) = self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
|
||||
self.linker_arg("-S");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -373,8 +369,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
// purely to support rustbuild right now, we should get a more
|
||||
// principled solution at some point to force the compiler to pass
|
||||
// the right `-Wl,-install_name` with an `@rpath` in it.
|
||||
if self.sess.opts.cg.rpath ||
|
||||
self.sess.opts.debugging_opts.osx_rpath_install_name {
|
||||
if self.sess.opts.cg.rpath || self.sess.opts.debugging_opts.osx_rpath_install_name {
|
||||
self.linker_arg("-install_name");
|
||||
let mut v = OsString::from("@rpath/");
|
||||
v.push(out_filename.file_name().unwrap());
|
||||
|
@ -461,9 +456,8 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
|
||||
fn finalize(&mut self) -> Command {
|
||||
self.hint_dynamic(); // Reset to default before returning the composed command line.
|
||||
let mut cmd = Command::new("");
|
||||
::std::mem::swap(&mut cmd, &mut self.cmd);
|
||||
cmd
|
||||
|
||||
::std::mem::replace(&mut self.cmd, Command::new(""))
|
||||
}
|
||||
|
||||
fn group_start(&mut self) {
|
||||
|
@ -715,9 +709,7 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
}
|
||||
|
||||
fn finalize(&mut self) -> Command {
|
||||
let mut cmd = Command::new("");
|
||||
::std::mem::swap(&mut cmd, &mut self.cmd);
|
||||
cmd
|
||||
::std::mem::replace(&mut self.cmd, Command::new(""))
|
||||
}
|
||||
|
||||
// MSVC doesn't need group indicators
|
||||
|
@ -865,7 +857,7 @@ impl<'a> Linker for EmLinker<'a> {
|
|||
let res = encoder.emit_seq(symbols.len(), |encoder| {
|
||||
for (i, sym) in symbols.iter().enumerate() {
|
||||
encoder.emit_seq_elt(i, |encoder| {
|
||||
encoder.emit_str(&("_".to_string() + sym))
|
||||
encoder.emit_str(&("_".to_owned() + sym))
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -885,9 +877,7 @@ impl<'a> Linker for EmLinker<'a> {
|
|||
}
|
||||
|
||||
fn finalize(&mut self) -> Command {
|
||||
let mut cmd = Command::new("");
|
||||
::std::mem::swap(&mut cmd, &mut self.cmd);
|
||||
cmd
|
||||
::std::mem::replace(&mut self.cmd, Command::new(""))
|
||||
}
|
||||
|
||||
// Appears not necessary on Emscripten
|
||||
|
@ -1085,9 +1075,7 @@ impl<'a> Linker for WasmLd<'a> {
|
|||
// indicative of bugs, let's prevent them.
|
||||
self.cmd.arg("--fatal-warnings");
|
||||
|
||||
let mut cmd = Command::new("");
|
||||
::std::mem::swap(&mut cmd, &mut self.cmd);
|
||||
cmd
|
||||
::std::mem::replace(&mut self.cmd, Command::new(""))
|
||||
}
|
||||
|
||||
// Not needed for now with LLD
|
||||
|
|
|
@ -47,11 +47,10 @@ fn crate_export_threshold(crate_type: config::CrateType) -> SymbolExportLevel {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn crates_export_threshold(crate_types: &[config::CrateType])
|
||||
-> SymbolExportLevel {
|
||||
if crate_types.iter().any(|&crate_type| {
|
||||
crate_export_threshold(crate_type) == SymbolExportLevel::Rust
|
||||
}) {
|
||||
pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExportLevel {
|
||||
if crate_types.iter().any(|&crate_type|
|
||||
crate_export_threshold(crate_type) == SymbolExportLevel::Rust)
|
||||
{
|
||||
SymbolExportLevel::Rust
|
||||
} else {
|
||||
SymbolExportLevel::C
|
||||
|
@ -359,7 +358,7 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt, def_id: DefId) -> bool
|
|||
!tcx.reachable_set(LOCAL_CRATE).0.contains(&node_id)
|
||||
} else {
|
||||
bug!("is_unreachable_local_definition called with non-local DefId: {:?}",
|
||||
def_id)
|
||||
def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue