codegen_llvm: avoid Deref
impls w/ extern type
`rustc_codegen_llvm` relied on `Deref` impls where `Deref::Target` was or contained an extern type - in my experimental implementation of rust-lang/rfcs#3729, this isn't possible as the `Target` associated type's `?Sized` bound cannot be relaxed backwards compatibly (unless we come up with some way of doing this). In later pull requests with the rust-lang/rfcs#3729 implementation, breakage like this could only occur for nightly users relying on the `extern_types` feature. Upstreaming this to avoid needing to keep carrying this patch locally, and I think it'll necessarily need to change eventually.
This commit is contained in:
parent
ad27045c31
commit
a5615d3c62
8 changed files with 31 additions and 30 deletions
|
@ -793,7 +793,9 @@ pub(crate) unsafe fn optimize_thin_module(
|
||||||
{
|
{
|
||||||
let _timer =
|
let _timer =
|
||||||
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
|
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
|
||||||
unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) };
|
unsafe {
|
||||||
|
llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target.raw())
|
||||||
|
};
|
||||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
|
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,7 +825,7 @@ pub(crate) unsafe fn optimize_thin_module(
|
||||||
let _timer =
|
let _timer =
|
||||||
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
|
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
|
||||||
if unsafe {
|
if unsafe {
|
||||||
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target)
|
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target.raw())
|
||||||
} {
|
} {
|
||||||
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
|
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::ffi::{CStr, c_char};
|
use std::ffi::{CStr, c_char};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
|
@ -80,12 +79,12 @@ impl OwnedTargetMachine {
|
||||||
.map(|tm_unique| Self { tm_unique, phantom: PhantomData })
|
.map(|tm_unique| Self { tm_unique, phantom: PhantomData })
|
||||||
.ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
|
.ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for OwnedTargetMachine {
|
/// Returns inner `llvm::TargetMachine` type.
|
||||||
type Target = llvm::TargetMachine;
|
///
|
||||||
|
/// This could be a `Deref` implementation, but `llvm::TargetMachine` is an extern type and
|
||||||
fn deref(&self) -> &Self::Target {
|
/// `Deref::Target: ?Sized`.
|
||||||
|
pub fn raw(&self) -> &llvm::TargetMachine {
|
||||||
// SAFETY: constructing ensures we have a valid pointer created by
|
// SAFETY: constructing ensures we have a valid pointer created by
|
||||||
// llvm::LLVMRustCreateTargetMachine.
|
// llvm::LLVMRustCreateTargetMachine.
|
||||||
unsafe { self.tm_unique.as_ref() }
|
unsafe { self.tm_unique.as_ref() }
|
||||||
|
|
|
@ -637,7 +637,7 @@ pub(crate) unsafe fn llvm_optimize(
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
llvm::LLVMRustOptimize(
|
llvm::LLVMRustOptimize(
|
||||||
module.module_llvm.llmod(),
|
module.module_llvm.llmod(),
|
||||||
&*module.module_llvm.tm,
|
&*module.module_llvm.tm.raw(),
|
||||||
to_pass_builder_opt_level(opt_level),
|
to_pass_builder_opt_level(opt_level),
|
||||||
opt_stage,
|
opt_stage,
|
||||||
cgcx.opts.cg.linker_plugin_lto.enabled(),
|
cgcx.opts.cg.linker_plugin_lto.enabled(),
|
||||||
|
@ -875,7 +875,7 @@ pub(crate) unsafe fn codegen(
|
||||||
};
|
};
|
||||||
write_output_file(
|
write_output_file(
|
||||||
dcx,
|
dcx,
|
||||||
tm,
|
tm.raw(),
|
||||||
config.no_builtins,
|
config.no_builtins,
|
||||||
llmod,
|
llmod,
|
||||||
&path,
|
&path,
|
||||||
|
@ -909,7 +909,7 @@ pub(crate) unsafe fn codegen(
|
||||||
|
|
||||||
write_output_file(
|
write_output_file(
|
||||||
dcx,
|
dcx,
|
||||||
tm,
|
tm.raw(),
|
||||||
config.no_builtins,
|
config.no_builtins,
|
||||||
llmod,
|
llmod,
|
||||||
&obj_out,
|
&obj_out,
|
||||||
|
|
|
@ -405,7 +405,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
|
|
||||||
// Emit KCFI operand bundle
|
// Emit KCFI operand bundle
|
||||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||||
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
|
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
|
||||||
bundles.push(kcfi_bundle);
|
bundles.push(kcfi_bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1433,7 +1433,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
|
|
||||||
// Emit KCFI operand bundle
|
// Emit KCFI operand bundle
|
||||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||||
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
|
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
|
||||||
bundles.push(kcfi_bundle);
|
bundles.push(kcfi_bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1782,7 +1782,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
|
|
||||||
// Emit KCFI operand bundle
|
// Emit KCFI operand bundle
|
||||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||||
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
|
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
|
||||||
bundles.push(kcfi_bundle);
|
bundles.push(kcfi_bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl<'ll> Funclet<'ll> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> {
|
pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> {
|
||||||
&self.operand
|
self.operand.raw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ pub(crate) unsafe fn create_module<'ll>(
|
||||||
{
|
{
|
||||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
|
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
|
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
|
let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::ops::Deref;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
@ -355,6 +354,16 @@ impl<'a> OperandBundleOwned<'a> {
|
||||||
};
|
};
|
||||||
OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() }
|
OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns inner `OperandBundle` type.
|
||||||
|
///
|
||||||
|
/// This could be a `Deref` implementation, but `OperandBundle` contains an extern type and
|
||||||
|
/// `Deref::Target: ?Sized`.
|
||||||
|
pub(crate) fn raw(&self) -> &OperandBundle<'a> {
|
||||||
|
// SAFETY: The returned reference is opaque and can only used for FFI.
|
||||||
|
// It is valid for as long as `&self` is.
|
||||||
|
unsafe { self.raw.as_ref() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for OperandBundleOwned<'_> {
|
impl Drop for OperandBundleOwned<'_> {
|
||||||
|
@ -365,16 +374,6 @@ impl Drop for OperandBundleOwned<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Deref for OperandBundleOwned<'a> {
|
|
||||||
type Target = OperandBundle<'a>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
// SAFETY: The returned reference is opaque and can only used for FFI.
|
|
||||||
// It is valid for as long as `&self` is.
|
|
||||||
unsafe { self.raw.as_ref() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn add_module_flag_u32(
|
pub(crate) fn add_module_flag_u32(
|
||||||
module: &Module,
|
module: &Module,
|
||||||
merge_behavior: ModuleFlagMergeBehavior,
|
merge_behavior: ModuleFlagMergeBehavior,
|
||||||
|
|
|
@ -331,7 +331,8 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec<S
|
||||||
if let Some(feat) = to_llvm_features(sess, feature) {
|
if let Some(feat) = to_llvm_features(sess, feature) {
|
||||||
for llvm_feature in feat {
|
for llvm_feature in feat {
|
||||||
let cstr = SmallCStr::new(llvm_feature);
|
let cstr = SmallCStr::new(llvm_feature);
|
||||||
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
|
if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) }
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,8 +454,8 @@ pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
|
||||||
require_inited();
|
require_inited();
|
||||||
let tm = create_informational_target_machine(sess, false);
|
let tm = create_informational_target_machine(sess, false);
|
||||||
match req.kind {
|
match req.kind {
|
||||||
PrintKind::TargetCPUs => print_target_cpus(sess, &tm, out),
|
PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
|
||||||
PrintKind::TargetFeatures => print_target_features(sess, &tm, out),
|
PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
|
||||||
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
|
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue