Merge commit '39683d8eb7
' into sync_cg_gcc-2022-03-26
This commit is contained in:
commit
bbff48e094
35 changed files with 1705 additions and 558 deletions
|
@ -1,6 +1,6 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use gccjit::{Block, CType, Context, Function, FunctionType, LValue, RValue, Struct, Type};
|
||||
use gccjit::{Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, RValue, Struct, Type};
|
||||
use rustc_codegen_ssa::base::wants_msvc_seh;
|
||||
use rustc_codegen_ssa::traits::{
|
||||
BackendTypes,
|
||||
|
@ -18,7 +18,6 @@ use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDat
|
|||
use rustc_target::spec::{HasTargetSpec, Target, TlsModel};
|
||||
|
||||
use crate::callee::get_fn;
|
||||
use crate::declare::mangle_name;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FuncSig<'gcc> {
|
||||
|
@ -31,8 +30,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
pub codegen_unit: &'tcx CodegenUnit<'tcx>,
|
||||
pub context: &'gcc Context<'gcc>,
|
||||
|
||||
// TODO(antoyo): First set it to a dummy block to avoid using Option?
|
||||
pub current_block: RefCell<Option<Block<'gcc>>>,
|
||||
// TODO(bjorn3): Can this field be removed?
|
||||
pub current_func: RefCell<Option<Function<'gcc>>>,
|
||||
pub normal_function_addresses: RefCell<FxHashSet<RValue<'gcc>>>,
|
||||
|
||||
|
@ -62,6 +60,8 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
pub ulonglong_type: Type<'gcc>,
|
||||
pub sizet_type: Type<'gcc>,
|
||||
|
||||
pub supports_128bit_integers: bool,
|
||||
|
||||
pub float_type: Type<'gcc>,
|
||||
pub double_type: Type<'gcc>,
|
||||
|
||||
|
@ -81,9 +81,19 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
/// Cache generated vtables
|
||||
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
|
||||
|
||||
// TODO(antoyo): improve the SSA API to not require those.
|
||||
// Mapping from function pointer type to indexes of on stack parameters.
|
||||
pub on_stack_params: RefCell<FxHashMap<FunctionPtrType<'gcc>, FxHashSet<usize>>>,
|
||||
// Mapping from function to indexes of on stack parameters.
|
||||
pub on_stack_function_params: RefCell<FxHashMap<Function<'gcc>, FxHashSet<usize>>>,
|
||||
|
||||
/// Cache of emitted const globals (value -> global)
|
||||
pub const_globals: RefCell<FxHashMap<RValue<'gcc>, RValue<'gcc>>>,
|
||||
|
||||
/// Map from the address of a global variable (rvalue) to the global variable itself (lvalue).
|
||||
/// TODO(antoyo): remove when the rustc API is fixed.
|
||||
pub global_lvalues: RefCell<FxHashMap<RValue<'gcc>, LValue<'gcc>>>,
|
||||
|
||||
/// Cache of constant strings,
|
||||
pub const_str_cache: RefCell<FxHashMap<Symbol, LValue<'gcc>>>,
|
||||
|
||||
|
@ -92,7 +102,6 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
|
||||
/// A counter that is used for generating local symbol names
|
||||
local_gen_sym_counter: Cell<usize>,
|
||||
pub global_gen_sym_counter: Cell<usize>,
|
||||
|
||||
eh_personality: Cell<Option<RValue<'gcc>>>,
|
||||
|
||||
|
@ -107,22 +116,29 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
pub fn new(context: &'gcc Context<'gcc>, codegen_unit: &'tcx CodegenUnit<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||
pub fn new(context: &'gcc Context<'gcc>, codegen_unit: &'tcx CodegenUnit<'tcx>, tcx: TyCtxt<'tcx>, supports_128bit_integers: bool) -> Self {
|
||||
let check_overflow = tcx.sess.overflow_checks();
|
||||
// TODO(antoyo): fix this mess. libgccjit seems to return random type when using new_int_type().
|
||||
let isize_type = context.new_c_type(CType::LongLong);
|
||||
let usize_type = context.new_c_type(CType::ULongLong);
|
||||
let bool_type = context.new_type::<bool>();
|
||||
let i8_type = context.new_type::<i8>();
|
||||
let i16_type = context.new_type::<i16>();
|
||||
let i32_type = context.new_type::<i32>();
|
||||
let i64_type = context.new_c_type(CType::LongLong);
|
||||
let i128_type = context.new_c_type(CType::Int128t).get_aligned(8); // TODO(antoyo): should the alignment be hard-coded?
|
||||
let u8_type = context.new_type::<u8>();
|
||||
let u16_type = context.new_type::<u16>();
|
||||
let u32_type = context.new_type::<u32>();
|
||||
let u64_type = context.new_c_type(CType::ULongLong);
|
||||
let u128_type = context.new_c_type(CType::UInt128t).get_aligned(8); // TODO(antoyo): should the alignment be hard-coded?
|
||||
|
||||
let i8_type = context.new_c_type(CType::Int8t);
|
||||
let i16_type = context.new_c_type(CType::Int16t);
|
||||
let i32_type = context.new_c_type(CType::Int32t);
|
||||
let i64_type = context.new_c_type(CType::Int64t);
|
||||
let u8_type = context.new_c_type(CType::UInt8t);
|
||||
let u16_type = context.new_c_type(CType::UInt16t);
|
||||
let u32_type = context.new_c_type(CType::UInt32t);
|
||||
let u64_type = context.new_c_type(CType::UInt64t);
|
||||
|
||||
let (i128_type, u128_type) =
|
||||
if supports_128bit_integers {
|
||||
let i128_type = context.new_c_type(CType::Int128t).get_aligned(8); // TODO(antoyo): should the alignment be hard-coded?;
|
||||
let u128_type = context.new_c_type(CType::UInt128t).get_aligned(8); // TODO(antoyo): should the alignment be hard-coded?;
|
||||
(i128_type, u128_type)
|
||||
}
|
||||
else {
|
||||
let i128_type = context.new_array_type(None, i64_type, 2);
|
||||
let u128_type = context.new_array_type(None, u64_type, 2);
|
||||
(i128_type, u128_type)
|
||||
};
|
||||
|
||||
let tls_model = to_gcc_tls_mode(tcx.sess.tls_model());
|
||||
|
||||
|
@ -136,8 +152,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
let ulonglong_type = context.new_c_type(CType::ULongLong);
|
||||
let sizet_type = context.new_c_type(CType::SizeT);
|
||||
|
||||
assert_eq!(isize_type, i64_type);
|
||||
assert_eq!(usize_type, u64_type);
|
||||
let isize_type = context.new_c_type(CType::LongLong);
|
||||
let usize_type = context.new_c_type(CType::ULongLong);
|
||||
let bool_type = context.new_type::<bool>();
|
||||
|
||||
// TODO(antoyo): only have those assertions on x86_64.
|
||||
assert_eq!(isize_type.get_size(), i64_type.get_size());
|
||||
assert_eq!(usize_type.get_size(), u64_type.get_size());
|
||||
|
||||
let mut functions = FxHashMap::default();
|
||||
let builtins = [
|
||||
|
@ -160,7 +181,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
check_overflow,
|
||||
codegen_unit,
|
||||
context,
|
||||
current_block: RefCell::new(None),
|
||||
current_func: RefCell::new(None),
|
||||
normal_function_addresses: Default::default(),
|
||||
functions: RefCell::new(functions),
|
||||
|
@ -187,14 +207,19 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
ulonglong_type,
|
||||
sizet_type,
|
||||
|
||||
supports_128bit_integers,
|
||||
|
||||
float_type,
|
||||
double_type,
|
||||
|
||||
linkage: Cell::new(FunctionType::Internal),
|
||||
instances: Default::default(),
|
||||
function_instances: Default::default(),
|
||||
on_stack_params: Default::default(),
|
||||
on_stack_function_params: Default::default(),
|
||||
vtables: Default::default(),
|
||||
const_globals: Default::default(),
|
||||
global_lvalues: Default::default(),
|
||||
const_str_cache: Default::default(),
|
||||
globals: Default::default(),
|
||||
scalar_types: Default::default(),
|
||||
|
@ -203,7 +228,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
struct_types: Default::default(),
|
||||
types_with_fields_to_set: Default::default(),
|
||||
local_gen_sym_counter: Cell::new(0),
|
||||
global_gen_sym_counter: Cell::new(0),
|
||||
eh_personality: Cell::new(None),
|
||||
pointee_infos: Default::default(),
|
||||
structs_as_pointer: Default::default(),
|
||||
|
@ -217,6 +241,41 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
function
|
||||
}
|
||||
|
||||
pub fn is_native_int_type(&self, typ: Type<'gcc>) -> bool {
|
||||
let types = [
|
||||
self.u8_type,
|
||||
self.u16_type,
|
||||
self.u32_type,
|
||||
self.u64_type,
|
||||
self.i8_type,
|
||||
self.i16_type,
|
||||
self.i32_type,
|
||||
self.i64_type,
|
||||
];
|
||||
|
||||
for native_type in types {
|
||||
if native_type.is_compatible_with(typ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
self.supports_128bit_integers &&
|
||||
(self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ))
|
||||
}
|
||||
|
||||
pub fn is_non_native_int_type(&self, typ: Type<'gcc>) -> bool {
|
||||
!self.supports_128bit_integers &&
|
||||
(self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ))
|
||||
}
|
||||
|
||||
pub fn is_native_int_type_or_bool(&self, typ: Type<'gcc>) -> bool {
|
||||
self.is_native_int_type(typ) || typ == self.bool_type
|
||||
}
|
||||
|
||||
pub fn is_int_type_or_bool(&self, typ: Type<'gcc>) -> bool {
|
||||
self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ == self.bool_type
|
||||
}
|
||||
|
||||
pub fn sess(&self) -> &Session {
|
||||
&self.tcx.sess
|
||||
}
|
||||
|
@ -450,11 +509,6 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unit_name<'tcx>(codegen_unit: &CodegenUnit<'tcx>) -> String {
|
||||
let name = &codegen_unit.name().to_string();
|
||||
mangle_name(&name.replace('-', "_"))
|
||||
}
|
||||
|
||||
fn to_gcc_tls_mode(tls_model: TlsModel) -> gccjit::TlsModel {
|
||||
match tls_model {
|
||||
TlsModel::GeneralDynamic => gccjit::TlsModel::GlobalDynamic,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue