mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Don't compute FnAbi for LLVM intrinsics in backends
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
#[cfg(feature = "master")]
|
||||
use std::iter;
|
||||
|
||||
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
|
||||
#[cfg(feature = "master")]
|
||||
use gccjit::{FnAttribute, Type};
|
||||
use gccjit::Type;
|
||||
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
|
||||
@@ -24,16 +24,16 @@
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, Instance, Ty};
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_session::config;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_target::callconv::ArgAttributes;
|
||||
use rustc_target::callconv::{ArgAbi, PassMode};
|
||||
|
||||
use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
|
||||
#[cfg(feature = "master")]
|
||||
use crate::abi::FnAbiGccExt;
|
||||
use crate::abi::GccType;
|
||||
use crate::builder::Builder;
|
||||
use crate::common::{SignType, TypeReflection};
|
||||
use crate::context::CodegenCx;
|
||||
@@ -625,83 +625,6 @@ fn codegen_llvm_intrinsic_call(
|
||||
*func
|
||||
} else {
|
||||
self.linkage.set(FunctionType::Extern);
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
assert!(!fn_abi.ret.is_indirect());
|
||||
assert!(!fn_abi.c_variadic);
|
||||
|
||||
let return_type = match fn_abi.ret.mode {
|
||||
PassMode::Ignore => self.type_void(),
|
||||
PassMode::Direct(_) | PassMode::Pair(..) => {
|
||||
fn_abi.ret.layout.immediate_gcc_type(self)
|
||||
}
|
||||
PassMode::Cast { .. } | PassMode::Indirect { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
let mut non_null_args = Vec::new();
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
let mut apply_attrs =
|
||||
|mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| {
|
||||
if self.sess().opts.optimize == config::OptLevel::No {
|
||||
return ty;
|
||||
}
|
||||
if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) {
|
||||
ty = ty.make_restrict()
|
||||
}
|
||||
if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) {
|
||||
non_null_args.push(arg_index as i32 + 1);
|
||||
}
|
||||
ty
|
||||
};
|
||||
#[cfg(not(feature = "master"))]
|
||||
let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty;
|
||||
|
||||
let mut argument_tys = Vec::with_capacity(fn_abi.args.len());
|
||||
for arg in fn_abi.args.iter() {
|
||||
match arg.mode {
|
||||
PassMode::Ignore => {}
|
||||
PassMode::Pair(a, b) => {
|
||||
let arg_pos = argument_tys.len();
|
||||
argument_tys.push(apply_attrs(
|
||||
arg.layout.scalar_pair_element_gcc_type(self, 0),
|
||||
&a,
|
||||
arg_pos,
|
||||
));
|
||||
argument_tys.push(apply_attrs(
|
||||
arg.layout.scalar_pair_element_gcc_type(self, 1),
|
||||
&b,
|
||||
arg_pos + 1,
|
||||
));
|
||||
}
|
||||
PassMode::Direct(attrs) => argument_tys.push(apply_attrs(
|
||||
arg.layout.immediate_gcc_type(self),
|
||||
&attrs,
|
||||
argument_tys.len(),
|
||||
)),
|
||||
PassMode::Indirect { .. } | PassMode::Cast { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
let fn_attrs = if non_null_args.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
vec![FnAttribute::NonNull(non_null_args)]
|
||||
};
|
||||
|
||||
let fn_ty = FnAbiGcc {
|
||||
return_type,
|
||||
arguments_type: argument_tys,
|
||||
is_c_variadic: false,
|
||||
on_stack_param_indices: FxHashSet::default(),
|
||||
#[cfg(feature = "master")]
|
||||
fn_attributes: fn_attrs,
|
||||
};
|
||||
|
||||
let func = match sym {
|
||||
"llvm.fma.f16" => {
|
||||
@@ -714,13 +637,7 @@ fn codegen_llvm_intrinsic_call(
|
||||
|
||||
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);
|
||||
}
|
||||
self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default());
|
||||
|
||||
crate::attributes::from_fn_attrs(self, func, instance);
|
||||
|
||||
|
||||
@@ -646,32 +646,34 @@ fn codegen_llvm_intrinsic_call(
|
||||
) -> Self::Value {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// FIXME remove usage of fn_abi
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
assert!(!fn_abi.ret.is_indirect());
|
||||
assert!(!fn_abi.c_variadic);
|
||||
|
||||
let llreturn_ty = match &fn_abi.ret.mode {
|
||||
PassMode::Ignore => self.type_void(),
|
||||
PassMode::Direct(_) | PassMode::Pair(..) => fn_abi.ret.layout.immediate_llvm_type(self),
|
||||
PassMode::Cast { .. } | PassMode::Indirect { .. } => {
|
||||
unreachable!()
|
||||
let fn_ty = instance.ty(tcx, self.typing_env());
|
||||
let fn_sig = match *fn_ty.kind() {
|
||||
ty::FnDef(def_id, args) => {
|
||||
tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert!(!fn_sig.c_variadic);
|
||||
|
||||
let ret_layout = self.layout_of(fn_sig.output());
|
||||
let llreturn_ty = if ret_layout.is_zst() {
|
||||
self.type_void()
|
||||
} else {
|
||||
ret_layout.immediate_llvm_type(self)
|
||||
};
|
||||
|
||||
let mut llargument_tys = Vec::with_capacity(fn_abi.args.len());
|
||||
for arg in &fn_abi.args {
|
||||
match &arg.mode {
|
||||
PassMode::Ignore => {}
|
||||
PassMode::Direct(_) => llargument_tys.push(arg.layout.immediate_llvm_type(self)),
|
||||
PassMode::Pair(..) => {
|
||||
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 0, true));
|
||||
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 1, true));
|
||||
}
|
||||
PassMode::Indirect { .. } | PassMode::Cast { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
let mut llargument_tys = Vec::with_capacity(fn_sig.inputs().len());
|
||||
for &arg in fn_sig.inputs() {
|
||||
let arg_layout = self.layout_of(arg);
|
||||
if arg_layout.is_zst() {
|
||||
continue;
|
||||
}
|
||||
if let BackendRepr::ScalarPair(_, _) = arg_layout.backend_repr {
|
||||
llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 0, true));
|
||||
llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 1, true));
|
||||
continue;
|
||||
}
|
||||
llargument_tys.push(arg_layout.immediate_llvm_type(self));
|
||||
}
|
||||
|
||||
let fn_ty = self.type_func(&llargument_tys, llreturn_ty);
|
||||
|
||||
Reference in New Issue
Block a user