@@ -4,7 +4,8 @@ use rustc_middle::mir::*;
4
4
use rustc_middle:: ty:: util:: IntTypeExt ;
5
5
use rustc_middle:: ty:: { self , Const , Ty , TyCtxt } ;
6
6
use rustc_span:: def_id:: DefId ;
7
- use rustc_target:: abi:: { Size , TagEncoding , Variants } ;
7
+ use rustc_target:: abi:: { HasDataLayout , Size , TagEncoding , Variants } ;
8
+ use std:: array:: IntoIter ;
8
9
9
10
/// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large
10
11
/// enough discrepanc between them
@@ -21,11 +22,10 @@ impl<const D: u64> EnumSizeOpt<D> {
21
22
tcx : TyCtxt < ' tcx > ,
22
23
ty : Ty < ' tcx > ,
23
24
body_did : DefId ,
24
- ) -> Option < ( Size , u64 , Vec < Size > ) > {
25
+ ) -> Option < ( u64 , Vec < Size > ) > {
25
26
match ty. kind ( ) {
26
27
ty:: Adt ( adt_def, _substs) if adt_def. is_enum ( ) => {
27
28
let p_e = tcx. param_env ( body_did) ;
28
- // FIXME(jknodt) handle error better below
29
29
let layout =
30
30
if let Ok ( layout) = tcx. layout_of ( p_e. and ( ty) ) { layout } else { return None } ;
31
31
let variants = & layout. variants ;
@@ -50,7 +50,7 @@ impl<const D: u64> EnumSizeOpt<D> {
50
50
assert_eq ! ( discr_sizes[ disc_idx] , Size :: ZERO ) ;
51
51
discr_sizes[ disc_idx] = layout. size ;
52
52
}
53
- Some ( ( layout . size , variants. len ( ) as u64 , discr_sizes) )
53
+ Some ( ( variants. len ( ) as u64 , discr_sizes) )
54
54
}
55
55
}
56
56
}
@@ -73,28 +73,44 @@ impl<const D: u64> EnumSizeOpt<D> {
73
73
let source_info = st. source_info ;
74
74
let span = source_info. span ;
75
75
76
- let ( total_size , num_variants, sizes) =
76
+ let ( num_variants, sizes) =
77
77
if let Some ( cand) = Self :: candidate ( tcx, ty, body_did) {
78
78
cand
79
79
} else {
80
80
return None ;
81
81
} ;
82
82
let adt_def = ty. ty_adt_def ( ) . unwrap ( ) ;
83
-
84
83
let alloc = if let Some ( alloc) = alloc_cache. get ( ty) {
85
84
alloc
86
85
} else {
87
- let mut data =
88
- vec ! [ 0 ; std:: mem:: size_of:: <usize >( ) * num_variants as usize ] ;
89
-
86
+ let data_layout = tcx. data_layout ( ) ;
87
+ let ptr_sized_int = data_layout. ptr_sized_integer ( ) ;
88
+ let target_bytes = ptr_sized_int. size ( ) . bytes ( ) as usize ;
89
+ let mut data = vec ! [ 0 ; target_bytes * num_variants as usize ] ;
90
90
let mut curr = 0 ;
91
- for byte in sizes
92
- . iter ( )
93
- . flat_map ( |sz| sz. bytes ( ) . to_ne_bytes ( ) )
94
- . take ( data. len ( ) )
95
- {
96
- data[ curr] = byte;
97
- curr += 1 ;
91
+ macro_rules! encode_store {
92
+ ( $endian: expr, $bytes: expr) => {
93
+ let bytes = match $endian {
94
+ rustc_target:: abi:: Endian :: Little => $bytes. to_le_bytes( ) ,
95
+ rustc_target:: abi:: Endian :: Big => $bytes. to_be_bytes( ) ,
96
+ } ;
97
+ for b in bytes {
98
+ data[ curr] = b;
99
+ curr += 1 ;
100
+ }
101
+ } ;
102
+ }
103
+
104
+ for sz in sizes {
105
+ match ptr_sized_int {
106
+ rustc_target:: abi:: Integer :: I32 => {
107
+ encode_store ! ( data_layout. endian, sz. bytes( ) as u32 ) ;
108
+ }
109
+ rustc_target:: abi:: Integer :: I64 => {
110
+ encode_store ! ( data_layout. endian, sz. bytes( ) ) ;
111
+ }
112
+ _ => unreachable ! ( ) ,
113
+ } ;
98
114
}
99
115
let alloc = interpret:: Allocation :: from_bytes (
100
116
data,
@@ -162,7 +178,6 @@ impl<const D: u64> EnumSizeOpt<D> {
162
178
) ) ,
163
179
} ;
164
180
165
- // FIXME(jknodt) do I need to add a storage live here for this place?
166
181
let size_place =
167
182
Place :: from ( local_decls. push ( LocalDecl :: new ( tcx. types . usize , span) ) ) ;
168
183
@@ -230,24 +245,15 @@ impl<const D: u64> EnumSizeOpt<D> {
230
245
kind : StatementKind :: CopyNonOverlapping ( box CopyNonOverlapping {
231
246
src : Operand :: Copy ( src_cast_place) ,
232
247
dst : Operand :: Copy ( dst_cast_place) ,
233
- count : Operand :: Constant (
234
- box ( Constant {
235
- span,
236
- user_ty : None ,
237
- literal : ConstantKind :: Val (
238
- interpret:: ConstValue :: from_u64 ( total_size. bytes ( ) ) ,
239
- tcx. types . usize ,
240
- ) ,
241
- } ) ,
242
- ) ,
248
+ count : Operand :: Copy ( size_place) ,
243
249
} ) ,
244
250
} ;
245
251
246
252
let store_dead = Statement {
247
253
source_info,
248
254
kind : StatementKind :: StorageDead ( size_array_local) ,
249
255
} ;
250
- let iter = std :: array :: IntoIter :: new ( [
256
+ let iter = IntoIter :: new ( [
251
257
store_live,
252
258
const_assign,
253
259
store_discr,
0 commit comments