about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2023-08-12 16:12:15 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2023-08-25 22:39:22 +0200
commit5ac2530d3ce2632226456edcb5d60403bbe6e79a (patch)
tree2426fee2ba372f16fed77ea2dcad6b00c71c289c
parent4ffa4254e18296150da182b609c7c8303903ed4d (diff)
downloadrust-5ac2530d3ce2632226456edcb5d60403bbe6e79a.tar.gz
rust-5ac2530d3ce2632226456edcb5d60403bbe6e79a.zip
Add support for `noalias` function parameters
-rw-r--r--src/abi.rs43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/abi.rs b/src/abi.rs
index 6fb1cbfad8c..8f5cd30fe3c 100644
--- a/src/abi.rs
+++ b/src/abi.rs
@@ -3,7 +3,7 @@ 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};
+use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
@@ -120,30 +120,49 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                 }
             };
 
+        #[cfg(feature = "master")]
+        let apply_attrs = |ty: Type<'gcc>, attrs: &ArgAttributes| {
+            if attrs.regular.contains(rustc_target::abi::call::ArgAttribute::NoAlias)
+                && ty.get_pointee().is_some()
+            {
+                ty.make_restrict()
+            } else {
+                ty
+            }
+        };
+        #[cfg(not(feature = "master"))]
+        let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes| {
+            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, true));
-                    argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1, true));
+                PassMode::Pair(a, b) => {
+                    argument_tys.push(apply_attrs(arg.layout.scalar_pair_element_gcc_type(cx, 0, true), &a));
+                    argument_tys.push(apply_attrs(arg.layout.scalar_pair_element_gcc_type(cx, 1, true), &b));
                     continue;
                 }
-                PassMode::Indirect { extra_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)
                 }
-                PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => {
+                PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
                     on_stack_param_indices.insert(argument_tys.len());
-                    arg.memory_ty(cx)
+                    apply_attrs(arg.memory_ty(cx), &attrs)
                 },
-                PassMode::Indirect { extra_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),
+                PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
+                    apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs)
+                }
+                PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
+                    assert!(!on_stack);
+                    apply_attrs(apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs), &extra_attrs)
+                }
             };
             argument_tys.push(arg_ty);
         }