diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
commit | ef24de24a82fe681581cc130f342363c47c0969a (patch) | |
tree | 0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_codegen_gcc/src/abi.rs | |
parent | Releasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip |
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/abi.rs')
-rw-r--r-- | compiler/rustc_codegen_gcc/src/abi.rs | 95 |
1 files changed, 78 insertions, 17 deletions
diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index a49530ebb..f601cd95f 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -1,9 +1,13 @@ +#[cfg(feature = "master")] +use gccjit::FnAttribute; use gccjit::{ToLValue, ToRValue, Type}; use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeMethods}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; use rustc_middle::ty::Ty; -use rustc_target::abi::call::{CastTarget, FnAbi, PassMode, Reg, RegKind}; +#[cfg(feature = "master")] +use rustc_session::config; +use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -94,14 +98,23 @@ impl GccType for Reg { } } +pub struct FnAbiGcc<'gcc> { + pub return_type: Type<'gcc>, + pub arguments_type: Vec<Type<'gcc>>, + pub is_c_variadic: bool, + pub on_stack_param_indices: FxHashSet<usize>, + #[cfg(feature = "master")] + pub fn_attributes: Vec<FnAttribute<'gcc>>, +} + pub trait FnAbiGccExt<'gcc, 'tcx> { // TODO(antoyo): return a function pointer type instead? - fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> (Type<'gcc>, Vec<Type<'gcc>>, bool, FxHashSet<usize>); + fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc>; fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; } impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { - fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> (Type<'gcc>, Vec<Type<'gcc>>, bool, FxHashSet<usize>) { + fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc> { let mut on_stack_param_indices = FxHashSet::default(); // This capacity calculation is approximate. @@ -109,7 +122,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { self.args.len() + if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } ); - let return_ty = + let return_type = match self.ret.mode { PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), @@ -119,41 +132,89 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { cx.type_void() } }; + #[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 cx.sess().opts.optimize == config::OptLevel::No { + return ty; + } + if attrs.regular.contains(rustc_target::abi::call::ArgAttribute::NoAlias) { + ty = ty.make_restrict() + } + if attrs.regular.contains(rustc_target::abi::call::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 + }; for arg in self.args.iter() { let arg_ty = match arg.mode { PassMode::Ignore => continue, - PassMode::Direct(_) => arg.layout.immediate_gcc_type(cx), - PassMode::Pair(..) => { - argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 0)); - argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1)); + PassMode::Pair(a, b) => { + let arg_pos = argument_tys.len(); + argument_tys.push(apply_attrs(arg.layout.scalar_pair_element_gcc_type(cx, 0), &a, arg_pos)); + argument_tys.push(apply_attrs(arg.layout.scalar_pair_element_gcc_type(cx, 1), &b, arg_pos + 1)); continue; } - PassMode::Indirect { meta_attrs: Some(_), .. } => { - unimplemented!(); - } PassMode::Cast { ref cast, pad_i32 } => { // add padding if pad_i32 { argument_tys.push(Reg::i32().gcc_type(cx)); } - cast.gcc_type(cx) + let ty = cast.gcc_type(cx); + apply_attrs(ty, &cast.attrs, argument_tys.len()) } - PassMode::Indirect { meta_attrs: None, on_stack: true, .. } => { + PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => { + // This is a "byval" argument, so we don't apply the `restrict` attribute on it. on_stack_param_indices.insert(argument_tys.len()); arg.memory_ty(cx) }, - PassMode::Indirect { meta_attrs: None, on_stack: false, .. } => cx.type_ptr_to(arg.memory_ty(cx)), + PassMode::Direct(attrs) => apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len()), + PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { + apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()) + } + PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { + assert!(!on_stack); + let ty = apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()); + apply_attrs(ty, &meta_attrs, argument_tys.len()) + } }; argument_tys.push(arg_ty); } - (return_ty, argument_tys, self.c_variadic, on_stack_param_indices) + #[cfg(feature = "master")] + let fn_attrs = if non_null_args.is_empty() { + Vec::new() + } else { + vec![FnAttribute::NonNull(non_null_args)] + }; + + FnAbiGcc { + return_type, + arguments_type: argument_tys, + is_c_variadic: self.c_variadic, + on_stack_param_indices, + #[cfg(feature = "master")] + fn_attributes: fn_attrs, + } } fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { - let (return_type, params, variadic, on_stack_param_indices) = self.gcc_type(cx); - let pointer_type = cx.context.new_function_pointer_type(None, return_type, ¶ms, variadic); + // FIXME(antoyo): Should we do something with `FnAbiGcc::fn_attributes`? + let FnAbiGcc { + return_type, + arguments_type, + is_c_variadic, + on_stack_param_indices, + .. + } = self.gcc_type(cx); + let pointer_type = cx.context.new_function_pointer_type(None, return_type, &arguments_type, is_c_variadic); cx.on_stack_params.borrow_mut().insert(pointer_type.dyncast_function_ptr_type().expect("function ptr type"), on_stack_param_indices); pointer_type } |