@@ -9,6 +9,7 @@ use crate::type_::Type;
9
9
use crate :: type_of:: LayoutLlvmExt ;
10
10
use crate :: value:: Value ;
11
11
use rustc_codegen_ssa:: traits:: * ;
12
+ use rustc_hir:: def:: DefKind ;
12
13
use rustc_hir:: def_id:: DefId ;
13
14
use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
14
15
use rustc_middle:: mir:: interpret:: {
@@ -17,7 +18,7 @@ use rustc_middle::mir::interpret::{
17
18
} ;
18
19
use rustc_middle:: mir:: mono:: MonoItem ;
19
20
use rustc_middle:: ty:: layout:: LayoutOf ;
20
- use rustc_middle:: ty:: { self , Instance , Ty } ;
21
+ use rustc_middle:: ty:: { self , Instance } ;
21
22
use rustc_middle:: { bug, span_bug} ;
22
23
use rustc_session:: config:: Lto ;
23
24
use rustc_target:: abi:: {
@@ -114,7 +115,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
114
115
cx. const_struct ( & llvals, true )
115
116
}
116
117
117
- pub fn codegen_static_initializer < ' ll , ' tcx > (
118
+ fn codegen_static_initializer < ' ll , ' tcx > (
118
119
cx : & CodegenCx < ' ll , ' tcx > ,
119
120
def_id : DefId ,
120
121
) -> Result < ( & ' ll Value , ConstAllocation < ' tcx > ) , ErrorHandled > {
@@ -147,11 +148,10 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align:
147
148
fn check_and_apply_linkage < ' ll , ' tcx > (
148
149
cx : & CodegenCx < ' ll , ' tcx > ,
149
150
attrs : & CodegenFnAttrs ,
150
- ty : Ty < ' tcx > ,
151
+ llty : & ' ll Type ,
151
152
sym : & str ,
152
153
def_id : DefId ,
153
154
) -> & ' ll Value {
154
- let llty = cx. layout_of ( ty) . llvm_type ( cx) ;
155
155
if let Some ( linkage) = attrs. import_linkage {
156
156
debug ! ( "get_static: sym={} linkage={:?}" , sym, linkage) ;
157
157
@@ -226,9 +226,28 @@ impl<'ll> CodegenCx<'ll, '_> {
226
226
}
227
227
}
228
228
229
+ #[ instrument( level = "debug" , skip( self ) ) ]
229
230
pub ( crate ) fn get_static ( & self , def_id : DefId ) -> & ' ll Value {
230
231
let instance = Instance :: mono ( self . tcx , def_id) ;
231
- if let Some ( & g) = self . instances . borrow ( ) . get ( & instance) {
232
+ trace ! ( ?instance) ;
233
+
234
+ let DefKind :: Static { nested, .. } = self . tcx . def_kind ( def_id) else { bug ! ( ) } ;
235
+ // Nested statics do not have a type, so pick a random type and let `define_static` figure out
236
+ // the llvm type from the actual evaluated initializer.
237
+ let llty = if nested {
238
+ self . type_i8 ( )
239
+ } else {
240
+ let ty = instance. ty ( self . tcx , ty:: ParamEnv :: reveal_all ( ) ) ;
241
+ trace ! ( ?ty) ;
242
+ self . layout_of ( ty) . llvm_type ( self )
243
+ } ;
244
+ self . get_static_inner ( def_id, llty)
245
+ }
246
+
247
+ #[ instrument( level = "debug" , skip( self , llty) ) ]
248
+ pub ( crate ) fn get_static_inner ( & self , def_id : DefId , llty : & ' ll Type ) -> & ' ll Value {
249
+ if let Some ( & g) = self . statics . borrow ( ) . get ( & def_id) {
250
+ trace ! ( "used cached value" ) ;
232
251
return g;
233
252
}
234
253
@@ -240,14 +259,12 @@ impl<'ll> CodegenCx<'ll, '_> {
240
259
statics defined in the same CGU, but did not for `{def_id:?}`"
241
260
) ;
242
261
243
- let ty = instance. ty ( self . tcx , ty:: ParamEnv :: reveal_all ( ) ) ;
244
- let sym = self . tcx . symbol_name ( instance) . name ;
262
+ let sym = self . tcx . symbol_name ( Instance :: mono ( self . tcx , def_id) ) . name ;
245
263
let fn_attrs = self . tcx . codegen_fn_attrs ( def_id) ;
246
264
247
- debug ! ( "get_static: sym={} instance={:?} fn_attrs={:?}" , sym, instance , fn_attrs) ;
265
+ debug ! ( ? sym, ? fn_attrs) ;
248
266
249
267
let g = if def_id. is_local ( ) && !self . tcx . is_foreign_item ( def_id) {
250
- let llty = self . layout_of ( ty) . llvm_type ( self ) ;
251
268
if let Some ( g) = self . get_declared_value ( sym) {
252
269
if self . val_ty ( g) != self . type_ptr ( ) {
253
270
span_bug ! ( self . tcx. def_span( def_id) , "Conflicting types for static" ) ;
@@ -264,7 +281,7 @@ impl<'ll> CodegenCx<'ll, '_> {
264
281
265
282
g
266
283
} else {
267
- check_and_apply_linkage ( self , fn_attrs, ty , sym, def_id)
284
+ check_and_apply_linkage ( self , fn_attrs, llty , sym, def_id)
268
285
} ;
269
286
270
287
// Thread-local statics in some other crate need to *always* be linked
@@ -332,34 +349,15 @@ impl<'ll> CodegenCx<'ll, '_> {
332
349
}
333
350
}
334
351
335
- self . instances . borrow_mut ( ) . insert ( instance , g) ;
352
+ self . statics . borrow_mut ( ) . insert ( def_id , g) ;
336
353
g
337
354
}
338
- }
339
-
340
- impl < ' ll > StaticMethods for CodegenCx < ' ll , ' _ > {
341
- fn static_addr_of ( & self , cv : & ' ll Value , align : Align , kind : Option < & str > ) -> & ' ll Value {
342
- if let Some ( & gv) = self . const_globals . borrow ( ) . get ( & cv) {
343
- unsafe {
344
- // Upgrade the alignment in cases where the same constant is used with different
345
- // alignment requirements
346
- let llalign = align. bytes ( ) as u32 ;
347
- if llalign > llvm:: LLVMGetAlignment ( gv) {
348
- llvm:: LLVMSetAlignment ( gv, llalign) ;
349
- }
350
- }
351
- return gv;
352
- }
353
- let gv = self . static_addr_of_mut ( cv, align, kind) ;
354
- unsafe {
355
- llvm:: LLVMSetGlobalConstant ( gv, True ) ;
356
- }
357
- self . const_globals . borrow_mut ( ) . insert ( cv, gv) ;
358
- gv
359
- }
360
355
361
- fn codegen_static ( & self , def_id : DefId , is_mutable : bool ) {
356
+ fn codegen_static_item ( & self , def_id : DefId ) {
362
357
unsafe {
358
+ assert ! (
359
+ llvm:: LLVMGetInitializer ( self . statics. borrow( ) . get( & def_id) . unwrap( ) ) . is_none( )
360
+ ) ;
363
361
let attrs = self . tcx . codegen_fn_attrs ( def_id) ;
364
362
365
363
let Ok ( ( v, alloc) ) = codegen_static_initializer ( self , def_id) else {
@@ -368,13 +366,11 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
368
366
} ;
369
367
let alloc = alloc. inner ( ) ;
370
368
371
- let g = self . get_static ( def_id) ;
372
-
373
369
let val_llty = self . val_ty ( v) ;
374
370
375
- let instance = Instance :: mono ( self . tcx , def_id ) ;
376
- let ty = instance . ty ( self . tcx , ty :: ParamEnv :: reveal_all ( ) ) ;
377
- let llty = self . layout_of ( ty ) . llvm_type ( self ) ;
371
+ let g = self . get_static_inner ( def_id , val_llty ) ;
372
+ let llty = self . val_ty ( g ) ;
373
+
378
374
let g = if val_llty == llty {
379
375
g
380
376
} else {
@@ -409,7 +405,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
409
405
self . statics_to_rauw . borrow_mut ( ) . push ( ( g, new_g) ) ;
410
406
new_g
411
407
} ;
412
- set_global_alignment ( self , g, self . align_of ( ty ) ) ;
408
+ set_global_alignment ( self , g, alloc . align ) ;
413
409
llvm:: LLVMSetInitializer ( g, v) ;
414
410
415
411
if self . should_assume_dso_local ( g, true ) {
@@ -418,7 +414,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
418
414
419
415
// As an optimization, all shared statics which do not have interior
420
416
// mutability are placed into read-only memory.
421
- if !is_mutable && self . type_is_freeze ( ty ) {
417
+ if !self . tcx . is_mutable_static ( def_id ) && alloc . mutability . is_not ( ) {
422
418
llvm:: LLVMSetGlobalConstant ( g, llvm:: True ) ;
423
419
}
424
420
@@ -541,6 +537,32 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
541
537
}
542
538
}
543
539
}
540
+ }
541
+
542
+ impl < ' ll > StaticMethods for CodegenCx < ' ll , ' _ > {
543
+ fn static_addr_of ( & self , cv : & ' ll Value , align : Align , kind : Option < & str > ) -> & ' ll Value {
544
+ if let Some ( & gv) = self . const_globals . borrow ( ) . get ( & cv) {
545
+ unsafe {
546
+ // Upgrade the alignment in cases where the same constant is used with different
547
+ // alignment requirements
548
+ let llalign = align. bytes ( ) as u32 ;
549
+ if llalign > llvm:: LLVMGetAlignment ( gv) {
550
+ llvm:: LLVMSetAlignment ( gv, llalign) ;
551
+ }
552
+ }
553
+ return gv;
554
+ }
555
+ let gv = self . static_addr_of_mut ( cv, align, kind) ;
556
+ unsafe {
557
+ llvm:: LLVMSetGlobalConstant ( gv, True ) ;
558
+ }
559
+ self . const_globals . borrow_mut ( ) . insert ( cv, gv) ;
560
+ gv
561
+ }
562
+
563
+ fn codegen_static ( & self , def_id : DefId ) {
564
+ self . codegen_static_item ( def_id)
565
+ }
544
566
545
567
/// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr.
546
568
fn add_used_global ( & self , global : & ' ll Value ) {
0 commit comments