summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_gcc/src/abi.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_codegen_gcc/src/abi.rs
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-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.rs95
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, &params, 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
}