Rollup merge of #132342 - Zalathar:operand-bundle, r=workingjubilee
cg_llvm: Clean up FFI calls for operand bundles All of these FFI functions have equivalents in the stable LLVM-C API, though `LLVMBuildCallBr` requires a temporary polyfill on LLVM 18. This PR also creates a clear split between `OperandBundleOwned` and `OperandBundle`, and updates the internals of the owner to be a little less terrifying.
This commit is contained in:
commit
879c4d5ccc
6 changed files with 104 additions and 139 deletions
|
@ -3,6 +3,7 @@
|
|||
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
|
||||
use rustc_macros::TryFromU32;
|
||||
|
@ -708,8 +709,9 @@ unsafe extern "C" {
|
|||
}
|
||||
#[repr(C)]
|
||||
pub struct RustArchiveMember<'a>(InvariantOpaque<'a>);
|
||||
/// Opaque pointee of `LLVMOperandBundleRef`.
|
||||
#[repr(C)]
|
||||
pub struct OperandBundleDef<'a>(InvariantOpaque<'a>);
|
||||
pub(crate) struct OperandBundle<'a>(InvariantOpaque<'a>);
|
||||
#[repr(C)]
|
||||
pub struct Linker<'a>(InvariantOpaque<'a>);
|
||||
|
||||
|
@ -1538,6 +1540,50 @@ unsafe extern "C" {
|
|||
|
||||
pub fn LLVMGetOrInsertComdat(M: &Module, Name: *const c_char) -> &Comdat;
|
||||
pub fn LLVMSetComdat(V: &Value, C: &Comdat);
|
||||
|
||||
pub(crate) fn LLVMCreateOperandBundle(
|
||||
Tag: *const c_char,
|
||||
TagLen: size_t,
|
||||
Args: *const &'_ Value,
|
||||
NumArgs: c_uint,
|
||||
) -> *mut OperandBundle<'_>;
|
||||
pub(crate) fn LLVMDisposeOperandBundle(Bundle: ptr::NonNull<OperandBundle<'_>>);
|
||||
|
||||
pub(crate) fn LLVMBuildCallWithOperandBundles<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
Bundles: *const &OperandBundle<'a>,
|
||||
NumBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
pub(crate) fn LLVMBuildInvokeWithOperandBundles<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
Then: &'a BasicBlock,
|
||||
Catch: &'a BasicBlock,
|
||||
Bundles: *const &OperandBundle<'a>,
|
||||
NumBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
pub(crate) fn LLVMBuildCallBr<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
DefaultDest: &'a BasicBlock,
|
||||
IndirectDests: *const &'a BasicBlock,
|
||||
NumIndirectDests: c_uint,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
Bundles: *const &OperandBundle<'a>,
|
||||
NumBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
}
|
||||
|
||||
#[link(name = "llvm-wrapper", kind = "static")]
|
||||
|
@ -1623,47 +1669,11 @@ unsafe extern "C" {
|
|||
AttrsLen: size_t,
|
||||
);
|
||||
|
||||
pub fn LLVMRustBuildInvoke<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
Then: &'a BasicBlock,
|
||||
Catch: &'a BasicBlock,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMRustBuildCallBr<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
DefaultDest: &'a BasicBlock,
|
||||
IndirectDests: *const &'a BasicBlock,
|
||||
NumIndirectDests: c_uint,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
Name: *const c_char,
|
||||
) -> &'a Value;
|
||||
|
||||
pub fn LLVMRustSetFastMath(Instr: &Value);
|
||||
pub fn LLVMRustSetAlgebraicMath(Instr: &Value);
|
||||
pub fn LLVMRustSetAllowReassoc(Instr: &Value);
|
||||
|
||||
// Miscellaneous instructions
|
||||
pub fn LLVMRustBuildCall<'a>(
|
||||
B: &Builder<'a>,
|
||||
Ty: &'a Type,
|
||||
Fn: &'a Value,
|
||||
Args: *const &'a Value,
|
||||
NumArgs: c_uint,
|
||||
OpBundles: *const &OperandBundleDef<'a>,
|
||||
NumOpBundles: c_uint,
|
||||
) -> &'a Value;
|
||||
pub fn LLVMRustBuildMemCpy<'a>(
|
||||
B: &Builder<'a>,
|
||||
Dst: &'a Value,
|
||||
|
@ -2357,13 +2367,6 @@ unsafe extern "C" {
|
|||
|
||||
pub fn LLVMRustSetDataLayoutFromTargetMachine<'a>(M: &'a Module, TM: &'a TargetMachine);
|
||||
|
||||
pub fn LLVMRustBuildOperandBundleDef(
|
||||
Name: *const c_char,
|
||||
Inputs: *const &'_ Value,
|
||||
NumInputs: c_uint,
|
||||
) -> &mut OperandBundleDef<'_>;
|
||||
pub fn LLVMRustFreeOperandBundleDef<'a>(Bundle: &'a mut OperandBundleDef<'a>);
|
||||
|
||||
pub fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock);
|
||||
|
||||
pub fn LLVMRustSetModulePICLevel(M: &Module);
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use std::str::FromStr;
|
||||
use std::string::FromUtf8Error;
|
||||
|
||||
use libc::c_uint;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_llvm::RustString;
|
||||
use rustc_target::abi::{Align, Size, WrappingRange};
|
||||
|
||||
|
@ -331,28 +332,43 @@ pub fn last_error() -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct OperandBundleDef<'a> {
|
||||
pub raw: &'a mut ffi::OperandBundleDef<'a>,
|
||||
/// Owns an [`OperandBundle`], and will dispose of it when dropped.
|
||||
pub(crate) struct OperandBundleOwned<'a> {
|
||||
raw: ptr::NonNull<OperandBundle<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> OperandBundleDef<'a> {
|
||||
pub fn new(name: &str, vals: &[&'a Value]) -> Self {
|
||||
let name = SmallCStr::new(name);
|
||||
let def = unsafe {
|
||||
LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
|
||||
impl<'a> OperandBundleOwned<'a> {
|
||||
pub(crate) fn new(name: &str, vals: &[&'a Value]) -> Self {
|
||||
let raw = unsafe {
|
||||
LLVMCreateOperandBundle(
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
vals.as_ptr(),
|
||||
vals.len() as c_uint,
|
||||
)
|
||||
};
|
||||
OperandBundleDef { raw: def }
|
||||
OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OperandBundleDef<'_> {
|
||||
impl Drop for OperandBundleOwned<'_> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
LLVMRustFreeOperandBundleDef(&mut *(self.raw as *mut _));
|
||||
LLVMDisposeOperandBundle(self.raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
module: &Module,
|
||||
merge_behavior: ModuleFlagMergeBehavior,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue