@@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{
77use rustc_middle:: mir:: Mutability ;
88use rustc_middle:: mir:: interpret:: { GlobalAlloc , PointerArithmetic , Scalar } ;
99use rustc_middle:: ty:: layout:: LayoutOf ;
10+ use rustc_middle:: ty:: { Instance , SymbolName } ;
1011
1112use crate :: consts:: const_alloc_to_gcc;
1213use crate :: context:: { CodegenCx , new_array_type} ;
@@ -46,6 +47,68 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
4647 // SIMD builtins require a constant value.
4748 self . bitcast_if_needed ( value, typ)
4849 }
50+
51+ pub ( crate ) fn alloc_to_backend (
52+ & self ,
53+ global_alloc : GlobalAlloc < ' tcx > ,
54+ need_symbol_name : bool ,
55+ ) -> Result < ( RValue < ' gcc > , Option < SymbolName < ' tcx > > ) , u64 > {
56+ let alloc = match global_alloc {
57+ GlobalAlloc :: Function { instance, .. } => {
58+ return Ok ( (
59+ self . get_fn_addr ( instance) ,
60+ need_symbol_name. then ( || self . tcx . symbol_name ( instance) ) ,
61+ ) ) ;
62+ }
63+ GlobalAlloc :: Static ( def_id) => {
64+ assert ! ( self . tcx. is_static( def_id) ) ;
65+ return Ok ( (
66+ self . get_static ( def_id) . get_address ( None ) ,
67+ need_symbol_name
68+ . then ( || self . tcx . symbol_name ( Instance :: mono ( self . tcx , def_id) ) ) ,
69+ ) ) ;
70+ }
71+ GlobalAlloc :: TypeId { .. } => {
72+ // Drop the provenance, the offset contains the bytes of the hash, so
73+ // just return 0 as base address.
74+ return Err ( 0 ) ;
75+ }
76+
77+ GlobalAlloc :: Memory ( alloc) => {
78+ if alloc. inner ( ) . len ( ) == 0 {
79+ // For ZSTs directly codegen an aligned pointer.
80+ // This avoids generating a zero-sized constant value and actually needing a
81+ // real address at runtime.
82+ return Err ( alloc. inner ( ) . align . bytes ( ) ) ;
83+ }
84+
85+ alloc
86+ }
87+
88+ GlobalAlloc :: VTable ( ty, dyn_ty) => {
89+ self . tcx
90+ . global_alloc ( self . tcx . vtable_allocation ( (
91+ ty,
92+ dyn_ty. principal ( ) . map ( |principal| {
93+ self . tcx . instantiate_bound_regions_with_erased ( principal)
94+ } ) ,
95+ ) ) )
96+ . unwrap_memory ( )
97+ }
98+ } ;
99+
100+ let value = match alloc. inner ( ) . mutability {
101+ Mutability :: Mut => {
102+ self . static_addr_of_mut ( const_alloc_to_gcc ( self , alloc) , alloc. inner ( ) . align , None )
103+ }
104+ _ => self . static_addr_of ( alloc, None ) ,
105+ } ;
106+ if !self . sess ( ) . fewer_names ( ) {
107+ // FIXME(antoyo): set value name.
108+ }
109+
110+ Ok ( ( value, None ) )
111+ }
49112}
50113
51114pub fn bytes_in_context < ' gcc , ' tcx > ( cx : & CodegenCx < ' gcc , ' tcx > , bytes : & [ u8 ] ) -> RValue < ' gcc > {
@@ -250,57 +313,17 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
250313 Scalar :: Ptr ( ptr, _size) => {
251314 let ( prov, offset) = ptr. prov_and_relative_offset ( ) ;
252315 let alloc_id = prov. alloc_id ( ) ;
253- let base_addr = match self . tcx . global_alloc ( alloc_id) {
254- GlobalAlloc :: Memory ( alloc) => {
255- // For ZSTs directly codegen an aligned pointer.
256- // This avoids generating a zero-sized constant value and actually needing a
257- // real address at runtime.
258- if alloc. inner ( ) . len ( ) == 0 {
259- let val = alloc. inner ( ) . align . bytes ( ) . wrapping_add ( offset. bytes ( ) ) ;
260- let val = self . const_usize ( self . tcx . truncate_to_target_usize ( val) ) ;
261- return if matches ! ( layout. primitive( ) , Pointer ( _) ) {
262- self . context . new_cast ( None , val, ty)
263- } else {
264- self . const_bitcast ( val, ty)
265- } ;
266- }
267-
268- let value = match alloc. inner ( ) . mutability {
269- Mutability :: Mut => self . static_addr_of_mut (
270- const_alloc_to_gcc ( self , alloc) ,
271- alloc. inner ( ) . align ,
272- None ,
273- ) ,
274- _ => self . static_addr_of ( alloc, None ) ,
316+ let base_addr = match self . alloc_to_backend ( self . tcx . global_alloc ( alloc_id) , false )
317+ {
318+ Ok ( ( base_addr, _) ) => base_addr,
319+ Err ( base_addr) => {
320+ let val = base_addr. wrapping_add ( offset. bytes ( ) ) ;
321+ let val = self . const_usize ( self . tcx . truncate_to_target_usize ( val) ) ;
322+ return if matches ! ( layout. primitive( ) , Pointer ( _) ) {
323+ self . context . new_cast ( None , val, ty)
324+ } else {
325+ self . const_bitcast ( val, ty)
275326 } ;
276- if !self . sess ( ) . fewer_names ( ) {
277- // FIXME(antoyo): set value name.
278- }
279- value
280- }
281- GlobalAlloc :: Function { instance, .. } => self . get_fn_addr ( instance) ,
282- GlobalAlloc :: VTable ( ty, dyn_ty) => {
283- let alloc = self
284- . tcx
285- . global_alloc ( self . tcx . vtable_allocation ( (
286- ty,
287- dyn_ty. principal ( ) . map ( |principal| {
288- self . tcx . instantiate_bound_regions_with_erased ( principal)
289- } ) ,
290- ) ) )
291- . unwrap_memory ( ) ;
292- self . static_addr_of ( alloc, None )
293- }
294- GlobalAlloc :: TypeId { .. } => {
295- let val = self . const_usize ( offset. bytes ( ) ) ;
296- // This is still a variable of pointer type, even though we only use the provenance
297- // of that pointer in CTFE and Miri. But to make LLVM's type system happy,
298- // we need an int-to-ptr cast here (it doesn't matter at all which provenance that picks).
299- return self . context . new_cast ( None , val, ty) ;
300- }
301- GlobalAlloc :: Static ( def_id) => {
302- assert ! ( self . tcx. is_static( def_id) ) ;
303- self . get_static ( def_id) . get_address ( None )
304327 }
305328 } ;
306329 let ptr_type = base_addr. get_type ( ) ;
0 commit comments