Simplify implementation of Rust intrinsics by using type parameters in the cache
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use std::num::NonZero;
|
||||
use std::ptr;
|
||||
|
||||
use bitflags::bitflags;
|
||||
@@ -1195,6 +1196,17 @@ unsafe extern "C" {
|
||||
// Operations on functions
|
||||
pub(crate) fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint);
|
||||
|
||||
// Operations about llvm intrinsics
|
||||
pub(crate) fn LLVMLookupIntrinsicID(Name: *const c_char, NameLen: size_t) -> c_uint;
|
||||
pub(crate) fn LLVMIntrinsicIsOverloaded(ID: NonZero<c_uint>) -> Bool;
|
||||
pub(crate) fn LLVMIntrinsicCopyOverloadedName2<'a>(
|
||||
Mod: &'a Module,
|
||||
ID: NonZero<c_uint>,
|
||||
ParamTypes: *const &'a Type,
|
||||
ParamCount: size_t,
|
||||
NameLength: *mut size_t,
|
||||
) -> *mut c_char;
|
||||
|
||||
// Operations on parameters
|
||||
pub(crate) fn LLVMIsAArgument(Val: &Value) -> Option<&Value>;
|
||||
pub(crate) safe fn LLVMCountParams(Fn: &Value) -> c_uint;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ptr;
|
||||
use std::num::NonZero;
|
||||
use std::str::FromStr;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::{ptr, slice};
|
||||
|
||||
use libc::c_uint;
|
||||
use rustc_abi::{Align, Size, WrappingRange};
|
||||
@@ -327,6 +328,48 @@ pub(crate) fn get_value_name(value: &Value) -> &[u8] {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) struct Intrinsic {
|
||||
id: NonZero<c_uint>,
|
||||
}
|
||||
|
||||
impl Intrinsic {
|
||||
pub(crate) fn lookup(name: &[u8]) -> Option<Self> {
|
||||
let id = unsafe { LLVMLookupIntrinsicID(name.as_c_char_ptr(), name.len()) };
|
||||
NonZero::new(id).map(|id| Self { id })
|
||||
}
|
||||
|
||||
pub(crate) fn is_overloaded(self) -> bool {
|
||||
unsafe { LLVMIntrinsicIsOverloaded(self.id) == True }
|
||||
}
|
||||
|
||||
pub(crate) fn overloaded_name<'ll>(
|
||||
self,
|
||||
llmod: &'ll Module,
|
||||
type_params: &[&'ll Type],
|
||||
) -> String {
|
||||
let mut len = 0;
|
||||
let ptr = unsafe {
|
||||
LLVMIntrinsicCopyOverloadedName2(
|
||||
llmod,
|
||||
self.id,
|
||||
type_params.as_ptr(),
|
||||
type_params.len(),
|
||||
&mut len,
|
||||
)
|
||||
};
|
||||
|
||||
let slice = unsafe { slice::from_raw_parts_mut(ptr.cast(), len) };
|
||||
let copied = str::from_utf8(slice).expect("Non-UTF8 intrinsic name").to_string();
|
||||
|
||||
unsafe {
|
||||
libc::free(ptr.cast());
|
||||
}
|
||||
|
||||
copied
|
||||
}
|
||||
}
|
||||
|
||||
/// Safe wrapper for `LLVMSetValueName2` from a byte slice
|
||||
pub(crate) fn set_value_name(value: &Value, name: &[u8]) {
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user