1
- use std:: borrow:: Cow ;
2
-
3
1
use rustc_span:: DUMMY_SP ;
4
2
5
3
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
6
4
use rustc_middle:: mir:: interpret:: {
7
- read_target_uint, AllocId , Allocation , ConstValue , GlobalAlloc , InterpResult , Scalar ,
5
+ read_target_uint, AllocId , Allocation , ConstValue , GlobalAlloc , Pointer , Scalar ,
8
6
} ;
9
7
use rustc_middle:: ty:: { Const , ConstKind } ;
10
8
use rustc_target:: abi:: Align ;
11
9
use rustc_data_structures:: fx:: FxHashSet ;
12
- use rustc_mir:: interpret:: {
13
- ImmTy , InterpCx , Machine , Memory , MemoryKind , OpTy , PlaceTy , Pointer ,
14
- StackPopCleanup , StackPopJump ,
15
- } ;
16
10
17
11
use cranelift_codegen:: ir:: GlobalValue ;
18
12
use cranelift_module:: * ;
@@ -84,6 +78,7 @@ pub(crate) fn trans_const_value<'tcx>(
84
78
) -> CValue < ' tcx > {
85
79
let ty = fx. monomorphize ( & const_. ty ) ;
86
80
let layout = fx. layout_of ( ty) ;
81
+ assert ! ( !layout. is_unsized( ) , "sized const value" ) ;
87
82
88
83
if layout. is_zst ( ) {
89
84
return CValue :: by_ref (
@@ -99,7 +94,15 @@ pub(crate) fn trans_const_value<'tcx>(
99
94
match const_val {
100
95
ConstValue :: Scalar ( x) => {
101
96
if fx. clif_type ( layout. ty ) . is_none ( ) {
102
- return trans_const_place ( fx, const_) . to_cvalue ( fx) ;
97
+ let ( size, align) = ( layout. size , layout. align . pref ) ;
98
+ let mut alloc = Allocation :: from_bytes (
99
+ std:: iter:: repeat ( 0 ) . take ( size. bytes_usize ( ) ) . collect :: < Vec < u8 > > ( ) ,
100
+ align,
101
+ ) ;
102
+ let ptr = Pointer :: new ( AllocId ( !0 ) , Size :: ZERO ) ; // The alloc id is never used
103
+ alloc. write_scalar ( fx, ptr, x. into ( ) , size) . unwrap ( ) ;
104
+ let alloc = fx. tcx . intern_const_alloc ( alloc) ;
105
+ return CValue :: by_ref ( pointer_for_allocation ( fx, alloc) , layout) ;
103
106
}
104
107
105
108
match x {
@@ -140,68 +143,35 @@ pub(crate) fn trans_const_value<'tcx>(
140
143
}
141
144
}
142
145
ConstValue :: ByRef { alloc, offset } => {
143
- let alloc_id = fx. tcx . alloc_map . lock ( ) . create_memory_alloc ( alloc) ;
144
- fx. constants_cx . todo . push ( TodoItem :: Alloc ( alloc_id) ) ;
145
- let data_id = data_id_for_alloc_id ( fx. module , alloc_id, alloc. align ) ;
146
- let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
147
- let global_ptr = fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id) ;
148
- assert ! ( !layout. is_unsized( ) , "unsized ConstValue::ByRef not supported" ) ;
149
146
CValue :: by_ref (
150
- crate :: pointer :: Pointer :: new ( global_ptr )
147
+ pointer_for_allocation ( fx , alloc )
151
148
. offset_i64 ( fx, i64:: try_from ( offset. bytes ( ) ) . unwrap ( ) ) ,
152
149
layout,
153
150
)
154
151
}
155
- ConstValue :: Slice { data : _, start : _, end : _ } => {
156
- trans_const_place ( fx, const_) . to_cvalue ( fx)
152
+ ConstValue :: Slice { data, start, end } => {
153
+ let ptr = pointer_for_allocation ( fx, data)
154
+ . offset_i64 ( fx, i64:: try_from ( start) . unwrap ( ) )
155
+ . get_addr ( fx) ;
156
+ let len = fx. bcx . ins ( ) . iconst ( fx. pointer_type , i64:: try_from ( end. checked_sub ( start) . unwrap ( ) ) . unwrap ( ) ) ;
157
+ CValue :: by_val_pair ( ptr, len, layout)
157
158
}
158
159
}
159
160
}
160
161
161
- fn trans_const_place < ' tcx > (
162
+ fn pointer_for_allocation < ' tcx > (
162
163
fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
163
- const_ : & ' tcx Const < ' tcx > ,
164
- ) -> CPlace < ' tcx > {
165
- // Adapted from https://github.com/rust-lang/rust/pull/53671/files#diff-e0b58bb6712edaa8595ad7237542c958L551
166
- let result = || -> InterpResult < ' tcx , & ' tcx Allocation > {
167
- let mut ecx = InterpCx :: new (
168
- fx. tcx . at ( DUMMY_SP ) ,
169
- ty:: ParamEnv :: reveal_all ( ) ,
170
- TransPlaceInterpreter ,
171
- ( ) ,
172
- ) ;
173
- ecx. push_stack_frame (
174
- fx. instance ,
175
- fx. mir ,
176
- None ,
177
- StackPopCleanup :: None { cleanup : false } ,
178
- )
179
- . unwrap ( ) ;
180
- let op = ecx. eval_operand (
181
- & Operand :: Constant ( Box :: new ( Constant {
182
- span : DUMMY_SP ,
183
- user_ty : None ,
184
- literal : const_,
185
- } ) ) ,
186
- None ,
187
- ) ?;
188
- let ptr = ecx. allocate ( op. layout , MemoryKind :: Stack ) ;
189
- ecx. copy_op ( op, ptr. into ( ) ) ?;
190
- let alloc = ecx
191
- . memory
192
- . get_raw ( ptr. to_ref ( ) . to_scalar ( ) ?. assert_ptr ( ) . alloc_id ) ?;
193
- Ok ( fx. tcx . intern_const_alloc ( alloc. clone ( ) ) )
194
- } ;
195
- let alloc = result ( ) . expect ( "unable to convert ConstKind to Allocation" ) ;
196
-
197
- //println!("const value: {:?} allocation: {:?}", value, alloc);
164
+ alloc : & ' tcx Allocation ,
165
+ ) -> crate :: pointer:: Pointer {
198
166
let alloc_id = fx. tcx . alloc_map . lock ( ) . create_memory_alloc ( alloc) ;
199
167
fx. constants_cx . todo . push ( TodoItem :: Alloc ( alloc_id) ) ;
200
168
let data_id = data_id_for_alloc_id ( fx. module , alloc_id, alloc. align ) ;
169
+
201
170
let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
202
171
#[ cfg( debug_assertions) ]
203
172
fx. add_comment ( local_data_id, format ! ( "{:?}" , alloc_id) ) ;
204
- cplace_for_dataid ( fx, fx. layout_of ( const_. ty ) , local_data_id)
173
+ let global_ptr = fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id) ;
174
+ crate :: pointer:: Pointer :: new ( global_ptr)
205
175
}
206
176
207
177
fn data_id_for_alloc_id < B : Backend > (
@@ -286,13 +256,14 @@ fn cplace_for_dataid<'tcx>(
286
256
}
287
257
288
258
fn define_all_allocs ( tcx : TyCtxt < ' _ > , module : & mut Module < impl Backend > , cx : & mut ConstantCx ) {
289
- let memory = Memory :: < TransPlaceInterpreter > :: new ( tcx. at ( DUMMY_SP ) , ( ) ) ;
290
-
291
259
while let Some ( todo_item) = cx. todo . pop ( ) {
292
260
let ( data_id, alloc) = match todo_item {
293
261
TodoItem :: Alloc ( alloc_id) => {
294
262
//println!("alloc_id {}", alloc_id);
295
- let alloc = memory. get_raw ( alloc_id) . unwrap ( ) ;
263
+ let alloc = match tcx. alloc_map . lock ( ) . get ( alloc_id) . unwrap ( ) {
264
+ GlobalAlloc :: Memory ( alloc) => alloc,
265
+ GlobalAlloc :: Function ( _) | GlobalAlloc :: Static ( _) => unreachable ! ( ) ,
266
+ } ;
296
267
let data_id = data_id_for_alloc_id ( module, alloc_id, alloc. align ) ;
297
268
( data_id, alloc)
298
269
}
@@ -388,105 +359,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut Module<impl Backend>, cx: &mu
388
359
assert ! ( cx. todo. is_empty( ) , "{:?}" , cx. todo) ;
389
360
}
390
361
391
- struct TransPlaceInterpreter ;
392
-
393
- impl < ' mir , ' tcx > Machine < ' mir , ' tcx > for TransPlaceInterpreter {
394
- type MemoryKind = !;
395
- type ExtraFnVal = !;
396
- type PointerTag = ( ) ;
397
- type AllocExtra = ( ) ;
398
- type MemoryExtra = ( ) ;
399
- type FrameExtra = ( ) ;
400
- type MemoryMap = FxHashMap < AllocId , ( MemoryKind < !> , Allocation < ( ) > ) > ;
401
-
402
- const CHECK_ALIGN : bool = true ;
403
- const GLOBAL_KIND : Option < !> = None ;
404
-
405
- fn enforce_validity ( _: & InterpCx < ' mir , ' tcx , Self > ) -> bool {
406
- false
407
- }
408
-
409
- fn before_terminator ( _: & mut InterpCx < ' mir , ' tcx , Self > ) -> InterpResult < ' tcx > {
410
- panic ! ( ) ;
411
- }
412
-
413
- fn find_mir_or_eval_fn (
414
- _: & mut InterpCx < ' mir , ' tcx , Self > ,
415
- _: Instance < ' tcx > ,
416
- _: & [ OpTy < ' tcx > ] ,
417
- _: Option < ( PlaceTy < ' tcx > , BasicBlock ) > ,
418
- _: Option < BasicBlock > ,
419
- ) -> InterpResult < ' tcx , Option < & ' mir Body < ' tcx > > > {
420
- panic ! ( ) ;
421
- }
422
-
423
- fn call_intrinsic (
424
- _: & mut InterpCx < ' mir , ' tcx , Self > ,
425
- _: Instance < ' tcx > ,
426
- _: & [ OpTy < ' tcx > ] ,
427
- _: Option < ( PlaceTy < ' tcx > , BasicBlock ) > ,
428
- _: Option < BasicBlock > ,
429
- ) -> InterpResult < ' tcx > {
430
- panic ! ( ) ;
431
- }
432
-
433
- fn binary_ptr_op (
434
- _: & InterpCx < ' mir , ' tcx , Self > ,
435
- _: mir:: BinOp ,
436
- _: ImmTy < ' tcx > ,
437
- _: ImmTy < ' tcx > ,
438
- ) -> InterpResult < ' tcx , ( Scalar , bool , Ty < ' tcx > ) > {
439
- panic ! ( ) ;
440
- }
441
-
442
- fn ptr_to_int ( _: & Memory < ' mir , ' tcx , Self > , _: Pointer < ( ) > ) -> InterpResult < ' tcx , u64 > {
443
- panic ! ( ) ;
444
- }
445
-
446
- fn box_alloc ( _: & mut InterpCx < ' mir , ' tcx , Self > , _: PlaceTy < ' tcx > ) -> InterpResult < ' tcx > {
447
- panic ! ( ) ;
448
- }
449
-
450
- fn init_allocation_extra < ' b > (
451
- _: & ( ) ,
452
- _: AllocId ,
453
- alloc : Cow < ' b , Allocation > ,
454
- _: Option < MemoryKind < !> > ,
455
- ) -> ( Cow < ' b , Allocation < ( ) , ( ) > > , ( ) ) {
456
- ( alloc, ( ) )
457
- }
458
-
459
- fn tag_global_base_pointer ( _: & ( ) , _: AllocId ) -> Self :: PointerTag {
460
- ( )
461
- }
462
-
463
- fn call_extra_fn (
464
- _: & mut InterpCx < ' mir , ' tcx , Self > ,
465
- _: !,
466
- _: & [ OpTy < ' tcx , ( ) > ] ,
467
- _: Option < ( PlaceTy < ' tcx , ( ) > , BasicBlock ) > ,
468
- _: Option < BasicBlock > ,
469
- ) -> InterpResult < ' tcx > {
470
- unreachable ! ( ) ;
471
- }
472
-
473
- fn stack_push ( _: & mut InterpCx < ' mir , ' tcx , Self > ) -> InterpResult < ' tcx > {
474
- Ok ( ( ) )
475
- }
476
-
477
- fn stack_pop ( _: & mut InterpCx < ' mir , ' tcx , Self > , _: ( ) , _: bool ) -> InterpResult < ' tcx , StackPopJump > {
478
- Ok ( StackPopJump :: Normal )
479
- }
480
-
481
- fn assert_panic (
482
- _: & mut InterpCx < ' mir , ' tcx , Self > ,
483
- _: & mir:: AssertKind < Operand < ' tcx > > ,
484
- _: Option < BasicBlock > ,
485
- ) -> InterpResult < ' tcx > {
486
- unreachable ! ( )
487
- }
488
- }
489
-
490
362
pub ( crate ) fn mir_operand_get_const_val < ' tcx > (
491
363
fx : & FunctionCx < ' _ , ' tcx , impl Backend > ,
492
364
operand : & Operand < ' tcx > ,
0 commit comments