Add OwnedTargetMachine to manage llvm:TargetMachine. Uses pointers
instead of &'static mut and provides safe interface to create/dispose it.
This commit is contained in:
parent
fc61fabc24
commit
3409ca65d8
7 changed files with 148 additions and 40 deletions
101
compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
Normal file
101
compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
Normal file
|
@ -0,0 +1,101 @@
|
|||
use std::{
|
||||
ffi::{c_char, CStr},
|
||||
marker::PhantomData,
|
||||
ops::Deref,
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
|
||||
use crate::{errors::LlvmError, llvm};
|
||||
|
||||
/// Responsible for safely creating and disposing llvm::TargetMachine via ffi functions.
|
||||
/// Not cloneable as there is no clone function for llvm::TargetMachine.
|
||||
#[repr(transparent)]
|
||||
pub struct OwnedTargetMachine {
|
||||
tm_unique: NonNull<llvm::TargetMachine>,
|
||||
phantom: PhantomData<llvm::TargetMachine>,
|
||||
}
|
||||
|
||||
impl OwnedTargetMachine {
|
||||
pub fn new(
|
||||
triple: &CStr,
|
||||
cpu: &CStr,
|
||||
features: &CStr,
|
||||
abi: &CStr,
|
||||
model: llvm::CodeModel,
|
||||
reloc: llvm::RelocModel,
|
||||
level: llvm::CodeGenOptLevel,
|
||||
use_soft_fp: bool,
|
||||
function_sections: bool,
|
||||
data_sections: bool,
|
||||
unique_section_names: bool,
|
||||
trap_unreachable: bool,
|
||||
singletree: bool,
|
||||
asm_comments: bool,
|
||||
emit_stack_size_section: bool,
|
||||
relax_elf_relocations: bool,
|
||||
use_init_array: bool,
|
||||
split_dwarf_file: &CStr,
|
||||
debug_info_compression: &CStr,
|
||||
force_emulated_tls: bool,
|
||||
args_cstr_buff: &[u8],
|
||||
) -> Result<Self, LlvmError<'static>> {
|
||||
assert!(args_cstr_buff.len() > 0);
|
||||
assert!(
|
||||
*args_cstr_buff.last().unwrap() == 0,
|
||||
"The last character must be a null terminator."
|
||||
);
|
||||
|
||||
// SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data
|
||||
let tm_ptr = unsafe {
|
||||
llvm::LLVMRustCreateTargetMachine(
|
||||
triple.as_ptr(),
|
||||
cpu.as_ptr(),
|
||||
features.as_ptr(),
|
||||
abi.as_ptr(),
|
||||
model,
|
||||
reloc,
|
||||
level,
|
||||
use_soft_fp,
|
||||
function_sections,
|
||||
data_sections,
|
||||
unique_section_names,
|
||||
trap_unreachable,
|
||||
singletree,
|
||||
asm_comments,
|
||||
emit_stack_size_section,
|
||||
relax_elf_relocations,
|
||||
use_init_array,
|
||||
split_dwarf_file.as_ptr(),
|
||||
debug_info_compression.as_ptr(),
|
||||
force_emulated_tls,
|
||||
args_cstr_buff.as_ptr() as *const c_char,
|
||||
args_cstr_buff.len(),
|
||||
)
|
||||
};
|
||||
|
||||
NonNull::new(tm_ptr)
|
||||
.map(|tm_unique| Self { tm_unique, phantom: PhantomData })
|
||||
.ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for OwnedTargetMachine {
|
||||
type Target = llvm::TargetMachine;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
|
||||
unsafe { self.tm_unique.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OwnedTargetMachine {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
|
||||
// OwnedTargetMachine is not copyable so there is no double free or use after free
|
||||
unsafe {
|
||||
llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
use crate::back::lto::ThinBuffer;
|
||||
use crate::back::owned_target_machine::OwnedTargetMachine;
|
||||
use crate::back::profiling::{
|
||||
selfprofile_after_pass_callback, selfprofile_before_pass_callback, LlvmSelfProfiler,
|
||||
};
|
||||
|
@ -98,7 +99,7 @@ pub fn write_output_file<'ll>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine {
|
||||
pub fn create_informational_target_machine(sess: &Session) -> OwnedTargetMachine {
|
||||
let config = TargetMachineFactoryConfig { split_dwarf_file: None };
|
||||
// Can't use query system here quite yet because this function is invoked before the query
|
||||
// system/tcx is set up.
|
||||
|
@ -107,7 +108,7 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm:
|
|||
.unwrap_or_else(|err| llvm_err(sess.diagnostic(), err).raise())
|
||||
}
|
||||
|
||||
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
|
||||
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
|
||||
let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
|
||||
tcx.output_filenames(()).split_dwarf_path(
|
||||
tcx.sess.split_debuginfo(),
|
||||
|
@ -259,34 +260,29 @@ pub fn target_machine_factory(
|
|||
path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0;
|
||||
let split_dwarf_file = CString::new(split_dwarf_file.to_str().unwrap()).unwrap();
|
||||
|
||||
let tm = unsafe {
|
||||
llvm::LLVMRustCreateTargetMachine(
|
||||
triple.as_ptr(),
|
||||
cpu.as_ptr(),
|
||||
features.as_ptr(),
|
||||
abi.as_ptr(),
|
||||
code_model,
|
||||
reloc_model,
|
||||
opt_level,
|
||||
use_softfp,
|
||||
ffunction_sections,
|
||||
fdata_sections,
|
||||
funique_section_names,
|
||||
trap_unreachable,
|
||||
singlethread,
|
||||
asm_comments,
|
||||
emit_stack_size_section,
|
||||
relax_elf_relocations,
|
||||
use_init_array,
|
||||
split_dwarf_file.as_ptr(),
|
||||
debuginfo_compression.as_ptr(),
|
||||
force_emulated_tls,
|
||||
args_cstr_buff.as_ptr() as *const c_char,
|
||||
args_cstr_buff.len(),
|
||||
)
|
||||
};
|
||||
|
||||
tm.ok_or_else(|| LlvmError::CreateTargetMachine { triple: triple.clone() })
|
||||
OwnedTargetMachine::new(
|
||||
&triple,
|
||||
&cpu,
|
||||
&features,
|
||||
&abi,
|
||||
code_model,
|
||||
reloc_model,
|
||||
opt_level,
|
||||
use_softfp,
|
||||
ffunction_sections,
|
||||
fdata_sections,
|
||||
funique_section_names,
|
||||
trap_unreachable,
|
||||
singlethread,
|
||||
asm_comments,
|
||||
emit_stack_size_section,
|
||||
relax_elf_relocations,
|
||||
use_init_array,
|
||||
&split_dwarf_file,
|
||||
&debuginfo_compression,
|
||||
force_emulated_tls,
|
||||
&args_cstr_buff,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue