@@ -9,6 +9,7 @@ use crate::type_::Type;
99use crate :: type_of:: LayoutLlvmExt ;
1010use crate :: value:: Value ;
1111use rustc_codegen_ssa:: traits:: * ;
12+ use rustc_hir:: def:: DefKind ;
1213use rustc_hir:: def_id:: DefId ;
1314use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
1415use rustc_middle:: mir:: interpret:: {
@@ -17,7 +18,7 @@ use rustc_middle::mir::interpret::{
1718} ;
1819use rustc_middle:: mir:: mono:: MonoItem ;
1920use rustc_middle:: ty:: layout:: LayoutOf ;
20- use rustc_middle:: ty:: { self , Instance , Ty } ;
21+ use rustc_middle:: ty:: { self , Instance } ;
2122use rustc_middle:: { bug, span_bug} ;
2223use rustc_session:: config:: Lto ;
2324use rustc_target:: abi:: {
@@ -114,7 +115,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
114115 cx. const_struct ( & llvals, true )
115116}
116117
117- pub fn codegen_static_initializer < ' ll , ' tcx > (
118+ fn codegen_static_initializer < ' ll , ' tcx > (
118119 cx : & CodegenCx < ' ll , ' tcx > ,
119120 def_id : DefId ,
120121) -> Result < ( & ' ll Value , ConstAllocation < ' tcx > ) , ErrorHandled > {
@@ -147,11 +148,10 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align:
147148fn check_and_apply_linkage < ' ll , ' tcx > (
148149 cx : & CodegenCx < ' ll , ' tcx > ,
149150 attrs : & CodegenFnAttrs ,
150- ty : Ty < ' tcx > ,
151+ llty : & ' ll Type ,
151152 sym : & str ,
152153 def_id : DefId ,
153154) -> & ' ll Value {
154- let llty = cx. layout_of ( ty) . llvm_type ( cx) ;
155155 if let Some ( linkage) = attrs. import_linkage {
156156 debug ! ( "get_static: sym={} linkage={:?}" , sym, linkage) ;
157157
@@ -226,9 +226,28 @@ impl<'ll> CodegenCx<'ll, '_> {
226226 }
227227 }
228228
229+ #[ instrument( level = "debug" , skip( self ) ) ]
229230 pub ( crate ) fn get_static ( & self , def_id : DefId ) -> & ' ll Value {
230231 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" ) ;
232251 return g;
233252 }
234253
@@ -240,14 +259,12 @@ impl<'ll> CodegenCx<'ll, '_> {
240259 statics defined in the same CGU, but did not for `{def_id:?}`"
241260 ) ;
242261
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 ;
245263 let fn_attrs = self . tcx . codegen_fn_attrs ( def_id) ;
246264
247- debug ! ( "get_static: sym={} instance={:?} fn_attrs={:?}" , sym, instance , fn_attrs) ;
265+ debug ! ( ? sym, ? fn_attrs) ;
248266
249267 let g = if def_id. is_local ( ) && !self . tcx . is_foreign_item ( def_id) {
250- let llty = self . layout_of ( ty) . llvm_type ( self ) ;
251268 if let Some ( g) = self . get_declared_value ( sym) {
252269 if self . val_ty ( g) != self . type_ptr ( ) {
253270 span_bug ! ( self . tcx. def_span( def_id) , "Conflicting types for static" ) ;
@@ -264,7 +281,7 @@ impl<'ll> CodegenCx<'ll, '_> {
264281
265282 g
266283 } 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)
268285 } ;
269286
270287 // Thread-local statics in some other crate need to *always* be linked
@@ -332,34 +349,15 @@ impl<'ll> CodegenCx<'ll, '_> {
332349 }
333350 }
334351
335- self . instances . borrow_mut ( ) . insert ( instance , g) ;
352+ self . statics . borrow_mut ( ) . insert ( def_id , g) ;
336353 g
337354 }
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- }
360355
361- fn codegen_static ( & self , def_id : DefId , is_mutable : bool ) {
356+ fn codegen_static_item ( & self , def_id : DefId ) {
362357 unsafe {
358+ assert ! (
359+ llvm:: LLVMGetInitializer ( self . statics. borrow( ) . get( & def_id) . unwrap( ) ) . is_none( )
360+ ) ;
363361 let attrs = self . tcx . codegen_fn_attrs ( def_id) ;
364362
365363 let Ok ( ( v, alloc) ) = codegen_static_initializer ( self , def_id) else {
@@ -368,13 +366,11 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
368366 } ;
369367 let alloc = alloc. inner ( ) ;
370368
371- let g = self . get_static ( def_id) ;
372-
373369 let val_llty = self . val_ty ( v) ;
374370
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+
378374 let g = if val_llty == llty {
379375 g
380376 } else {
@@ -409,7 +405,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
409405 self . statics_to_rauw . borrow_mut ( ) . push ( ( g, new_g) ) ;
410406 new_g
411407 } ;
412- set_global_alignment ( self , g, self . align_of ( ty ) ) ;
408+ set_global_alignment ( self , g, alloc . align ) ;
413409 llvm:: LLVMSetInitializer ( g, v) ;
414410
415411 if self . should_assume_dso_local ( g, true ) {
@@ -418,7 +414,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
418414
419415 // As an optimization, all shared statics which do not have interior
420416 // 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 ( ) {
422418 llvm:: LLVMSetGlobalConstant ( g, llvm:: True ) ;
423419 }
424420
@@ -541,6 +537,32 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
541537 }
542538 }
543539 }
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+ }
544566
545567 /// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr.
546568 fn add_used_global ( & self , global : & ' ll Value ) {
0 commit comments