@@ -13,34 +13,14 @@ use rustc_middle::bug;
13
13
use rustc_middle:: ty:: layout:: LayoutOf ;
14
14
pub use rustc_middle:: ty:: layout:: { FAT_PTR_ADDR , FAT_PTR_EXTRA } ;
15
15
use rustc_middle:: ty:: Ty ;
16
+ use rustc_session:: config;
16
17
use rustc_target:: abi:: call:: ArgAbi ;
17
18
pub use rustc_target:: abi:: call:: * ;
18
19
use rustc_target:: abi:: { self , HasDataLayout , Int } ;
19
20
pub use rustc_target:: spec:: abi:: Abi ;
20
21
21
22
use libc:: c_uint;
22
23
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
-
44
24
pub trait ArgAttributesExt {
45
25
fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) ;
46
26
fn apply_attrs_to_callsite (
@@ -58,10 +38,36 @@ fn should_use_mutable_noalias(cx: &CodegenCx<'_, '_>) -> bool {
58
38
cx. tcx . sess . opts . debugging_opts . mutable_noalias . unwrap_or ( true )
59
39
}
60
40
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
+
61
52
impl ArgAttributesExt for ArgAttributes {
62
53
fn apply_attrs_to_llfn ( & self , idx : AttributePlace , cx : & CodegenCx < ' _ , ' _ > , llfn : & Value ) {
63
54
let mut regular = self . regular ;
64
55
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
+ }
65
71
let deref = self . pointee_size . bytes ( ) ;
66
72
if deref != 0 {
67
73
if regular. contains ( ArgAttribute :: NonNull ) {
@@ -74,19 +80,14 @@ impl ArgAttributesExt for ArgAttributes {
74
80
if let Some ( align) = self . pointee_align {
75
81
llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
76
82
}
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
+ }
78
88
if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
79
89
llvm:: Attribute :: NoAlias . apply_llfn ( idx, llfn) ;
80
90
}
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
- }
90
91
}
91
92
}
92
93
@@ -98,6 +99,21 @@ impl ArgAttributesExt for ArgAttributes {
98
99
) {
99
100
let mut regular = self . regular ;
100
101
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
+ }
101
117
let deref = self . pointee_size . bytes ( ) ;
102
118
if deref != 0 {
103
119
if regular. contains ( ArgAttribute :: NonNull ) {
@@ -118,19 +134,14 @@ impl ArgAttributesExt for ArgAttributes {
118
134
align. bytes ( ) as u32 ,
119
135
) ;
120
136
}
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
+ }
122
142
if regular. contains ( ArgAttribute :: NoAliasMutRef ) && should_use_mutable_noalias ( cx) {
123
143
llvm:: Attribute :: NoAlias . apply_callsite ( idx, callsite) ;
124
144
}
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
- }
134
145
}
135
146
}
136
147
}
0 commit comments