Skip to content

Commit 706d967

Browse files
committed
Unify handling of GlobalAlloc inside backend
With the previous commit, now we can see there are some code duplication for the handling of `GlobalAlloc` inside backends. Do some clean up to unify them.
1 parent 7ab9247 commit 706d967

4 files changed

Lines changed: 181 additions & 188 deletions

File tree

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
145145
// Clobbers collected from `out("explicit register") _` and `inout("explicit_reg") var => _`
146146
let mut clobbers = vec![];
147147

148+
// Symbols name that needs to be inserted to asm const ptr template string.
149+
let mut const_syms = vec![];
150+
148151
// We're trying to preallocate space for the template
149152
let mut constants_len = 0;
150153

@@ -405,17 +408,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
405408
let (prov, offset) = ptr.prov_and_relative_offset();
406409
assert_eq!(offset.bytes(), 0);
407410
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
408-
let val = match global_alloc {
409-
GlobalAlloc::Function { instance } => {
410-
get_fn(self.cx, instance).get_address(None)
411-
}
412-
GlobalAlloc::Static(def_id) => {
413-
self.cx.get_static(def_id).get_address(None)
414-
}
415-
GlobalAlloc::Memory(_)
416-
| GlobalAlloc::VTable(..)
417-
| GlobalAlloc::TypeId { .. } => unreachable!(),
418-
};
411+
let (val, sym) = self.cx.alloc_to_backend(global_alloc, true).unwrap();
412+
const_syms.push(sym.unwrap());
419413
inputs.push(AsmInOperand { constraint: "X".into(), rust_idx, val });
420414
}
421415
},
@@ -514,27 +508,13 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
514508
}
515509

516510
Scalar::Ptr(ptr, _) => {
517-
let (prov, offset) = ptr.prov_and_relative_offset();
511+
let (_, offset) = ptr.prov_and_relative_offset();
518512
assert_eq!(offset.bytes(), 0);
519-
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
520-
let symbol_name = match global_alloc {
521-
GlobalAlloc::Function { instance } => {
522-
// FIXME(@Amanieu): Additional mangling is needed on
523-
// some targets to add a leading underscore (Mach-O)
524-
// or byte count suffixes (x86 Windows).
525-
self.tcx.symbol_name(instance)
526-
}
527-
GlobalAlloc::Static(def_id) => {
528-
// FIXME(@Amanieu): Additional mangling is needed on
529-
// some targets to add a leading underscore (Mach-O).
530-
let instance = Instance::mono(self.tcx, def_id);
531-
self.tcx.symbol_name(instance)
532-
}
533-
GlobalAlloc::Memory(_)
534-
| GlobalAlloc::VTable(..)
535-
| GlobalAlloc::TypeId { .. } => unreachable!(),
536-
};
537-
template_str.push_str(symbol_name.name);
513+
let sym = const_syms.remove(0);
514+
// FIXME(@Amanieu): Additional mangling is needed on
515+
// some targets to add a leading underscore (Mach-O)
516+
// or byte count suffixes (x86 Windows).
517+
template_str.push_str(sym.name);
538518
}
539519
}
540520
}
@@ -984,16 +964,14 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
984964
// or byte count suffixes (x86 Windows).
985965
self.tcx.symbol_name(instance)
986966
}
987-
GlobalAlloc::Static(def_id) => {
967+
_ => {
968+
let (_, syms) =
969+
self.alloc_to_backend(global_alloc, true).unwrap();
988970
// FIXME(antoyo): set the global variable as used.
989971
// FIXME(@Amanieu): Additional mangling is needed on
990972
// some targets to add a leading underscore (Mach-O).
991-
let instance = Instance::mono(self.tcx, def_id);
992-
self.tcx.symbol_name(instance)
973+
syms.unwrap()
993974
}
994-
GlobalAlloc::Memory(_)
995-
| GlobalAlloc::VTable(..)
996-
| GlobalAlloc::TypeId { .. } => unreachable!(),
997975
};
998976
template_str.push_str(symbol_name.name);
999977
}

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 73 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{
77
use rustc_middle::mir::Mutability;
88
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
99
use rustc_middle::ty::layout::LayoutOf;
10+
use rustc_middle::ty::{Instance, SymbolName};
1011

1112
use crate::consts::const_alloc_to_gcc;
1213
use 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

51114
pub 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();

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
55
use rustc_codegen_ssa::mir::operand::OperandValue;
66
use rustc_codegen_ssa::traits::*;
77
use rustc_data_structures::fx::FxHashMap;
8-
use rustc_middle::mir::interpret::{GlobalAlloc, Scalar as ConstScalar};
8+
use rustc_middle::mir::interpret::Scalar as ConstScalar;
99
use rustc_middle::ty::Instance;
1010
use rustc_middle::ty::layout::TyAndLayout;
1111
use rustc_middle::{bug, span_bug};
@@ -164,21 +164,10 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
164164
let (prov, offset) = ptr.prov_and_relative_offset();
165165
assert_eq!(offset.bytes(), 0);
166166
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
167-
match global_alloc {
168-
GlobalAlloc::Function { instance } => {
169-
inputs.push(self.cx.get_fn(instance));
170-
op_idx.insert(idx, constraints.len());
171-
constraints.push("s".to_string());
172-
}
173-
GlobalAlloc::Static(def_id) => {
174-
inputs.push(self.cx.get_static(def_id));
175-
op_idx.insert(idx, constraints.len());
176-
constraints.push("s".to_string());
177-
}
178-
GlobalAlloc::Memory(_)
179-
| GlobalAlloc::VTable(..)
180-
| GlobalAlloc::TypeId { .. } => unreachable!(),
181-
}
167+
let value = self.cx.alloc_to_backend(global_alloc, false).unwrap();
168+
inputs.push(value);
169+
op_idx.insert(idx, constraints.len());
170+
constraints.push("s".to_string());
182171
}
183172
},
184173
InlineAsmOperandRef::SymThreadLocalStatic { def_id } => {
@@ -236,21 +225,12 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
236225
template_str.push_str(&string);
237226
}
238227
ConstScalar::Ptr(ptr, _) => {
239-
let (prov, offset) = ptr.prov_and_relative_offset();
228+
let (_, offset) = ptr.prov_and_relative_offset();
240229
assert_eq!(offset.bytes(), 0);
241-
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
242-
match global_alloc {
243-
GlobalAlloc::Function { .. } | GlobalAlloc::Static(_) => {
244-
// Only emit the raw symbol name
245-
template_str.push_str(&format!(
246-
"${{{}:c}}",
247-
op_idx[&operand_idx]
248-
));
249-
}
250-
GlobalAlloc::Memory(_)
251-
| GlobalAlloc::VTable(..)
252-
| GlobalAlloc::TypeId { .. } => unreachable!(),
253-
}
230+
231+
// Only emit the raw symbol name
232+
template_str
233+
.push_str(&format!("${{{}:c}}", op_idx[&operand_idx]));
254234
}
255235
}
256236
}
@@ -468,18 +448,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
468448
let (prov, offset) = ptr.prov_and_relative_offset();
469449
assert_eq!(offset.bytes(), 0);
470450
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
471-
let llval = match global_alloc {
472-
GlobalAlloc::Function { instance } => self.get_fn(instance),
473-
GlobalAlloc::Static(def_id) => self
474-
.renamed_statics
475-
.borrow()
476-
.get(&def_id)
477-
.copied()
478-
.unwrap_or_else(|| self.get_static(def_id)),
479-
GlobalAlloc::Memory(_)
480-
| GlobalAlloc::VTable(..)
481-
| GlobalAlloc::TypeId { .. } => unreachable!(),
482-
};
451+
let llval = self.alloc_to_backend(global_alloc, true).unwrap();
483452

484453
self.add_compiler_used_global(llval);
485454
let symbol = llvm::build_string(|s| unsafe {

0 commit comments

Comments
 (0)