@@ -13,34 +13,14 @@ use rustc_middle::bug;
1313use rustc_middle:: ty:: layout:: LayoutOf ;
1414pub use rustc_middle:: ty:: layout:: { FAT_PTR_ADDR , FAT_PTR_EXTRA } ;
1515use rustc_middle:: ty:: Ty ;
16+ use rustc_session:: config;
1617use rustc_target:: abi:: call:: ArgAbi ;
1718pub use rustc_target:: abi:: call:: * ;
1819use rustc_target:: abi:: { self , HasDataLayout , Int } ;
1920pub use rustc_target:: spec:: abi:: Abi ;
2021
2122use libc:: c_uint;
2223
23- macro_rules! for_each_kind {
24- ( $flags: ident, $f: ident, $( $kind: ident) ,+) => ( {
25- $( if $flags. contains( ArgAttribute :: $kind) { $f( llvm:: Attribute :: $kind) } ) +
26- } )
27- }
28-
29- trait ArgAttributeExt {
30- fn for_each_kind < F > ( & self , f : F )
31- where
32- F : FnMut ( llvm:: Attribute ) ;
33- }
34-
35- impl ArgAttributeExt for ArgAttribute {
36- fn for_each_kind < F > ( & self , mut f : F )
37- where
38- F : FnMut ( llvm:: Attribute ) ,
39- {
40- for_each_kind ! ( self , f, NoAlias , NoCapture , NonNull , ReadOnly , InReg , NoUndef )
41- }
42- }
43-
4424pub trait ArgAttributesExt {
4525 fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) ;
4626 fn apply_attrs_to_callsite (
@@ -58,10 +38,39 @@ fn should_use_mutable_noalias(cx: &CodegenCx<'_, '_>) -> bool {
5838 cx. tcx . sess . opts . debugging_opts . mutable_noalias . unwrap_or ( true )
5939}
6040
41+ const ABI_AFFECTING_ATTRIBUTES : [ ( ArgAttribute , llvm:: Attribute ) ; 1 ] =
42+ [ ( ArgAttribute :: InReg , llvm:: Attribute :: InReg ) ] ;
43+
44+ const OPTIMIZATION_ATTRIBUTES : [ ( ArgAttribute , llvm:: Attribute ) ; 5 ] = [
45+ ( ArgAttribute :: NoAlias , llvm:: Attribute :: NoAlias ) ,
46+ ( ArgAttribute :: NoCapture , llvm:: Attribute :: NoCapture ) ,
47+ ( ArgAttribute :: NonNull , llvm:: Attribute :: NonNull ) ,
48+ ( ArgAttribute :: ReadOnly , llvm:: Attribute :: ReadOnly ) ,
49+ ( ArgAttribute :: NoUndef , llvm:: Attribute :: NoUndef ) ,
50+ ] ;
51+
6152impl ArgAttributesExt for ArgAttributes {
6253 fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) {
6354 let mut regular = self . regular ;
6455 unsafe {
56+ // ABI-affecting attributes must always be applied
57+ for ( attr, llattr) in ABI_AFFECTING_ATTRIBUTES {
58+ if regular. contains ( attr) {
59+ llattr. apply_llfn ( idx, llfn) ;
60+ }
61+ }
62+ if let Some ( align) = self . pointee_align {
63+ llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
64+ }
65+ match self . arg_ext {
66+ ArgExtension :: None => { }
67+ ArgExtension :: Zext => llvm:: Attribute :: ZExt . apply_llfn ( idx, llfn) ,
68+ ArgExtension :: Sext => llvm:: Attribute :: SExt . apply_llfn ( idx, llfn) ,
69+ }
70+ // Only apply remaining attributes when optimizing
71+ if cx. sess ( ) . opts . optimize == config:: OptLevel :: No {
72+ return ;
73+ }
6574 let deref = self . pointee_size . bytes ( ) ;
6675 if deref != 0 {
6776 if regular. contains ( ArgAttribute :: NonNull ) {
@@ -71,22 +80,14 @@ impl ArgAttributesExt for ArgAttributes {
7180 }
7281 regular -= ArgAttribute :: NonNull ;
7382 }
74- if let Some ( align) = self . pointee_align {
75- llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
83+ for ( attr, llattr) in OPTIMIZATION_ATTRIBUTES {
84+ if regular. contains ( attr) {
85+ llattr. apply_llfn ( idx, llfn) ;
86+ }
7687 }
77- regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
7888 if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
7989 llvm:: Attribute :: NoAlias . apply_llfn ( idx, llfn) ;
8090 }
81- match self . arg_ext {
82- ArgExtension :: None => { }
83- ArgExtension :: Zext => {
84- llvm:: Attribute :: ZExt . apply_llfn ( idx, llfn) ;
85- }
86- ArgExtension :: Sext => {
87- llvm:: Attribute :: SExt . apply_llfn ( idx, llfn) ;
88- }
89- }
9091 }
9192 }
9293
@@ -98,6 +99,28 @@ impl ArgAttributesExt for ArgAttributes {
9899 ) {
99100 let mut regular = self . regular ;
100101 unsafe {
102+ // ABI-affecting attributes must always be applied
103+ for ( attr, llattr) in ABI_AFFECTING_ATTRIBUTES {
104+ if regular. contains ( attr) {
105+ llattr. apply_callsite ( idx, callsite) ;
106+ }
107+ }
108+ if let Some ( align) = self . pointee_align {
109+ llvm:: LLVMRustAddAlignmentCallSiteAttr (
110+ callsite,
111+ idx. as_uint ( ) ,
112+ align. bytes ( ) as u32 ,
113+ ) ;
114+ }
115+ match self . arg_ext {
116+ ArgExtension :: None => { }
117+ ArgExtension :: Zext => llvm:: Attribute :: ZExt . apply_callsite ( idx, callsite) ,
118+ ArgExtension :: Sext => llvm:: Attribute :: SExt . apply_callsite ( idx, callsite) ,
119+ }
120+ // Only apply remaining attributes when optimizing
121+ if cx. sess ( ) . opts . optimize == config:: OptLevel :: No {
122+ return ;
123+ }
101124 let deref = self . pointee_size . bytes ( ) ;
102125 if deref != 0 {
103126 if regular. contains ( ArgAttribute :: NonNull ) {
@@ -111,26 +134,14 @@ impl ArgAttributesExt for ArgAttributes {
111134 }
112135 regular -= ArgAttribute :: NonNull ;
113136 }
114- if let Some ( align) = self . pointee_align {
115- llvm:: LLVMRustAddAlignmentCallSiteAttr (
116- callsite,
117- idx. as_uint ( ) ,
118- align. bytes ( ) as u32 ,
119- ) ;
137+ for ( attr, llattr) in OPTIMIZATION_ATTRIBUTES {
138+ if regular. contains ( attr) {
139+ llattr. apply_callsite ( idx, callsite) ;
140+ }
120141 }
121- regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
122142 if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
123143 llvm:: Attribute :: NoAlias . apply_callsite ( idx, callsite) ;
124144 }
125- match self . arg_ext {
126- ArgExtension :: None => { }
127- ArgExtension :: Zext => {
128- llvm:: Attribute :: ZExt . apply_callsite ( idx, callsite) ;
129- }
130- ArgExtension :: Sext => {
131- llvm:: Attribute :: SExt . apply_callsite ( idx, callsite) ;
132- }
133- }
134145 }
135146 }
136147}
0 commit comments