Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #129225

Merged
merged 10 commits into from
Aug 18, 2024
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ dependencies = [

[[package]]
name = "ar_archive_writer"
version = "0.3.3"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2bcb7cf51decfbbfc7ef476e28b0775b13e5eb1190f8b7df145cd53d4f4374"
checksum = "de11a9d32db3327f981143bdf699ade4d637c6887b13b97e6e91a9154666963c"
dependencies = [
"object 0.36.2",
]
Expand Down
83 changes: 1 addition & 82 deletions compiler/rustc_codegen_cranelift/src/archive.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
use std::borrow::Borrow;
use std::fs;
use std::path::Path;

use ar_archive_writer::{COFFShortExport, MachineTypes};
use rustc_codegen_ssa::back::archive::{
create_mingw_dll_import_lib, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
DEFAULT_OBJECT_READER,
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
};
use rustc_codegen_ssa::common::is_mingw_gnu_toolchain;
use rustc_session::Session;

pub(crate) struct ArArchiveBuilderBuilder;
Expand All @@ -16,78 +9,4 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
}

fn create_dll_import_lib(
&self,
sess: &Session,
lib_name: &str,
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
output_path: &Path,
) {
if is_mingw_gnu_toolchain(&sess.target) {
// The binutils linker used on -windows-gnu targets cannot read the import
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
create_mingw_dll_import_lib(
sess,
lib_name,
import_name_and_ordinal_vector,
output_path,
);
} else {
let mut file =
match fs::OpenOptions::new().write(true).create_new(true).open(&output_path) {
Ok(file) => file,
Err(error) => {
sess.dcx().fatal(format!(
"failed to create import library file `{path}`: {error}",
path = output_path.display(),
));
}
};

let machine = match sess.target.arch.borrow() {
"x86" => MachineTypes::I386,
"x86_64" => MachineTypes::AMD64,
"arm" => MachineTypes::ARMNT,
"aarch64" => MachineTypes::ARM64,
_ => {
sess.dcx().fatal(format!(
"unsupported target architecture `{arch}`",
arch = sess.target.arch,
));
}
};

let exports = import_name_and_ordinal_vector
.iter()
.map(|(name, ordinal)| COFFShortExport {
name: name.to_string(),
ext_name: None,
symbol_name: None,
alias_target: None,
ordinal: ordinal.unwrap_or(0),
noname: ordinal.is_some(),
data: false,
private: false,
constant: false,
})
.collect::<Vec<_>>();

if let Err(error) = ar_archive_writer::write_import_library(
&mut file,
lib_name,
&exports,
machine,
!sess.target.is_like_msvc,
) {
sess.dcx().fatal(format!(
"failed to create import library `{path}`: `{error}`",
path = output_path.display(),
));
}
}
}
}
1 change: 0 additions & 1 deletion compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#![warn(unused_lifetimes)]
// tidy-alphabetical-end

extern crate ar_archive_writer;
extern crate jobserver;
#[macro_use]
extern crate rustc_middle;
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_codegen_llvm/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ codegen_llvm_dynamic_linking_with_lto =
.note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO


codegen_llvm_error_creating_import_library =
Error creating import library for {$lib_name}: {$error}

codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture

codegen_llvm_from_llvm_diag = {$message}
Expand Down
94 changes: 3 additions & 91 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@ use std::path::{Path, PathBuf};
use std::{io, mem, ptr, str};

use rustc_codegen_ssa::back::archive::{
create_mingw_dll_import_lib, try_extract_macho_fat_archive, ArArchiveBuilder,
ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind,
DEFAULT_OBJECT_READER,
try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
};
use rustc_codegen_ssa::common;
use rustc_session::Session;
use tracing::trace;

use crate::errors::ErrorCreatingImportLibrary;
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
use crate::llvm::{self, ArchiveKind};

/// Helper for adding many files to an archive.
#[must_use = "must call build() to finish building the archive"]
Expand Down Expand Up @@ -44,18 +40,6 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
}
}

/// Map machine type strings to values of LLVM's MachineTypes enum.
fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
match cpu {
"x86_64" => LLVMMachineType::AMD64,
"x86" => LLVMMachineType::I386,
"aarch64" => LLVMMachineType::ARM64,
"arm64ec" => LLVMMachineType::ARM64EC,
"arm" => LLVMMachineType::ARM,
_ => panic!("unsupported cpu type {cpu}"),
}
}

impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
fn add_archive(
&mut self,
Expand Down Expand Up @@ -116,78 +100,6 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
}
}

fn create_dll_import_lib(
&self,
sess: &Session,
lib_name: &str,
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
output_path: &Path,
) {
if common::is_mingw_gnu_toolchain(&sess.target) {
// The binutils linker used on -windows-gnu targets cannot read the import
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
create_mingw_dll_import_lib(
sess,
lib_name,
import_name_and_ordinal_vector,
output_path,
);
} else {
// we've checked for \0 characters in the library name already
let dll_name_z = CString::new(lib_name).unwrap();

let output_path_z = rustc_fs_util::path_to_c_string(&output_path);

trace!("invoking LLVMRustWriteImportLibrary");
trace!(" dll_name {:#?}", dll_name_z);
trace!(" output_path {}", output_path.display());
trace!(
" import names: {}",
import_name_and_ordinal_vector
.iter()
.map(|(name, _ordinal)| name.clone())
.collect::<Vec<_>>()
.join(", "),
);

// All import names are Rust identifiers and therefore cannot contain \0 characters.
// FIXME: when support for #[link_name] is implemented, ensure that the import names
// still don't contain any \0 characters. Also need to check that the names don't
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
// in definition files.
let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
import_name_and_ordinal_vector
.into_iter()
.map(|(name, ordinal)| (CString::new(name).unwrap(), ordinal))
.collect();

let ffi_exports: Vec<LLVMRustCOFFShortExport> = cstring_import_name_and_ordinal_vector
.iter()
.map(|(name_z, ordinal)| LLVMRustCOFFShortExport::new(name_z.as_ptr(), *ordinal))
.collect();
let result = unsafe {
crate::llvm::LLVMRustWriteImportLibrary(
dll_name_z.as_ptr(),
output_path_z.as_ptr(),
ffi_exports.as_ptr(),
ffi_exports.len(),
llvm_machine_type(&sess.target.arch) as u16,
!sess.target.is_like_msvc,
)
};

if result == crate::llvm::LLVMRustResult::Failure {
sess.dcx().emit_fatal(ErrorCreatingImportLibrary {
lib_name,
error: llvm::last_error().unwrap_or("unknown LLVM error".to_string()),
});
}
}
}
}

// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,8 +1000,10 @@ impl<'ll> CodegenCx<'ll, '_> {
ifn!("llvm.is.constant.i64", fn(t_i64) -> i1);
ifn!("llvm.is.constant.i128", fn(t_i128) -> i1);
ifn!("llvm.is.constant.isize", fn(t_isize) -> i1);
ifn!("llvm.is.constant.f16", fn(t_f16) -> i1);
ifn!("llvm.is.constant.f32", fn(t_f32) -> i1);
ifn!("llvm.is.constant.f64", fn(t_f64) -> i1);
ifn!("llvm.is.constant.f128", fn(t_f128) -> i1);
ifn!("llvm.is.constant.ptr", fn(ptr) -> i1);

ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ pub(crate) enum PossibleFeature<'a> {
None,
}

#[derive(Diagnostic)]
#[diag(codegen_llvm_error_creating_import_library)]
pub(crate) struct ErrorCreatingImportLibrary<'a> {
pub lib_name: &'a str,
pub error: String,
}

#[derive(Diagnostic)]
#[diag(codegen_llvm_symbol_already_defined)]
pub(crate) struct SymbolAlreadyDefined<'a> {
Expand Down
22 changes: 15 additions & 7 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,22 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
sym::is_val_statically_known => {
let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx);
match self.type_kind(intrinsic_type) {
TypeKind::Pointer | TypeKind::Integer | TypeKind::Float | TypeKind::Double => {
self.call_intrinsic(
&format!("llvm.is.constant.{:?}", intrinsic_type),
&[args[0].immediate()],
)
let kind = self.type_kind(intrinsic_type);
let intrinsic_name = match kind {
TypeKind::Pointer | TypeKind::Integer => {
Some(format!("llvm.is.constant.{intrinsic_type:?}"))
}
_ => self.const_bool(false),
// LLVM float types' intrinsic names differ from their type names.
TypeKind::Half => Some(format!("llvm.is.constant.f16")),
TypeKind::Float => Some(format!("llvm.is.constant.f32")),
TypeKind::Double => Some(format!("llvm.is.constant.f64")),
TypeKind::FP128 => Some(format!("llvm.is.constant.f128")),
_ => None,
};
if let Some(intrinsic_name) = intrinsic_name {
self.call_intrinsic(&intrinsic_name, &[args[0].immediate()])
} else {
self.const_bool(false)
}
}
sym::unlikely => self
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
ar_archive_writer = "0.3.3"
ar_archive_writer = "0.4.0"
arrayvec = { version = "0.7", default-features = false }
bitflags = "2.4.1"
cc = "1.0.90"
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ codegen_ssa_dlltool_fail_import_library =
codegen_ssa_error_calling_dlltool =
Error calling dlltool '{$dlltool_path}': {$error}

codegen_ssa_error_creating_import_library =
Error creating import library for {$lib_name}: {$error}

codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}

codegen_ssa_error_writing_def_file =
Expand Down
Loading
Loading