Skip to content

Commit 58b4901

Browse files
committed
Merge addr_of_const and addr_of_mut
1 parent a59fc1f commit 58b4901

6 files changed

Lines changed: 68 additions & 118 deletions

File tree

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use gccjit::{LValue, RValue, ToRValue, Type};
22
use rustc_abi as abi;
33
use rustc_abi::HasDataLayout;
4-
use rustc_codegen_ssa::traits::{
5-
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods as _,
6-
};
4+
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
75
use rustc_middle::mir::interpret::ConstAllocation;
86
use rustc_middle::ty::layout::LayoutOf;
97

@@ -246,13 +244,48 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
246244
self.context.new_cast(None, val, ty)
247245
}
248246

249-
fn static_addr_of_const(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
250-
self.static_addr_of(alloc, kind)
251-
}
252-
253-
fn static_addr_of_mut(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
247+
fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> RValue<'gcc> {
254248
let cv = const_alloc_to_gcc(self, alloc);
255-
self.static_addr_of_mut(cv, alloc.inner().align, kind)
249+
let align = alloc.inner().align;
250+
251+
if alloc.inner().mutability.is_not()
252+
&& let Some(variable) = self.const_globals.borrow().get(&cv)
253+
{
254+
if let Some(global_variable) = self.global_lvalues.borrow().get(variable) {
255+
let alignment = align.bits() as i32;
256+
if alignment > global_variable.get_alignment() {
257+
global_variable.set_alignment(alignment);
258+
}
259+
}
260+
return *variable;
261+
}
262+
let global_value = match kind {
263+
Some(kind) if !self.tcx.sess.fewer_names() => {
264+
let name = self.generate_local_symbol_name(kind);
265+
// FIXME(antoyo): check if it's okay that no link_section is set.
266+
267+
let typ = self.val_ty(cv).get_aligned(align.bytes());
268+
self.declare_private_global(&name[..], typ)
269+
}
270+
_ => {
271+
let typ = self.val_ty(cv).get_aligned(align.bytes());
272+
self.declare_unnamed_global(typ)
273+
}
274+
};
275+
global_value.global_set_initializer_rvalue(cv);
276+
// FIXME(antoyo): set unnamed address.
277+
let rvalue = global_value.get_address(None);
278+
self.global_lvalues.borrow_mut().insert(rvalue, global_value);
279+
if alloc.inner().mutability.is_not() {
280+
#[cfg(feature = "master")]
281+
self.global_lvalues
282+
.borrow()
283+
.get(&rvalue)
284+
.expect("`static_addr_of_mut` did not add the global to `self.global_lvalues`")
285+
.global_set_readonly();
286+
self.const_globals.borrow_mut().insert(cv, rvalue);
287+
}
288+
rvalue
256289
}
257290
}
258291

compiler/rustc_codegen_gcc/src/consts.rs

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,6 @@ fn set_global_alignment<'gcc, 'tcx>(
5656
}
5757

5858
impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
59-
fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> RValue<'gcc> {
60-
let cv = const_alloc_to_gcc(self, alloc);
61-
let align = alloc.inner().align;
62-
63-
if let Some(variable) = self.const_globals.borrow().get(&cv) {
64-
if let Some(global_variable) = self.global_lvalues.borrow().get(variable) {
65-
let alignment = align.bits() as i32;
66-
if alignment > global_variable.get_alignment() {
67-
global_variable.set_alignment(alignment);
68-
}
69-
}
70-
return *variable;
71-
}
72-
let global_value = self.static_addr_of_mut(cv, align, kind);
73-
#[cfg(feature = "master")]
74-
self.global_lvalues
75-
.borrow()
76-
.get(&global_value)
77-
.expect("`static_addr_of_mut` did not add the global to `self.global_lvalues`")
78-
.global_set_readonly();
79-
self.const_globals.borrow_mut().insert(cv, global_value);
80-
global_value
81-
}
82-
8359
fn codegen_static(&mut self, def_id: DefId) {
8460
let attrs = self.tcx.codegen_fn_attrs(def_id);
8561

@@ -196,32 +172,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
196172
function.add_attribute(FnAttribute::Used);
197173
}
198174

199-
pub fn static_addr_of_mut(
200-
&self,
201-
cv: RValue<'gcc>,
202-
align: Align,
203-
kind: Option<&str>,
204-
) -> RValue<'gcc> {
205-
let global = match kind {
206-
Some(kind) if !self.tcx.sess.fewer_names() => {
207-
let name = self.generate_local_symbol_name(kind);
208-
// FIXME(antoyo): check if it's okay that no link_section is set.
209-
210-
let typ = self.val_ty(cv).get_aligned(align.bytes());
211-
self.declare_private_global(&name[..], typ)
212-
}
213-
_ => {
214-
let typ = self.val_ty(cv).get_aligned(align.bytes());
215-
self.declare_unnamed_global(typ)
216-
}
217-
};
218-
global.global_set_initializer_rvalue(cv);
219-
// FIXME(antoyo): set unnamed address.
220-
let rvalue = global.get_address(None);
221-
self.global_lvalues.borrow_mut().insert(rvalue, global);
222-
rvalue
223-
}
224-
225175
pub fn get_static(&self, def_id: DefId) -> LValue<'gcc> {
226176
let instance = Instance::mono(self.tcx, def_id);
227177
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,9 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
289289
unsafe { llvm::LLVMConstPtrToInt(val, ty) }
290290
}
291291

292-
fn static_addr_of_const(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
292+
fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
293293
let cv = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
294-
self.static_addr_of_const(cv, alloc.inner().align, kind)
295-
}
296-
297-
fn static_addr_of_mut(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
298-
let cv = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
299-
self.static_addr_of_mut(cv, alloc.inner().align, kind)
294+
self.static_addr_of(cv, alloc.inner().align, kind, alloc.inner().mutability)
300295
}
301296
}
302297

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::ops::Range;
22

33
use rustc_abi::{Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange};
4+
use rustc_ast::Mutability;
45
use rustc_codegen_ssa::common;
56
use rustc_codegen_ssa::traits::*;
67
use rustc_hir::LangItem;
@@ -225,12 +226,26 @@ impl<'ll> CodegenCx<'ll, '_> {
225226
///
226227
/// The returned global variable is a pointer in the default address space for globals.
227228
/// Fails if a symbol with the given name already exists.
228-
pub(crate) fn static_addr_of_mut(
229+
pub(crate) fn static_addr_of(
229230
&self,
230231
cv: &'ll Value,
231232
align: Align,
232233
kind: Option<&str>,
234+
mutability: Mutability,
233235
) -> &'ll Value {
236+
if let Mutability::Not = mutability
237+
&& let Some(&gv) = self.const_globals.borrow().get(&cv)
238+
{
239+
unsafe {
240+
// Upgrade the alignment in cases where the same constant is used with different
241+
// alignment requirements
242+
let llalign = align.bytes() as u32;
243+
if llalign > llvm::LLVMGetAlignment(gv) {
244+
llvm::LLVMSetAlignment(gv, llalign);
245+
}
246+
}
247+
return gv;
248+
}
234249
let gv = match kind {
235250
Some(kind) if !self.tcx.sess.fewer_names() => {
236251
let name = self.generate_local_symbol_name(kind);
@@ -247,33 +262,11 @@ impl<'ll> CodegenCx<'ll, '_> {
247262
llvm::set_initializer(gv, cv);
248263
set_global_alignment(self, gv, align);
249264
llvm::set_unnamed_address(gv, llvm::UnnamedAddr::Global);
250-
gv
251-
}
265+
if let Mutability::Not = mutability {
266+
llvm::set_global_constant(gv, true);
252267

253-
/// Create a global constant.
254-
///
255-
/// The returned global variable is a pointer in the default address space for globals.
256-
pub(crate) fn static_addr_of_const(
257-
&self,
258-
cv: &'ll Value,
259-
align: Align,
260-
kind: Option<&str>,
261-
) -> &'ll Value {
262-
if let Some(&gv) = self.const_globals.borrow().get(&cv) {
263-
unsafe {
264-
// Upgrade the alignment in cases where the same constant is used with different
265-
// alignment requirements
266-
let llalign = align.bytes() as u32;
267-
if llalign > llvm::LLVMGetAlignment(gv) {
268-
llvm::LLVMSetAlignment(gv, llalign);
269-
}
270-
}
271-
return gv;
268+
self.const_globals.borrow_mut().insert(cv, gv);
272269
}
273-
let gv = self.static_addr_of_mut(cv, align, kind);
274-
llvm::set_global_constant(gv, true);
275-
276-
self.const_globals.borrow_mut().insert(cv, gv);
277270
gv
278271
}
279272

@@ -760,20 +753,6 @@ impl<'ll> CodegenCx<'ll, '_> {
760753
}
761754

762755
impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
763-
/// Get a pointer to a global variable.
764-
///
765-
/// The pointer will always be in the default address space. If global variables default to a
766-
/// different address space, an addrspacecast is inserted.
767-
fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> &'ll Value {
768-
// FIXME: should we cache `const_alloc_to_llvm` to avoid repeating this for the
769-
// same `ConstAllocation`?
770-
let cv = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
771-
let gv = self.static_addr_of_const(cv, alloc.inner().align, kind);
772-
// static_addr_of_const returns the bare global variable, which might not be in the default
773-
// address space. Cast to the default address space if necessary.
774-
self.const_pointercast(gv, self.type_ptr())
775-
}
776-
777756
fn codegen_static(&mut self, def_id: DefId) {
778757
self.codegen_static_item(def_id)
779758
}

compiler/rustc_codegen_ssa/src/traits/consts.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use rustc_abi::{self as abi, HasDataLayout, Primitive};
2-
use rustc_ast::Mutability;
32
use rustc_data_structures::stable_hash::{StableHash as _, StableHasher};
43
use rustc_hashes::Hash128;
54
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
@@ -54,13 +53,12 @@ pub trait ConstCodegenMethods<'tcx>:
5453
fn const_pointercast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
5554
fn const_int_to_ptr(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
5655
fn const_ptr_to_int(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
56+
5757
/// Create a global constant.
5858
///
5959
/// The returned global variable is a pointer in the default address space for globals.
60-
fn static_addr_of_const(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value;
61-
62-
/// Same as `static_addr_of_const`, but does not mark the static as immutable
63-
fn static_addr_of_mut(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value;
60+
/// Immutable allocations are deduplicated.
61+
fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value;
6462

6563
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Self::Type) -> Self::Value {
6664
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
@@ -91,10 +89,7 @@ pub trait ConstCodegenMethods<'tcx>:
9189
self.const_bitcast(val, ty)
9290
};
9391
} else {
94-
let value = match alloc.inner().mutability {
95-
Mutability::Mut => self.static_addr_of_mut(alloc, None),
96-
_ => self.static_addr_of_const(alloc, None),
97-
};
92+
let value = self.static_addr_of(alloc, None);
9893
self.set_value_name(value, || {
9994
let hash = self.tcx().with_stable_hashing_context(|mut hcx| {
10095
let mut hasher = StableHasher::new();
@@ -118,7 +113,7 @@ pub trait ConstCodegenMethods<'tcx>:
118113
}),
119114
)))
120115
.unwrap_memory();
121-
self.static_addr_of_const(alloc, None)
116+
self.static_addr_of(alloc, None)
122117
}
123118
GlobalAlloc::Static(def_id) => {
124119
assert!(self.tcx().is_static(def_id));

compiler/rustc_codegen_ssa/src/traits/statics.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use rustc_hir::def_id::DefId;
2-
use rustc_middle::mir::interpret::ConstAllocation;
32

43
use super::BackendTypes;
54

65
pub trait StaticCodegenMethods: BackendTypes {
7-
fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value;
86
/// Set a debuginfo name. The name closure is only invoked if a name actually needs to be
97
/// registered, so you can do expensive name calculations in it.
108
fn set_value_name(&self, val: Self::Value, gen_name: impl FnOnce() -> String);

0 commit comments

Comments
 (0)