@@ -5,103 +5,49 @@ use crate::value_and_place::assert_assignable;
55
66use cranelift_codegen:: ir:: ArgumentPurpose ;
77use 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 } ;
639
6410pub ( 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 ] > ;
6612 fn get_abi_return ( & self , tcx : TyCtxt < ' tcx > ) -> ( Option < AbiParam > , Vec < AbiParam > ) ;
6713}
6814
6915impl < ' 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 ] > {
7117 match self . mode {
72- PassMode :: Ignore => EmptySinglePair :: Empty ,
18+ PassMode :: Ignore => smallvec ! [ ] ,
7319 PassMode :: Direct ( _) => match & self . layout . abi {
7420 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( ) ) ) ]
7622 }
7723 Abi :: Vector { .. } => {
7824 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) ]
8026 }
8127 _ => unreachable ! ( "{:?}" , self . layout. abi) ,
8228 } ,
8329 PassMode :: Pair ( _, _) => match & self . layout . abi {
8430 Abi :: ScalarPair ( a, b) => {
8531 let a = scalar_to_clif_type ( tcx, a. clone ( ) ) ;
8632 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) ]
8834 }
8935 _ => unreachable ! ( "{:?}" , self . layout. abi) ,
9036 } ,
91- PassMode :: Cast ( _) => EmptySinglePair :: Single ( AbiParam :: new ( pointer_ty ( tcx) ) ) ,
37+ PassMode :: Cast ( _) => smallvec ! [ AbiParam :: new( pointer_ty( tcx) ) ] ,
9238 PassMode :: Indirect {
9339 attrs : _,
9440 extra_attrs : None ,
9541 on_stack,
9642 } => {
9743 if on_stack {
9844 let size = u32:: try_from ( self . layout . size . bytes ( ) ) . unwrap ( ) ;
99- EmptySinglePair :: Single ( AbiParam :: special (
45+ smallvec ! [ AbiParam :: special(
10046 pointer_ty( tcx) ,
10147 ArgumentPurpose :: StructArgument ( size) ,
102- ) )
48+ ) ]
10349 } else {
104- EmptySinglePair :: Single ( AbiParam :: new ( pointer_ty ( tcx) ) )
50+ smallvec ! [ AbiParam :: new( pointer_ty( tcx) ) ]
10551 }
10652 }
10753 PassMode :: Indirect {
@@ -110,10 +56,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
11056 on_stack,
11157 } => {
11258 assert ! ( !on_stack) ;
113- EmptySinglePair :: Pair (
59+ smallvec ! [
11460 AbiParam :: new( pointer_ty( tcx) ) ,
11561 AbiParam :: new( pointer_ty( tcx) ) ,
116- )
62+ ]
11763 }
11864 }
11965 }
@@ -176,18 +122,18 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
176122 fx : & mut FunctionCx < ' _ , ' tcx , impl Module > ,
177123 arg : CValue < ' tcx > ,
178124 arg_abi : & ArgAbi < ' tcx , Ty < ' tcx > > ,
179- ) -> EmptySinglePair < Value > {
125+ ) -> SmallVec < [ Value ; 2 ] > {
180126 assert_assignable ( fx, arg. layout ( ) . ty , arg_abi. layout . ty ) ;
181127 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) ] ,
184130 PassMode :: Pair ( _, _) => {
185131 let ( a, b) = arg. load_scalar_pair ( fx) ;
186- Pair ( a, b)
132+ smallvec ! [ a, b]
187133 }
188134 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] ,
191137 } ,
192138 }
193139}
@@ -202,47 +148,57 @@ pub(super) fn cvalue_for_param<'tcx>(
202148 arg_abi : & ArgAbi < ' tcx , Ty < ' tcx > > ,
203149) -> Option < CValue < ' tcx > > {
204150 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 ] > > ( ) ;
207155
208156 #[ cfg( debug_assertions) ]
209157 crate :: abi:: comments:: add_arg_comment (
210158 fx,
211159 "arg" ,
212160 local,
213161 local_field,
214- block_params,
162+ & block_params,
215163 arg_abi. mode ,
216164 arg_abi. layout ,
217165 ) ;
218166
219167 match arg_abi. mode {
220168 PassMode :: Ignore => None ,
221169 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 ) )
223172 }
224173 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+ ) )
227180 }
228181 PassMode :: Cast ( _)
229182 | PassMode :: Indirect {
230183 attrs : _,
231184 extra_attrs : None ,
232185 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+ }
237193 PassMode :: Indirect {
238194 attrs : _,
239195 extra_attrs : Some ( _) ,
240196 on_stack : _,
241197 } => {
242- let ( ptr , meta ) = block_params. assert_pair ( ) ;
198+ assert_eq ! ( block_params . len ( ) , 2 , "{:?}" , block_params) ;
243199 Some ( CValue :: by_ref_unsized (
244- Pointer :: new ( ptr ) ,
245- meta ,
200+ Pointer :: new ( block_params [ 0 ] ) ,
201+ block_params [ 1 ] ,
246202 arg_abi. layout ,
247203 ) )
248204 }
0 commit comments