Skip to content

Commit 5bcd472

Browse files
committed
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.
1 parent 56be08e commit 5bcd472

4 files changed

Lines changed: 46 additions & 19 deletions

File tree

src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
314314
self.block.get_function()
315315
}
316316

317-
fn function_call(
317+
pub fn function_call(
318318
&mut self,
319319
func: Function<'gcc>,
320320
args: &[RValue<'gcc>],

src/context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ pub struct CodegenCx<'gcc, 'tcx> {
9292
pub instances: RefCell<FxHashMap<Instance<'tcx>, LValue<'gcc>>>,
9393
/// Cache function instances of monomorphic and polymorphic items
9494
pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
95+
/// Cache function instances of intrinsics
96+
pub intrinsic_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
9597
/// Cache generated vtables
9698
pub vtables:
9799
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
@@ -280,6 +282,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
280282
linkage: Cell::new(FunctionType::Internal),
281283
instances: Default::default(),
282284
function_instances: Default::default(),
285+
intrinsic_instances: Default::default(),
283286
on_stack_params: Default::default(),
284287
on_stack_function_params: Default::default(),
285288
vtables: Default::default(),
@@ -397,9 +400,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
397400
fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> {
398401
let func_name = self.tcx.symbol_name(instance).name;
399402

400-
let func = if self.intrinsics.borrow().contains_key(func_name) {
401-
self.intrinsics.borrow()[func_name]
402-
} else if let Some(variable) = self.get_declared_value(func_name) {
403+
let func = if let Some(variable) = self.get_declared_value(func_name) {
403404
return variable;
404405
} else {
405406
get_fn(self, instance)

src/declare.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_target::callconv::FnAbi;
88

99
use crate::abi::{FnAbiGcc, FnAbiGccExt};
1010
use crate::context::CodegenCx;
11-
use crate::intrinsic::llvm;
1211

1312
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
1413
pub fn get_or_insert_global(
@@ -162,19 +161,6 @@ fn declare_raw_fn<'gcc>(
162161
param_types: &[Type<'gcc>],
163162
variadic: bool,
164163
) -> Function<'gcc> {
165-
if name.starts_with("llvm.") {
166-
let intrinsic = match name {
167-
"llvm.fma.f16" => {
168-
// fma is not a target builtin, but a normal builtin, so we handle it differently
169-
// here.
170-
cx.context.get_builtin_function("fma")
171-
}
172-
_ => llvm::intrinsic(name, cx),
173-
};
174-
175-
cx.intrinsics.borrow_mut().insert(name.to_string(), intrinsic);
176-
return intrinsic;
177-
}
178164
let func = if cx.functions.borrow().contains_key(name) {
179165
cx.functions.borrow()[name]
180166
} else {

src/intrinsic/mod.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,47 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
615615
args: &[OperandRef<'tcx, Self::Value>],
616616
is_cleanup: bool,
617617
) -> Self::Value {
618-
let fn_ptr = self.get_fn_addr(instance);
618+
let func = if let Some(&func) = self.intrinsic_instances.borrow().get(&instance) {
619+
func
620+
} else {
621+
let sym = self.tcx.symbol_name(instance).name;
622+
623+
let func = if let Some(func) = self.intrinsics.borrow().get(sym) {
624+
*func
625+
} else {
626+
self.linkage.set(FunctionType::Extern);
627+
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
628+
let fn_ty = fn_abi.gcc_type(self);
629+
630+
let func = match sym {
631+
"llvm.fma.f16" => {
632+
// fma is not a target builtin, but a normal builtin, so we handle it differently
633+
// here.
634+
self.context.get_builtin_function("fma")
635+
}
636+
_ => llvm::intrinsic(sym, self),
637+
};
638+
639+
self.intrinsics.borrow_mut().insert(sym.to_string(), func);
640+
641+
self.on_stack_function_params
642+
.borrow_mut()
643+
.insert(func, fn_ty.on_stack_param_indices);
644+
#[cfg(feature = "master")]
645+
for fn_attr in fn_ty.fn_attributes {
646+
func.add_attribute(fn_attr);
647+
}
648+
649+
crate::attributes::from_fn_attrs(self, func, instance);
650+
651+
func
652+
};
653+
654+
self.intrinsic_instances.borrow_mut().insert(instance, func);
655+
656+
func
657+
};
658+
let fn_ptr = func.get_address(None);
619659
let fn_ty = fn_ptr.get_type();
620660

621661
let mut llargs = vec![];

0 commit comments

Comments
 (0)