@@ -210,6 +210,14 @@ impl<'ll> CodegenCx<'ll, '_> {
210
210
unsafe { llvm:: LLVMConstBitCast ( val, ty) }
211
211
}
212
212
213
+ pub ( crate ) fn const_pointercast ( & self , val : & ' ll Value , ty : & ' ll Type ) -> & ' ll Value {
214
+ unsafe { llvm:: LLVMConstPointerCast ( val, ty) }
215
+ }
216
+
217
+ /// Create a global variable.
218
+ ///
219
+ /// The returned global variable is a pointer in the default address space for globals.
220
+ /// Fails if a symbol with the given name already exists.
213
221
pub ( crate ) fn static_addr_of_mut (
214
222
& self ,
215
223
cv : & ' ll Value ,
@@ -233,6 +241,34 @@ impl<'ll> CodegenCx<'ll, '_> {
233
241
gv
234
242
}
235
243
244
+ /// Create a global constant.
245
+ ///
246
+ /// The returned global variable is a pointer in the default address space for globals.
247
+ pub ( crate ) fn static_addr_of_impl (
248
+ & self ,
249
+ cv : & ' ll Value ,
250
+ align : Align ,
251
+ kind : Option < & str > ,
252
+ ) -> & ' ll Value {
253
+ if let Some ( & gv) = self . const_globals . borrow ( ) . get ( & cv) {
254
+ unsafe {
255
+ // Upgrade the alignment in cases where the same constant is used with different
256
+ // alignment requirements
257
+ let llalign = align. bytes ( ) as u32 ;
258
+ if llalign > llvm:: LLVMGetAlignment ( gv) {
259
+ llvm:: LLVMSetAlignment ( gv, llalign) ;
260
+ }
261
+ }
262
+ return gv;
263
+ }
264
+ let gv = self . static_addr_of_mut ( cv, align, kind) ;
265
+ unsafe {
266
+ llvm:: LLVMSetGlobalConstant ( gv, True ) ;
267
+ }
268
+ self . const_globals . borrow_mut ( ) . insert ( cv, gv) ;
269
+ gv
270
+ }
271
+
236
272
#[ instrument( level = "debug" , skip( self ) ) ]
237
273
pub ( crate ) fn get_static ( & self , def_id : DefId ) -> & ' ll Value {
238
274
let instance = Instance :: mono ( self . tcx , def_id) ;
@@ -505,24 +541,15 @@ impl<'ll> CodegenCx<'ll, '_> {
505
541
}
506
542
507
543
impl < ' ll > StaticCodegenMethods for CodegenCx < ' ll , ' _ > {
544
+ /// Get a pointer to a global variable.
545
+ ///
546
+ /// The pointer will always be in the default address space. If global variables default to a
547
+ /// different address space, an addrspacecast is inserted.
508
548
fn static_addr_of ( & self , cv : & ' ll Value , align : Align , kind : Option < & str > ) -> & ' ll Value {
509
- if let Some ( & gv) = self . const_globals . borrow ( ) . get ( & cv) {
510
- unsafe {
511
- // Upgrade the alignment in cases where the same constant is used with different
512
- // alignment requirements
513
- let llalign = align. bytes ( ) as u32 ;
514
- if llalign > llvm:: LLVMGetAlignment ( gv) {
515
- llvm:: LLVMSetAlignment ( gv, llalign) ;
516
- }
517
- }
518
- return gv;
519
- }
520
- let gv = self . static_addr_of_mut ( cv, align, kind) ;
521
- unsafe {
522
- llvm:: LLVMSetGlobalConstant ( gv, True ) ;
523
- }
524
- self . const_globals . borrow_mut ( ) . insert ( cv, gv) ;
525
- gv
549
+ let gv = self . static_addr_of_impl ( cv, align, kind) ;
550
+ // static_addr_of_impl returns the bare global variable, which might not be in the default
551
+ // address space. Cast to the default address space if necessary.
552
+ self . const_pointercast ( gv, self . type_ptr ( ) )
526
553
}
527
554
528
555
fn codegen_static ( & self , def_id : DefId ) {
0 commit comments