Skip to content

Commit

Permalink
Added default impl for DerivedTypeMethods + empty impl for Cranelift …
Browse files Browse the repository at this point in the history
…BaseTypeMethods
  • Loading branch information
denismerigoux authored and eddyb committed Nov 16, 2018
1 parent 54dd3a4 commit b25b804
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 151 deletions.
125 changes: 5 additions & 120 deletions src/librustc_codegen_llvm/type_.rs
Expand Up @@ -18,16 +18,12 @@ use context::CodegenCx;
use rustc_codegen_ssa::interfaces::*;
use value::Value;


use syntax::ast;
use rustc::ty::layout::{self, Align, Size, HasTyCtxt};
use rustc::util::nodemap::FxHashMap;
use rustc::ty::{self, Ty};
use rustc::ty::Ty;
use rustc::ty::layout::TyLayout;
use rustc_target::abi::call::{CastTarget, FnType, Reg};
use rustc_data_structures::small_c_str::SmallCStr;
use common;
use rustc_codegen_ssa;
use rustc_codegen_ssa::common::TypeKind;
use type_of::LayoutLlvmExt;
use abi::{LlvmType, FnTypeExt};
Expand Down Expand Up @@ -108,6 +104,10 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}

fn type_isize(&self) -> &'ll Type {
self.isize_ty
}

fn type_f32(&self) -> &'ll Type {
unsafe {
llvm::LLVMFloatTypeInContext(self.llcx)
Expand Down Expand Up @@ -274,121 +274,6 @@ impl Type {
}
}

impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_bool(&self) -> &'ll Type {
self.type_i8()
}

fn type_i8p(&self) -> &'ll Type {
self.type_ptr_to(self.type_i8())
}

fn type_isize(&self) -> &'ll Type {
self.isize_ty
}

fn type_int(&self) -> &'ll Type {
match &self.sess().target.target.target_c_int_width[..] {
"16" => self.type_i16(),
"32" => self.type_i32(),
"64" => self.type_i64(),
width => bug!("Unsupported target_c_int_width: {}", width),
}
}

fn type_int_from_ty(
&self,
t: ast::IntTy
) -> &'ll Type {
match t {
ast::IntTy::Isize => self.isize_ty,
ast::IntTy::I8 => self.type_i8(),
ast::IntTy::I16 => self.type_i16(),
ast::IntTy::I32 => self.type_i32(),
ast::IntTy::I64 => self.type_i64(),
ast::IntTy::I128 => self.type_i128(),
}
}

fn type_uint_from_ty(
&self,
t: ast::UintTy
) -> &'ll Type {
match t {
ast::UintTy::Usize => self.isize_ty,
ast::UintTy::U8 => self.type_i8(),
ast::UintTy::U16 => self.type_i16(),
ast::UintTy::U32 => self.type_i32(),
ast::UintTy::U64 => self.type_i64(),
ast::UintTy::U128 => self.type_i128(),
}
}

fn type_float_from_ty(
&self,
t: ast::FloatTy
) -> &'ll Type {
match t {
ast::FloatTy::F32 => self.type_f32(),
ast::FloatTy::F64 => self.type_f64(),
}
}

fn type_from_integer(&self, i: layout::Integer) -> &'ll Type {
use rustc::ty::layout::Integer::*;
match i {
I8 => self.type_i8(),
I16 => self.type_i16(),
I32 => self.type_i32(),
I64 => self.type_i64(),
I128 => self.type_i128(),
}
}

fn type_pointee_for_abi_align(&self, align: Align) -> &'ll Type {
// FIXME(eddyb) We could find a better approximation if ity.align < align.
let ity = layout::Integer::approximate_abi_align(self, align);
self.type_from_integer(ity)
}

fn type_padding_filler(
&self,
size: Size,
align: Align
) -> &'ll Type {
let unit = layout::Integer::approximate_abi_align(self, align);
let size = size.bytes();
let unit_size = unit.size().bytes();
assert_eq!(size % unit_size, 0);
self.type_array(self.type_from_integer(unit), size / unit_size)
}

fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
rustc_codegen_ssa::common::type_needs_drop(self.tcx(), ty)
}

fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
rustc_codegen_ssa::common::type_is_sized(self.tcx(), ty)
}

fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
rustc_codegen_ssa::common::type_is_freeze(self.tcx(), ty)
}

fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
return false;
}

let tail = self.tcx().struct_tail(ty);
match tail.sty {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
}
}
}

impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn backend_type(&self, layout: TyLayout<'tcx>) -> &'ll Type {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/interfaces/backend.rs
Expand Up @@ -35,7 +35,7 @@ pub trait BackendTypes {
}

pub trait Backend<'tcx>:
BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
{
}

Expand Down
135 changes: 105 additions & 30 deletions src/librustc_codegen_ssa/interfaces/type_.rs
Expand Up @@ -8,13 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::misc::MiscMethods;
use super::Backend;
use super::HasCodegen;
use common::TypeKind;
use common::{self, TypeKind};
use mir::place::PlaceRef;
use rustc::ty::layout::TyLayout;
use rustc::ty::layout::{self, Align, Size};
use rustc::ty::Ty;
use rustc::ty::layout::{self, Align, Size, TyLayout};
use rustc::ty::{self, Ty};
use rustc::util::nodemap::FxHashMap;
use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg};
use std::cell::RefCell;
Expand All @@ -32,6 +32,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {

// Creates an integer type with the given number of bits, e.g. i24
fn type_ix(&self, num_bits: u64) -> Self::Type;
fn type_isize(&self) -> Self::Type;

fn type_f32(&self) -> Self::Type;
fn type_f64(&self) -> Self::Type;
Expand Down Expand Up @@ -61,30 +62,109 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>>;
}

pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
fn type_bool(&self) -> Self::Type;
fn type_i8p(&self) -> Self::Type;
fn type_isize(&self) -> Self::Type;
fn type_int(&self) -> Self::Type;
fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type;
fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type;
fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type;
fn type_from_integer(&self, i: layout::Integer) -> Self::Type;

/// Return a LLVM type that has at most the required alignment,
/// as a conservative approximation for unknown pointee types.
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
fn type_bool(&self) -> Self::Type {
self.type_i8()
}

fn type_i8p(&self) -> Self::Type {
self.type_ptr_to(self.type_i8())
}

fn type_int(&self) -> Self::Type {
match &self.sess().target.target.target_c_int_width[..] {
"16" => self.type_i16(),
"32" => self.type_i32(),
"64" => self.type_i64(),
width => bug!("Unsupported target_c_int_width: {}", width),
}
}

fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type {
match t {
ast::IntTy::Isize => self.type_isize(),
ast::IntTy::I8 => self.type_i8(),
ast::IntTy::I16 => self.type_i16(),
ast::IntTy::I32 => self.type_i32(),
ast::IntTy::I64 => self.type_i64(),
ast::IntTy::I128 => self.type_i128(),
}
}

fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type {
match t {
ast::UintTy::Usize => self.type_isize(),
ast::UintTy::U8 => self.type_i8(),
ast::UintTy::U16 => self.type_i16(),
ast::UintTy::U32 => self.type_i32(),
ast::UintTy::U64 => self.type_i64(),
ast::UintTy::U128 => self.type_i128(),
}
}

fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type {
match t {
ast::FloatTy::F32 => self.type_f32(),
ast::FloatTy::F64 => self.type_f64(),
}
}

fn type_from_integer(&self, i: layout::Integer) -> Self::Type {
use rustc::ty::layout::Integer::*;
match i {
I8 => self.type_i8(),
I16 => self.type_i16(),
I32 => self.type_i32(),
I64 => self.type_i64(),
I128 => self.type_i128(),
}
}

fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type {
// FIXME(eddyb) We could find a better approximation if ity.align < align.
let ity = layout::Integer::approximate_abi_align(self, align);
self.type_from_integer(ity)
}

/// Return a LLVM type that has at most the required alignment,
/// and exactly the required size, as a best-effort padding array.
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;

fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool;
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool;
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool;
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool;
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type {
let unit = layout::Integer::approximate_abi_align(self, align);
let size = size.bytes();
let unit_size = unit.size().bytes();
assert_eq!(size % unit_size, 0);
self.type_array(self.type_from_integer(unit), size / unit_size)
}

fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
common::type_needs_drop(self.tcx(), ty)
}

fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
common::type_is_sized(self.tcx(), ty)
}

fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
common::type_is_freeze(self.tcx(), ty)
}

fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
return false;
}

let tail = self.tcx().struct_tail(ty);
match tail.sty {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
}
}
}

impl<T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}

pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
fn backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type;
fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type;
Expand Down Expand Up @@ -119,11 +199,6 @@ pub trait ArgTypeMethods<'tcx>: HasCodegen<'tcx> {
fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> Self::Type;
}

pub trait TypeMethods<'tcx>:
BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
{
}
pub trait TypeMethods<'tcx>: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> {}

impl<T> TypeMethods<'tcx> for T where
Self: BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
{}
impl<T> TypeMethods<'tcx> for T where Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> {}

0 comments on commit b25b804

Please sign in to comment.