Skip to content

Commit 64c561d

Browse files
authored
Fix global initialization (rust-lang#91)
* Make define_global() return a RValue directly * Return LValue in functions declaring a global variable * Remove useless cast * Fix bytes_in_context to use an array rvalue * Remove global_names which is unused * Make const_struct create a constant struct * Correctly initialize global in static_addr_of_mut * Fix global variable initialization * Remove workaround for ARGV
1 parent 4e7e822 commit 64c561d

12 files changed

+93
-283
lines changed

Diff for: Cargo.lock

+19-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/base.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
use std::env;
2-
use std::sync::Once;
32
use std::time::Instant;
43

54
use gccjit::{
65
Context,
76
FunctionType,
87
GlobalKind,
98
};
10-
use rustc_hir::def_id::LOCAL_CRATE;
119
use rustc_middle::dep_graph;
1210
use rustc_middle::middle::cstore::EncodedMetadata;
1311
use rustc_middle::middle::exported_symbols;
@@ -20,7 +18,7 @@ use rustc_codegen_ssa::traits::DebugInfoMethods;
2018
use rustc_session::config::DebugInfo;
2119
use rustc_span::Symbol;
2220

23-
use crate::{GccContext, create_function_calling_initializers};
21+
use crate::GccContext;
2422
use crate::builder::Builder;
2523
use crate::context::CodegenCx;
2624

@@ -97,15 +95,6 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (Modul
9795
{
9896
let cx = CodegenCx::new(&context, cgu, tcx);
9997

100-
static START: Once = Once::new();
101-
START.call_once(|| {
102-
let initializer_name = format!("__gccGlobalCrateInit{}", tcx.crate_name(LOCAL_CRATE));
103-
let func = context.new_function(None, FunctionType::Exported, context.new_type::<()>(), &[], initializer_name, false);
104-
let block = func.new_block("initial");
105-
create_function_calling_initializers(tcx, &context, block);
106-
block.end_with_void_return(None);
107-
});
108-
10998
let mono_items = cgu.items_in_deterministic_order(tcx);
11099
for &(mono_item, (linkage, visibility)) in &mono_items {
111100
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
@@ -124,8 +113,6 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (Modul
124113
if cx.sess().opts.debuginfo != DebugInfo::None {
125114
cx.debuginfo_finalize();
126115
}
127-
128-
cx.global_init_block.end_with_void_return(None);
129116
}
130117

131118
ModuleCodegen {

Diff for: src/builder.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
505505
// FIXME(antoyo): rustc_codegen_ssa::mir::intrinsic uses different types for a and b but they
506506
// should be the same.
507507
let typ = a.get_type().to_signed(self);
508-
let a = self.context.new_cast(None, a, typ);
509508
let b = self.context.new_cast(None, b, typ);
510509
a / b
511510
}
@@ -1413,7 +1412,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
14131412
impl<'a, 'gcc, 'tcx> StaticBuilderMethods for Builder<'a, 'gcc, 'tcx> {
14141413
fn get_static(&mut self, def_id: DefId) -> RValue<'gcc> {
14151414
// Forward to the `get_static` method of `CodegenCx`
1416-
self.cx().get_static(def_id)
1415+
self.cx().get_static(def_id).get_address(None)
14171416
}
14181417
}
14191418

Diff for: src/callee.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
2020
assert!(!instance.substs.needs_infer());
2121
assert!(!instance.substs.has_escaping_bound_vars());
2222

23-
if let Some(&func) = cx.instances.borrow().get(&instance) {
23+
if let Some(&func) = cx.function_instances.borrow().get(&instance) {
2424
return func;
2525
}
2626

@@ -72,7 +72,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
7272
func
7373
};
7474

75-
cx.instances.borrow_mut().insert(instance, func);
75+
cx.function_instances.borrow_mut().insert(instance, func);
7676

7777
func
7878
}

Diff for: src/common.rs

+20-26
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::convert::TryFrom;
22
use std::convert::TryInto;
33

4+
use gccjit::LValue;
45
use gccjit::{Block, CType, RValue, Type, ToRValue};
56
use rustc_codegen_ssa::mir::place::PlaceRef;
67
use rustc_codegen_ssa::traits::{
@@ -10,7 +11,6 @@ use rustc_codegen_ssa::traits::{
1011
MiscMethods,
1112
StaticMethods,
1213
};
13-
use rustc_middle::bug;
1414
use rustc_middle::mir::Mutability;
1515
use rustc_middle::ty::ScalarInt;
1616
use rustc_middle::ty::layout::{TyAndLayout, LayoutOf};
@@ -27,28 +27,27 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
2727
bytes_in_context(self, bytes)
2828
}
2929

30-
fn const_cstr(&self, symbol: Symbol, _null_terminated: bool) -> RValue<'gcc> {
30+
fn const_cstr(&self, symbol: Symbol, _null_terminated: bool) -> LValue<'gcc> {
3131
// TODO(antoyo): handle null_terminated.
3232
if let Some(&value) = self.const_cstr_cache.borrow().get(&symbol) {
33-
return value.to_rvalue();
33+
return value;
3434
}
3535

3636
let global = self.global_string(&*symbol.as_str());
3737

38-
self.const_cstr_cache.borrow_mut().insert(symbol, global.dereference(None));
38+
self.const_cstr_cache.borrow_mut().insert(symbol, global);
3939
global
4040
}
4141

42-
fn global_string(&self, string: &str) -> RValue<'gcc> {
42+
fn global_string(&self, string: &str) -> LValue<'gcc> {
4343
// TODO(antoyo): handle non-null-terminated strings.
4444
let string = self.context.new_string_literal(&*string);
4545
let sym = self.generate_local_symbol_name("str");
4646
// NOTE: TLS is always off for a string litteral.
4747
// NOTE: string litterals do not have a link section.
48-
let global = self.define_global(&sym, self.val_ty(string), false, None)
49-
.unwrap_or_else(|| bug!("symbol `{}` is already defined", sym));
50-
self.global_init_block.add_assignment(None, global.dereference(None), string);
51-
global.to_rvalue()
48+
let global = self.declare_private_global(&sym, self.val_ty(string));
49+
global.global_set_initializer_value(string); // TODO: only set if not imported?
50+
global
5251
// TODO(antoyo): set linkage.
5352
}
5453

@@ -76,10 +75,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
7675

7776
pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> {
7877
let context = &cx.context;
79-
let typ = context.new_array_type(None, context.new_type::<u8>(), bytes.len() as i32);
80-
let global = cx.declare_unnamed_global(typ);
81-
global.global_set_initializer(bytes);
82-
global.to_rvalue()
78+
let byte_type = context.new_type::<u8>();
79+
let typ = context.new_array_type(None, byte_type, bytes.len() as i32);
80+
let elements: Vec<_> =
81+
bytes.iter()
82+
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
83+
.collect();
84+
context.new_rvalue_from_array(None, typ, &elements)
8385
}
8486

8587
pub fn type_is_pointer<'gcc>(typ: Type<'gcc>) -> bool {
@@ -180,7 +182,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
180182

181183
fn const_str(&self, s: Symbol) -> (RValue<'gcc>, RValue<'gcc>) {
182184
let len = s.as_str().len();
183-
let cs = self.const_ptrcast(self.const_cstr(s, false),
185+
let cs = self.const_ptrcast(self.const_cstr(s, false).get_address(None),
184186
self.type_ptr_to(self.layout_of(self.tcx.types.str_).gcc_type(self, true)),
185187
);
186188
(cs, self.const_usize(len as u64))
@@ -191,16 +193,9 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
191193
.map(|value| value.get_type())
192194
.collect();
193195
// TODO(antoyo): cache the type? It's anonymous, so probably not.
194-
let name = fields.iter().map(|typ| format!("{:?}", typ)).collect::<Vec<_>>().join("_");
195196
let typ = self.type_struct(&fields, packed);
196-
let structure = self.global_init_func.new_local(None, typ, &name);
197197
let struct_type = typ.is_struct().expect("struct type");
198-
for (index, value) in values.iter().enumerate() {
199-
let field = struct_type.get_field(index as i32);
200-
let field_lvalue = structure.access_field(None, field);
201-
self.global_init_block.add_assignment(None, field_lvalue, *value);
202-
}
203-
self.lvalue_to_rvalue(structure)
198+
self.context.new_rvalue_from_struct(None, struct_type, values)
204199
}
205200

206201
fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
@@ -260,19 +255,18 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
260255
},
261256
GlobalAlloc::Static(def_id) => {
262257
assert!(self.tcx.is_static(def_id));
263-
self.get_static(def_id)
258+
self.get_static(def_id).get_address(None)
264259
},
265260
};
266261
let ptr_type = base_addr.get_type();
267262
let base_addr = self.const_bitcast(base_addr, self.usize_type);
268263
let offset = self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
269264
let ptr = self.const_bitcast(base_addr + offset, ptr_type);
270-
let value = ptr.dereference(None);
271265
if layout.value != Pointer {
272-
self.const_bitcast(value.to_rvalue(), ty)
266+
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
273267
}
274268
else {
275-
self.const_bitcast(value.get_address(None), ty)
269+
self.const_bitcast(ptr, ty)
276270
}
277271
}
278272
}

0 commit comments

Comments
 (0)