@@ -9,6 +9,7 @@ use rustc_mir::interpret::{
9
9
StackPopInfo ,
10
10
} ;
11
11
12
+ use cranelift:: codegen:: ir:: GlobalValue ;
12
13
use cranelift_module:: * ;
13
14
14
15
use crate :: prelude:: * ;
@@ -94,41 +95,65 @@ pub fn trans_const_value<'tcx>(
94
95
) -> CValue < ' tcx > {
95
96
let ty = fx. monomorphize ( & const_. ty ) ;
96
97
let layout = fx. layout_of ( ty) ;
97
- match ty. kind {
98
- ty:: Bool | ty:: Uint ( _) => {
99
- let bits = const_. val . try_to_bits ( layout. size ) . unwrap ( ) ;
100
- CValue :: const_val ( fx, ty, bits)
101
- }
102
- ty:: Int ( _) => {
103
- let bits = const_. val . try_to_bits ( layout. size ) . unwrap ( ) ;
104
- CValue :: const_val (
105
- fx,
106
- ty,
107
- rustc:: mir:: interpret:: sign_extend ( bits, layout. size ) ,
108
- )
109
- }
110
- ty:: Float ( fty) => {
111
- let bits = const_. val . try_to_bits ( layout. size ) . unwrap ( ) ;
112
- let val = match fty {
113
- FloatTy :: F32 => fx
114
- . bcx
115
- . ins ( )
116
- . f32const ( Ieee32 :: with_bits ( u32:: try_from ( bits) . unwrap ( ) ) ) ,
117
- FloatTy :: F64 => fx
118
- . bcx
119
- . ins ( )
120
- . f64const ( Ieee64 :: with_bits ( u64:: try_from ( bits) . unwrap ( ) ) ) ,
121
- } ;
122
- CValue :: by_val ( val, layout)
123
- }
124
- ty:: FnDef ( _def_id, _substs) => CValue :: by_ref (
98
+
99
+ if layout. is_zst ( ) {
100
+ return CValue :: by_ref (
125
101
fx. bcx
126
102
. ins ( )
127
- . iconst ( fx. pointer_type , fx . pointer_type . bytes ( ) as i64 ) ,
103
+ . iconst ( fx. pointer_type , i64 :: try_from ( layout . align . pref . bytes ( ) ) . unwrap ( ) ) ,
128
104
layout,
129
- ) ,
130
- _ => trans_const_place ( fx, const_) . to_cvalue ( fx) ,
105
+ ) ;
131
106
}
107
+
108
+ if let Some ( _) = fx. clif_type ( layout. ty ) {
109
+ let val = match const_. val {
110
+ ConstKind :: Value ( val) => val,
111
+ _ => bug ! ( "encountered bad ConstKind in codegen" ) ,
112
+ } ;
113
+ match val {
114
+ ConstValue :: Scalar ( x) => {
115
+ match x {
116
+ Scalar :: Raw { data, size } => {
117
+ assert_eq ! ( u64 :: from( size) , layout. size. bytes( ) ) ;
118
+ return CValue :: const_val ( fx, layout. ty , data) ;
119
+ }
120
+ Scalar :: Ptr ( ptr) => {
121
+ let alloc_kind = fx. tcx . alloc_map . lock ( ) . get ( ptr. alloc_id ) ;
122
+ let base_addr = match alloc_kind {
123
+ Some ( GlobalAlloc :: Memory ( alloc) ) => {
124
+ fx. constants_cx . todo . insert ( TodoItem :: Alloc ( ptr. alloc_id ) ) ;
125
+ let data_id = data_id_for_alloc_id ( fx. module , ptr. alloc_id , alloc. align ) ;
126
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
127
+ #[ cfg( debug_assertions) ]
128
+ fx. add_entity_comment ( local_data_id, format ! ( "{:?}" , ptr. alloc_id) ) ;
129
+ fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
130
+ }
131
+ Some ( GlobalAlloc :: Function ( instance) ) => {
132
+ let func_id = crate :: abi:: import_function ( fx. tcx , fx. module , instance) ;
133
+ let local_func_id = fx. module . declare_func_in_func ( func_id, & mut fx. bcx . func ) ;
134
+ fx. bcx . ins ( ) . func_addr ( fx. pointer_type , local_func_id)
135
+ }
136
+ Some ( GlobalAlloc :: Static ( def_id) ) => {
137
+ assert ! ( fx. tcx. is_static( def_id) ) ;
138
+ let linkage = crate :: linkage:: get_static_ref_linkage ( fx. tcx , def_id) ;
139
+ let data_id = data_id_for_static ( fx. tcx , fx. module , def_id, linkage) ;
140
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
141
+ #[ cfg( debug_assertions) ]
142
+ fx. add_entity_comment ( local_data_id, format ! ( "{:?}" , def_id) ) ;
143
+ fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
144
+ }
145
+ None => bug ! ( "missing allocation {:?}" , ptr. alloc_id) ,
146
+ } ;
147
+ let val = fx. bcx . ins ( ) . iadd_imm ( base_addr, i64:: try_from ( ptr. offset . bytes ( ) ) . unwrap ( ) ) ;
148
+ return CValue :: by_val ( val, layout) ;
149
+ }
150
+ }
151
+ }
152
+ _ => { }
153
+ }
154
+ }
155
+
156
+ trans_const_place ( fx, const_) . to_cvalue ( fx)
132
157
}
133
158
134
159
fn trans_const_place < ' tcx > (
@@ -172,7 +197,10 @@ fn trans_const_place<'tcx>(
172
197
let alloc_id = fx. tcx . alloc_map . lock ( ) . create_memory_alloc ( alloc) ;
173
198
fx. constants_cx . todo . insert ( TodoItem :: Alloc ( alloc_id) ) ;
174
199
let data_id = data_id_for_alloc_id ( fx. module , alloc_id, alloc. align ) ;
175
- cplace_for_dataid ( fx, const_. ty , data_id)
200
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
201
+ #[ cfg( debug_assertions) ]
202
+ fx. add_entity_comment ( local_data_id, format ! ( "{:?}" , alloc_id) ) ;
203
+ cplace_for_dataid ( fx, const_. ty , local_data_id)
176
204
}
177
205
178
206
fn data_id_for_alloc_id < B : Backend > (
@@ -185,6 +213,7 @@ fn data_id_for_alloc_id<B: Backend>(
185
213
& format ! ( "__alloc_{}" , alloc_id. 0 ) ,
186
214
Linkage :: Local ,
187
215
false ,
216
+ false ,
188
217
Some ( align. bytes ( ) as u8 ) ,
189
218
)
190
219
. unwrap ( )
@@ -211,11 +240,14 @@ fn data_id_for_static(
211
240
. pref
212
241
. bytes ( ) ;
213
242
243
+ let attrs = tcx. codegen_fn_attrs ( def_id) ;
244
+
214
245
let data_id = module
215
246
. declare_data (
216
247
& * symbol_name,
217
248
linkage,
218
249
is_mutable,
250
+ attrs. flags . contains ( rustc:: hir:: CodegenFnAttrFlags :: THREAD_LOCAL ) ,
219
251
Some ( align. try_into ( ) . unwrap ( ) ) ,
220
252
)
221
253
. unwrap ( ) ;
@@ -249,9 +281,8 @@ fn data_id_for_static(
249
281
fn cplace_for_dataid < ' tcx > (
250
282
fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
251
283
ty : Ty < ' tcx > ,
252
- data_id : DataId ,
284
+ local_data_id : GlobalValue ,
253
285
) -> CPlace < ' tcx > {
254
- let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
255
286
let global_ptr = fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id) ;
256
287
let layout = fx. layout_of ( fx. monomorphize ( & ty) ) ;
257
288
assert ! ( !layout. is_unsized( ) , "unsized statics aren't supported" ) ;
0 commit comments