Skip to content

Commit

Permalink
Feature/global rvalue initialization petter tomner (rust-lang#111)
Browse files Browse the repository at this point in the history
* Use new initialization functions

* Fix for new reflection patch

* Fix for new TLS patch
  • Loading branch information
antoyo authored Dec 16, 2021
1 parent ddb015a commit 2989a25
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 54 deletions.
26 changes: 13 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 17 additions & 12 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
fn check_ptr_call<'b>(&mut self, _typ: &str, func_ptr: RValue<'gcc>, args: &'b [RValue<'gcc>]) -> Cow<'b, [RValue<'gcc>]> {
let mut all_args_match = true;
let mut param_types = vec![];
let gcc_func = func_ptr.get_type().is_function_ptr_type().expect("function ptr");
let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr");
for (index, arg) in args.iter().enumerate().take(gcc_func.get_param_count()) {
let param = gcc_func.get_param_type(index);
if param != arg.get_type() {
Expand Down Expand Up @@ -277,7 +277,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {

// gccjit requires to use the result of functions, even when it's not used.
// That's why we assign the result to a local or call add_eval().
let gcc_func = func_ptr.get_type().is_function_ptr_type().expect("function ptr");
let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr");
let mut return_type = gcc_func.get_return_type();
let current_block = self.current_block.borrow().expect("block");
let void_type = self.context.new_type::<()>();
Expand Down Expand Up @@ -810,7 +810,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
let atomic_load = self.context.get_builtin_function(&format!("__atomic_load_{}", size.bytes()));
let ordering = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc());

let volatile_const_void_ptr_type = self.context.new_type::<*mut ()>().make_const().make_volatile();
let volatile_const_void_ptr_type = self.context.new_type::<()>()
.make_const()
.make_volatile()
.make_pointer();
let ptr = self.context.new_cast(None, ptr, volatile_const_void_ptr_type);
self.context.new_call(None, atomic_load, &[ptr, ordering])
}
Expand Down Expand Up @@ -935,7 +938,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
// TODO(antoyo): handle alignment.
let atomic_store = self.context.get_builtin_function(&format!("__atomic_store_{}", size.bytes()));
let ordering = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc());
let volatile_const_void_ptr_type = self.context.new_type::<*mut ()>().make_const().make_volatile();
let volatile_const_void_ptr_type = self.context.new_type::<()>()
.make_volatile()
.make_pointer();
let ptr = self.context.new_cast(None, ptr, volatile_const_void_ptr_type);

// FIXME(antoyo): fix libgccjit to allow comparing an integer type with an aligned integer type because
Expand Down Expand Up @@ -975,12 +980,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
assert_eq!(idx as usize as u64, idx);
let value = ptr.dereference(None).to_rvalue();

if value_type.is_array().is_some() {
if value_type.dyncast_array().is_some() {
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
let element = self.context.new_array_access(None, value, index);
element.get_address(None)
}
else if let Some(vector_type) = value_type.is_vector() {
else if let Some(vector_type) = value_type.dyncast_vector() {
let array_type = vector_type.get_element_type().make_pointer();
let array = self.bitcast(ptr, array_type);
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
Expand All @@ -1003,7 +1008,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

fn sext(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
// TODO(antoyo): check that it indeed sign extend the value.
if dest_ty.is_vector().is_some() {
if dest_ty.dyncast_vector().is_some() {
// TODO(antoyo): nothing to do as it is only for LLVM?
return value;
}
Expand Down Expand Up @@ -1075,7 +1080,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
let right_type = rhs.get_type();
if left_type != right_type {
// NOTE: because libgccjit cannot compare function pointers.
if left_type.is_function_ptr_type().is_some() && right_type.is_function_ptr_type().is_some() {
if left_type.dyncast_function_ptr_type().is_some() && right_type.dyncast_function_ptr_type().is_some() {
lhs = self.context.new_cast(None, lhs, self.usize_type.make_pointer());
rhs = self.context.new_cast(None, rhs, self.usize_type.make_pointer());
}
Expand Down Expand Up @@ -1183,12 +1188,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
assert_eq!(idx as usize as u64, idx);
let value_type = aggregate_value.get_type();

if value_type.is_array().is_some() {
if value_type.dyncast_array().is_some() {
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
let element = self.context.new_array_access(None, aggregate_value, index);
element.get_address(None)
}
else if value_type.is_vector().is_some() {
else if value_type.dyncast_vector().is_some() {
panic!();
}
else if let Some(pointer_type) = value_type.get_pointee() {
Expand All @@ -1215,11 +1220,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
let value_type = aggregate_value.get_type();

let lvalue =
if value_type.is_array().is_some() {
if value_type.dyncast_array().is_some() {
let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
self.context.new_array_access(None, aggregate_value, index)
}
else if value_type.is_vector().is_some() {
else if value_type.dyncast_vector().is_some() {
panic!();
}
else if let Some(pointer_type) = value_type.get_pointee() {
Expand Down
14 changes: 3 additions & 11 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::convert::TryFrom;
use std::convert::TryInto;

use gccjit::LValue;
use gccjit::{Block, CType, RValue, Type, ToRValue};
Expand Down Expand Up @@ -44,7 +43,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
let string = self.context.new_string_literal(&*string);
let sym = self.generate_local_symbol_name("str");
let global = self.declare_private_global(&sym, self.val_ty(string));
global.global_set_initializer_value(string);
global.global_set_initializer_rvalue(string);
global
// TODO(antoyo): set linkage.
}
Expand Down Expand Up @@ -79,7 +78,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
bytes.iter()
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
.collect();
context.new_rvalue_from_array(None, typ, &elements)
context.new_array_constructor(None, typ, &elements)
}

pub fn type_is_pointer<'gcc>(typ: Type<'gcc>) -> bool {
Expand Down Expand Up @@ -120,13 +119,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
}

fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
let num64: Result<i64, _> = num.try_into();
if let Ok(num) = num64 {
// FIXME(antoyo): workaround for a bug where libgccjit is expecting a constant.
// The operations >> 64 and | low are making the normal case a non-constant.
return self.context.new_rvalue_from_long(typ, num as i64);
}

if num >> 64 != 0 {
// FIXME(antoyo): use a new function new_rvalue_from_unsigned_long()?
let low = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64);
Expand Down Expand Up @@ -193,7 +185,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
// TODO(antoyo): cache the type? It's anonymous, so probably not.
let typ = self.type_struct(&fields, packed);
let struct_type = typ.is_struct().expect("struct type");
self.context.new_rvalue_from_struct(None, struct_type, values)
self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
}

fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
Expand Down
8 changes: 4 additions & 4 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
if value.get_type() == self.bool_type.make_pointer() {
if let Some(pointee) = typ.get_pointee() {
if pointee.is_vector().is_some() {
if pointee.dyncast_vector().is_some() {
panic!()
}
}
Expand Down Expand Up @@ -81,7 +81,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
else {
value
};
global.global_set_initializer_value(value);
global.global_set_initializer_rvalue(value);

// As an optimization, all shared statics which do not have interior
// mutability are placed into read-only memory.
Expand Down Expand Up @@ -180,7 +180,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
};
// FIXME(antoyo): I think the name coming from generate_local_symbol_name() above cannot be used
// globally.
global.global_set_initializer_value(cv);
global.global_set_initializer_rvalue(cv);
// TODO(antoyo): set unnamed address.
global.get_address(None)
}
Expand Down Expand Up @@ -375,7 +375,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &Codeg
real_name.push_str(&sym);
let global2 = cx.define_global(&real_name, llty, is_tls, attrs.link_section);
// TODO(antoyo): set linkage.
global2.global_set_initializer_value(global1.get_address(None));
global2.global_set_initializer_rvalue(global1.get_address(None));
// TODO(antoyo): use global_set_initializer() when it will work.
global2
}
Expand Down
12 changes: 1 addition & 11 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
use std::cell::{Cell, RefCell};

use gccjit::{
Block,
Context,
CType,
Function,
FunctionType,
LValue,
RValue,
Struct,
Type,
};
use gccjit::{Block, CType, Context, Function, FunctionType, LValue, RValue, Struct, Type};
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::traits::{
BackendTypes,
Expand Down
6 changes: 3 additions & 3 deletions src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
if typ.is_integral() {
TypeKind::Integer
}
else if typ.is_vector().is_some() {
else if typ.dyncast_vector().is_some() {
TypeKind::Vector
}
else {
Expand All @@ -141,10 +141,10 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
}

fn element_type(&self, ty: Type<'gcc>) -> Type<'gcc> {
if let Some(typ) = ty.is_array() {
if let Some(typ) = ty.dyncast_array() {
typ
}
else if let Some(vector_type) = ty.is_vector() {
else if let Some(vector_type) = ty.dyncast_vector() {
vector_type.get_element_type()
}
else if let Some(typ) = ty.get_pointee() {
Expand Down

0 comments on commit 2989a25

Please sign in to comment.