Partially inline get_fn_addr/get_fn in codegen_llvm_intrinsic_call
This moves all LLVM intrinsic handling out of the regular call path for cg_gcc and makes it easier to hook into this code for future cg_llvm changes.
This commit is contained in:
parent
56be08eb45
commit
5bcd472b86
4 changed files with 46 additions and 19 deletions
|
|
@ -314,7 +314,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
self.block.get_function()
|
||||
}
|
||||
|
||||
fn function_call(
|
||||
pub fn function_call(
|
||||
&mut self,
|
||||
func: Function<'gcc>,
|
||||
args: &[RValue<'gcc>],
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
pub instances: RefCell<FxHashMap<Instance<'tcx>, LValue<'gcc>>>,
|
||||
/// Cache function instances of monomorphic and polymorphic items
|
||||
pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
|
||||
/// Cache function instances of intrinsics
|
||||
pub intrinsic_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
|
||||
/// Cache generated vtables
|
||||
pub vtables:
|
||||
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
|
||||
|
|
@ -280,6 +282,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
linkage: Cell::new(FunctionType::Internal),
|
||||
instances: Default::default(),
|
||||
function_instances: Default::default(),
|
||||
intrinsic_instances: Default::default(),
|
||||
on_stack_params: Default::default(),
|
||||
on_stack_function_params: Default::default(),
|
||||
vtables: Default::default(),
|
||||
|
|
@ -397,9 +400,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> {
|
||||
let func_name = self.tcx.symbol_name(instance).name;
|
||||
|
||||
let func = if self.intrinsics.borrow().contains_key(func_name) {
|
||||
self.intrinsics.borrow()[func_name]
|
||||
} else if let Some(variable) = self.get_declared_value(func_name) {
|
||||
let func = if let Some(variable) = self.get_declared_value(func_name) {
|
||||
return variable;
|
||||
} else {
|
||||
get_fn(self, instance)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use rustc_target::callconv::FnAbi;
|
|||
|
||||
use crate::abi::{FnAbiGcc, FnAbiGccExt};
|
||||
use crate::context::CodegenCx;
|
||||
use crate::intrinsic::llvm;
|
||||
|
||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
pub fn get_or_insert_global(
|
||||
|
|
@ -162,19 +161,6 @@ fn declare_raw_fn<'gcc>(
|
|||
param_types: &[Type<'gcc>],
|
||||
variadic: bool,
|
||||
) -> Function<'gcc> {
|
||||
if name.starts_with("llvm.") {
|
||||
let intrinsic = match name {
|
||||
"llvm.fma.f16" => {
|
||||
// fma is not a target builtin, but a normal builtin, so we handle it differently
|
||||
// here.
|
||||
cx.context.get_builtin_function("fma")
|
||||
}
|
||||
_ => llvm::intrinsic(name, cx),
|
||||
};
|
||||
|
||||
cx.intrinsics.borrow_mut().insert(name.to_string(), intrinsic);
|
||||
return intrinsic;
|
||||
}
|
||||
let func = if cx.functions.borrow().contains_key(name) {
|
||||
cx.functions.borrow()[name]
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -615,7 +615,47 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
|||
args: &[OperandRef<'tcx, Self::Value>],
|
||||
is_cleanup: bool,
|
||||
) -> Self::Value {
|
||||
let fn_ptr = self.get_fn_addr(instance);
|
||||
let func = if let Some(&func) = self.intrinsic_instances.borrow().get(&instance) {
|
||||
func
|
||||
} else {
|
||||
let sym = self.tcx.symbol_name(instance).name;
|
||||
|
||||
let func = if let Some(func) = self.intrinsics.borrow().get(sym) {
|
||||
*func
|
||||
} else {
|
||||
self.linkage.set(FunctionType::Extern);
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
let fn_ty = fn_abi.gcc_type(self);
|
||||
|
||||
let func = match sym {
|
||||
"llvm.fma.f16" => {
|
||||
// fma is not a target builtin, but a normal builtin, so we handle it differently
|
||||
// here.
|
||||
self.context.get_builtin_function("fma")
|
||||
}
|
||||
_ => llvm::intrinsic(sym, self),
|
||||
};
|
||||
|
||||
self.intrinsics.borrow_mut().insert(sym.to_string(), func);
|
||||
|
||||
self.on_stack_function_params
|
||||
.borrow_mut()
|
||||
.insert(func, fn_ty.on_stack_param_indices);
|
||||
#[cfg(feature = "master")]
|
||||
for fn_attr in fn_ty.fn_attributes {
|
||||
func.add_attribute(fn_attr);
|
||||
}
|
||||
|
||||
crate::attributes::from_fn_attrs(self, func, instance);
|
||||
|
||||
func
|
||||
};
|
||||
|
||||
self.intrinsic_instances.borrow_mut().insert(instance, func);
|
||||
|
||||
func
|
||||
};
|
||||
let fn_ptr = func.get_address(None);
|
||||
let fn_ty = fn_ptr.get_type();
|
||||
|
||||
let mut llargs = vec![];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue