@@ -5,103 +5,49 @@ use crate::value_and_place::assert_assignable;
5
5
6
6
use cranelift_codegen:: ir:: ArgumentPurpose ;
7
7
use rustc_target:: abi:: call:: { ArgAbi , PassMode } ;
8
- pub ( super ) use EmptySinglePair :: * ;
9
-
10
- #[ derive( Copy , Clone , Debug ) ]
11
- pub ( super ) enum EmptySinglePair < T > {
12
- Empty ,
13
- Single ( T ) ,
14
- Pair ( T , T ) ,
15
- }
16
-
17
- impl < T > EmptySinglePair < T > {
18
- pub ( super ) fn into_iter ( self ) -> EmptySinglePairIter < T > {
19
- EmptySinglePairIter ( self )
20
- }
21
-
22
- pub ( super ) fn map < U > ( self , mut f : impl FnMut ( T ) -> U ) -> EmptySinglePair < U > {
23
- match self {
24
- Empty => Empty ,
25
- Single ( v) => Single ( f ( v) ) ,
26
- Pair ( a, b) => Pair ( f ( a) , f ( b) ) ,
27
- }
28
- }
29
- }
30
-
31
- pub ( super ) struct EmptySinglePairIter < T > ( EmptySinglePair < T > ) ;
32
-
33
- impl < T > Iterator for EmptySinglePairIter < T > {
34
- type Item = T ;
35
-
36
- fn next ( & mut self ) -> Option < T > {
37
- match std:: mem:: replace ( & mut self . 0 , Empty ) {
38
- Empty => None ,
39
- Single ( v) => Some ( v) ,
40
- Pair ( a, b) => {
41
- self . 0 = Single ( b) ;
42
- Some ( a)
43
- }
44
- }
45
- }
46
- }
47
-
48
- impl < T : std:: fmt:: Debug > EmptySinglePair < T > {
49
- pub ( super ) fn assert_single ( self ) -> T {
50
- match self {
51
- Single ( v) => v,
52
- _ => panic ! ( "Called assert_single on {:?}" , self ) ,
53
- }
54
- }
55
-
56
- pub ( super ) fn assert_pair ( self ) -> ( T , T ) {
57
- match self {
58
- Pair ( a, b) => ( a, b) ,
59
- _ => panic ! ( "Called assert_pair on {:?}" , self ) ,
60
- }
61
- }
62
- }
8
+ use smallvec:: { smallvec, SmallVec } ;
63
9
64
10
pub ( super ) trait ArgAbiExt < ' tcx > {
65
- fn get_abi_param ( & self , tcx : TyCtxt < ' tcx > ) -> EmptySinglePair < AbiParam > ;
11
+ fn get_abi_param ( & self , tcx : TyCtxt < ' tcx > ) -> SmallVec < [ AbiParam ; 2 ] > ;
66
12
fn get_abi_return ( & self , tcx : TyCtxt < ' tcx > ) -> ( Option < AbiParam > , Vec < AbiParam > ) ;
67
13
}
68
14
69
15
impl < ' tcx > ArgAbiExt < ' tcx > for ArgAbi < ' tcx , Ty < ' tcx > > {
70
- fn get_abi_param ( & self , tcx : TyCtxt < ' tcx > ) -> EmptySinglePair < AbiParam > {
16
+ fn get_abi_param ( & self , tcx : TyCtxt < ' tcx > ) -> SmallVec < [ AbiParam ; 2 ] > {
71
17
match self . mode {
72
- PassMode :: Ignore => EmptySinglePair :: Empty ,
18
+ PassMode :: Ignore => smallvec ! [ ] ,
73
19
PassMode :: Direct ( _) => match & self . layout . abi {
74
20
Abi :: Scalar ( scalar) => {
75
- EmptySinglePair :: Single ( AbiParam :: new ( scalar_to_clif_type ( tcx, scalar. clone ( ) ) ) )
21
+ smallvec ! [ AbiParam :: new( scalar_to_clif_type( tcx, scalar. clone( ) ) ) ]
76
22
}
77
23
Abi :: Vector { .. } => {
78
24
let vector_ty = crate :: intrinsics:: clif_vector_type ( tcx, self . layout ) . unwrap ( ) ;
79
- EmptySinglePair :: Single ( AbiParam :: new ( vector_ty) )
25
+ smallvec ! [ AbiParam :: new( vector_ty) ]
80
26
}
81
27
_ => unreachable ! ( "{:?}" , self . layout. abi) ,
82
28
} ,
83
29
PassMode :: Pair ( _, _) => match & self . layout . abi {
84
30
Abi :: ScalarPair ( a, b) => {
85
31
let a = scalar_to_clif_type ( tcx, a. clone ( ) ) ;
86
32
let b = scalar_to_clif_type ( tcx, b. clone ( ) ) ;
87
- EmptySinglePair :: Pair ( AbiParam :: new ( a) , AbiParam :: new ( b) )
33
+ smallvec ! [ AbiParam :: new( a) , AbiParam :: new( b) ]
88
34
}
89
35
_ => unreachable ! ( "{:?}" , self . layout. abi) ,
90
36
} ,
91
- PassMode :: Cast ( _) => EmptySinglePair :: Single ( AbiParam :: new ( pointer_ty ( tcx) ) ) ,
37
+ PassMode :: Cast ( _) => smallvec ! [ AbiParam :: new( pointer_ty( tcx) ) ] ,
92
38
PassMode :: Indirect {
93
39
attrs : _,
94
40
extra_attrs : None ,
95
41
on_stack,
96
42
} => {
97
43
if on_stack {
98
44
let size = u32:: try_from ( self . layout . size . bytes ( ) ) . unwrap ( ) ;
99
- EmptySinglePair :: Single ( AbiParam :: special (
45
+ smallvec ! [ AbiParam :: special(
100
46
pointer_ty( tcx) ,
101
47
ArgumentPurpose :: StructArgument ( size) ,
102
- ) )
48
+ ) ]
103
49
} else {
104
- EmptySinglePair :: Single ( AbiParam :: new ( pointer_ty ( tcx) ) )
50
+ smallvec ! [ AbiParam :: new( pointer_ty( tcx) ) ]
105
51
}
106
52
}
107
53
PassMode :: Indirect {
@@ -110,10 +56,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
110
56
on_stack,
111
57
} => {
112
58
assert ! ( !on_stack) ;
113
- EmptySinglePair :: Pair (
59
+ smallvec ! [
114
60
AbiParam :: new( pointer_ty( tcx) ) ,
115
61
AbiParam :: new( pointer_ty( tcx) ) ,
116
- )
62
+ ]
117
63
}
118
64
}
119
65
}
@@ -176,18 +122,18 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
176
122
fx : & mut FunctionCx < ' _ , ' tcx , impl Module > ,
177
123
arg : CValue < ' tcx > ,
178
124
arg_abi : & ArgAbi < ' tcx , Ty < ' tcx > > ,
179
- ) -> EmptySinglePair < Value > {
125
+ ) -> SmallVec < [ Value ; 2 ] > {
180
126
assert_assignable ( fx, arg. layout ( ) . ty , arg_abi. layout . ty ) ;
181
127
match arg_abi. mode {
182
- PassMode :: Ignore => Empty ,
183
- PassMode :: Direct ( _) => Single ( arg. load_scalar ( fx) ) ,
128
+ PassMode :: Ignore => smallvec ! [ ] ,
129
+ PassMode :: Direct ( _) => smallvec ! [ arg. load_scalar( fx) ] ,
184
130
PassMode :: Pair ( _, _) => {
185
131
let ( a, b) = arg. load_scalar_pair ( fx) ;
186
- Pair ( a, b)
132
+ smallvec ! [ a, b]
187
133
}
188
134
PassMode :: Cast ( _) | PassMode :: Indirect { .. } => match arg. force_stack ( fx) {
189
- ( ptr, None ) => Single ( ptr. get_addr ( fx) ) ,
190
- ( ptr, Some ( meta) ) => Pair ( ptr. get_addr ( fx) , meta) ,
135
+ ( ptr, None ) => smallvec ! [ ptr. get_addr( fx) ] ,
136
+ ( ptr, Some ( meta) ) => smallvec ! [ ptr. get_addr( fx) , meta] ,
191
137
} ,
192
138
}
193
139
}
@@ -202,47 +148,57 @@ pub(super) fn cvalue_for_param<'tcx>(
202
148
arg_abi : & ArgAbi < ' tcx , Ty < ' tcx > > ,
203
149
) -> Option < CValue < ' tcx > > {
204
150
let clif_types = arg_abi. get_abi_param ( fx. tcx ) ;
205
- let block_params =
206
- clif_types. map ( |abi_param| fx. bcx . append_block_param ( start_block, abi_param. value_type ) ) ;
151
+ let block_params = clif_types
152
+ . into_iter ( )
153
+ . map ( |abi_param| fx. bcx . append_block_param ( start_block, abi_param. value_type ) )
154
+ . collect :: < SmallVec < [ _ ; 2 ] > > ( ) ;
207
155
208
156
#[ cfg( debug_assertions) ]
209
157
crate :: abi:: comments:: add_arg_comment (
210
158
fx,
211
159
"arg" ,
212
160
local,
213
161
local_field,
214
- block_params,
162
+ & block_params,
215
163
arg_abi. mode ,
216
164
arg_abi. layout ,
217
165
) ;
218
166
219
167
match arg_abi. mode {
220
168
PassMode :: Ignore => None ,
221
169
PassMode :: Direct ( _) => {
222
- Some ( CValue :: by_val ( block_params. assert_single ( ) , arg_abi. layout ) )
170
+ assert_eq ! ( block_params. len( ) , 1 , "{:?}" , block_params) ;
171
+ Some ( CValue :: by_val ( block_params[ 0 ] , arg_abi. layout ) )
223
172
}
224
173
PassMode :: Pair ( _, _) => {
225
- let ( a, b) = block_params. assert_pair ( ) ;
226
- Some ( CValue :: by_val_pair ( a, b, arg_abi. layout ) )
174
+ assert_eq ! ( block_params. len( ) , 2 , "{:?}" , block_params) ;
175
+ Some ( CValue :: by_val_pair (
176
+ block_params[ 0 ] ,
177
+ block_params[ 1 ] ,
178
+ arg_abi. layout ,
179
+ ) )
227
180
}
228
181
PassMode :: Cast ( _)
229
182
| PassMode :: Indirect {
230
183
attrs : _,
231
184
extra_attrs : None ,
232
185
on_stack : _,
233
- } => Some ( CValue :: by_ref (
234
- Pointer :: new ( block_params. assert_single ( ) ) ,
235
- arg_abi. layout ,
236
- ) ) ,
186
+ } => {
187
+ assert_eq ! ( block_params. len( ) , 1 , "{:?}" , block_params) ;
188
+ Some ( CValue :: by_ref (
189
+ Pointer :: new ( block_params[ 0 ] ) ,
190
+ arg_abi. layout ,
191
+ ) )
192
+ }
237
193
PassMode :: Indirect {
238
194
attrs : _,
239
195
extra_attrs : Some ( _) ,
240
196
on_stack : _,
241
197
} => {
242
- let ( ptr , meta ) = block_params. assert_pair ( ) ;
198
+ assert_eq ! ( block_params . len ( ) , 2 , "{:?}" , block_params) ;
243
199
Some ( CValue :: by_ref_unsized (
244
- Pointer :: new ( ptr ) ,
245
- meta ,
200
+ Pointer :: new ( block_params [ 0 ] ) ,
201
+ block_params [ 1 ] ,
246
202
arg_abi. layout ,
247
203
) )
248
204
}
0 commit comments