Skip to content

Commit ff1c5db

Browse files
Improve code to generate static items
1 parent cbd94ff commit ff1c5db

File tree

2 files changed

+36
-27
lines changed

2 files changed

+36
-27
lines changed

src/consts.rs

+34-19
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
#[cfg(feature = "master")]
22
use gccjit::{FnAttribute, VarAttribute, Visibility};
33
use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue};
4-
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, DerivedTypeMethods, StaticMethods};
4+
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, StaticMethods};
5+
use rustc_hir::def::DefKind;
56
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
67
use rustc_middle::mir::interpret::{
78
self, read_target_uint, ConstAllocation, ErrorHandled, Scalar as InterpScalar,
89
};
910
use rustc_middle::mir::mono::MonoItem;
10-
use rustc_middle::span_bug;
1111
use rustc_middle::ty::layout::LayoutOf;
12-
use rustc_middle::ty::{self, Instance, Ty};
12+
use rustc_middle::ty::{self, Instance};
13+
use rustc_middle::{bug, span_bug};
1314
use rustc_span::def_id::DefId;
1415
use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange};
1516

@@ -66,33 +67,31 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
6667
fn codegen_static(&self, def_id: DefId) {
6768
let attrs = self.tcx.codegen_fn_attrs(def_id);
6869

69-
let value = match codegen_static_initializer(self, def_id) {
70-
Ok((value, _)) => value,
70+
let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else {
7171
// Error has already been reported
72-
Err(_) => return,
72+
return;
7373
};
7474

75-
let global = self.get_static(def_id);
75+
let alloc = alloc.inner();
7676

7777
// boolean SSA values are i1, but they have to be stored in i8 slots,
7878
// otherwise some LLVM optimization passes don't work as expected
7979
let val_llty = self.val_ty(value);
8080
if val_llty == self.type_i1() {
8181
unimplemented!();
8282
};
83+
let global = self.get_static_inner(def_id, val_llty);
8384

84-
let instance = Instance::mono(self.tcx, def_id);
85-
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
86-
let gcc_type = self.layout_of(ty).gcc_type(self);
85+
let gcc_type = self.val_ty(global.to_rvalue());
8786

88-
set_global_alignment(self, global, self.align_of(ty));
87+
set_global_alignment(self, global, alloc.align);
8988

9089
let value = self.bitcast_if_needed(value, gcc_type);
9190
global.global_set_initializer_rvalue(value);
9291

9392
// As an optimization, all shared statics which do not have interior
9493
// mutability are placed into read-only memory.
95-
if !self.tcx.static_mutability(def_id).unwrap().is_mut() && self.type_is_freeze(ty) {
94+
if !alloc.mutability.is_not() {
9695
#[cfg(feature = "master")]
9796
global.global_set_readonly();
9897
}
@@ -205,7 +204,21 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
205204

206205
pub fn get_static(&self, def_id: DefId) -> LValue<'gcc> {
207206
let instance = Instance::mono(self.tcx, def_id);
208-
let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
207+
208+
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
209+
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
210+
// the llvm type from the actual evaluated initializer.
211+
let llty = if nested {
212+
self.type_i8()
213+
} else {
214+
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
215+
self.layout_of(ty).gcc_type(self)
216+
};
217+
self.get_static_inner(def_id, llty)
218+
}
219+
220+
pub fn get_static_inner(&self, def_id: DefId, llty: gccjit::Type<'gcc>) -> LValue<'gcc> {
221+
let instance = Instance::mono(self.tcx, def_id);
209222
if let Some(&global) = self.instances.borrow().get(&instance) {
210223
return global;
211224
}
@@ -219,18 +232,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
219232
def_id
220233
);
221234

222-
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
223235
let sym = self.tcx.symbol_name(instance).name;
236+
let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
224237

238+
let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
225239
let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
226-
let llty = self.layout_of(ty).gcc_type(self);
227240
if let Some(global) = self.get_declared_value(sym) {
228241
if self.val_ty(global) != self.type_ptr_to(llty) {
229242
span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
230243
}
231244
}
232245

233-
let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
234246
let global =
235247
self.declare_global(sym, llty, GlobalKind::Exported, is_tls, fn_attrs.link_section);
236248

@@ -241,7 +253,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
241253

242254
global
243255
} else {
244-
check_and_apply_linkage(self, fn_attrs, ty, sym)
256+
let global = check_and_apply_linkage(self, fn_attrs, llty, sym);
257+
if is_tls {
258+
global.set_tls_model(self.tls_model);
259+
}
260+
global
245261
};
246262

247263
if !def_id.is_local() {
@@ -355,11 +371,10 @@ fn codegen_static_initializer<'gcc, 'tcx>(
355371
fn check_and_apply_linkage<'gcc, 'tcx>(
356372
cx: &CodegenCx<'gcc, 'tcx>,
357373
attrs: &CodegenFnAttrs,
358-
ty: Ty<'tcx>,
374+
gcc_type: gccjit::Type<'gcc>,
359375
sym: &str,
360376
) -> LValue<'gcc> {
361377
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
362-
let gcc_type = cx.layout_of(ty).gcc_type(cx);
363378
if let Some(linkage) = attrs.import_linkage {
364379
// Declare a symbol `foo` with the desired linkage.
365380
let global1 =

src/type_of.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
88
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
99
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
1010
use rustc_target::abi::{
11-
self, Abi, Align, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface,
12-
Variants, F128, F16, F32, F64,
11+
self, Abi, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, Variants,
12+
F128, F16, F32, F64,
1313
};
1414

1515
use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
@@ -53,12 +53,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
5353
}
5454
}
5555

56-
impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
57-
pub fn align_of(&self, ty: Ty<'tcx>) -> Align {
58-
self.layout_of(ty).align.abi
59-
}
60-
}
61-
6256
fn uncached_gcc_type<'gcc, 'tcx>(
6357
cx: &CodegenCx<'gcc, 'tcx>,
6458
layout: TyAndLayout<'tcx>,

0 commit comments

Comments
 (0)