@@ -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,36 @@ 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+ match self . arg_ext {
63+ ArgExtension :: None => { }
64+ ArgExtension :: Zext => llvm:: Attribute :: ZExt . apply_llfn ( idx, llfn) ,
65+ ArgExtension :: Sext => llvm:: Attribute :: SExt . apply_llfn ( idx, llfn) ,
66+ }
67+ // Only apply remaining attributes when optimizing
68+ if cx. sess ( ) . opts . optimize == config:: OptLevel :: No {
69+ return ;
70+ }
6571 let deref = self . pointee_size . bytes ( ) ;
6672 if deref != 0 {
6773 if regular. contains ( ArgAttribute :: NonNull ) {
@@ -74,19 +80,14 @@ impl ArgAttributesExt for ArgAttributes {
7480 if let Some ( align) = self . pointee_align {
7581 llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
7682 }
77- regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
83+ for ( attr, llattr) in OPTIMIZATION_ATTRIBUTES {
84+ if regular. contains ( attr) {
85+ llattr. apply_llfn ( idx, llfn) ;
86+ }
87+ }
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,21 @@ 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+ match self . arg_ext {
109+ ArgExtension :: None => { }
110+ ArgExtension :: Zext => llvm:: Attribute :: ZExt . apply_callsite ( idx, callsite) ,
111+ ArgExtension :: Sext => llvm:: Attribute :: SExt . apply_callsite ( idx, callsite) ,
112+ }
113+ // Only apply remaining attributes when optimizing
114+ if cx. sess ( ) . opts . optimize == config:: OptLevel :: No {
115+ return ;
116+ }
101117 let deref = self . pointee_size . bytes ( ) ;
102118 if deref != 0 {
103119 if regular. contains ( ArgAttribute :: NonNull ) {
@@ -118,19 +134,14 @@ impl ArgAttributesExt for ArgAttributes {
118134 align. bytes ( ) as u32 ,
119135 ) ;
120136 }
121- regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
137+ for ( attr, llattr) in OPTIMIZATION_ATTRIBUTES {
138+ if regular. contains ( attr) {
139+ llattr. apply_callsite ( idx, callsite) ;
140+ }
141+ }
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