summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/context.rs')
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs112
1 files changed, 83 insertions, 29 deletions
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 6c1dce969f0..5e5b9e7e9b1 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -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,