rustc_target: move in type definitions from rustc_trans::abi.

This commit is contained in:
Irina Popa 2017-12-28 19:07:02 +02:00
parent bdcd08278a
commit 3bd7efadae
10 changed files with 243 additions and 213 deletions

3
src/Cargo.lock generated
View File

@ -2115,8 +2115,8 @@ dependencies = [
name = "rustc_target"
version = "0.0.0"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"syntax 0.0.0",
]
@ -2138,7 +2138,6 @@ dependencies = [
name = "rustc_trans"
version = "0.0.0"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -9,10 +9,10 @@ path = "lib.rs"
crate-type = ["dylib"]
[dependencies]
bitflags = "1.0"
log = "0.4"
syntax = { path = "../libsyntax" }
serialize = { path = "../libserialize" }
log = "0.4"
rand = "0.4"
[features]
jemalloc = []

View File

@ -0,0 +1,214 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use abi::{Align, HasDataLayout, Size};
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum PassMode {
/// Ignore the argument (useful for empty struct).
Ignore,
/// Pass the argument directly.
Direct(ArgAttributes),
/// Pass a pair's elements directly in two arguments.
Pair(ArgAttributes, ArgAttributes),
/// Pass the argument after casting it, to either
/// a single uniform or a pair of registers.
Cast(CastTarget),
/// Pass the argument indirectly via a hidden pointer.
Indirect(ArgAttributes),
}
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
// of this module
pub use self::attr_impl::ArgAttribute;
#[allow(non_upper_case_globals)]
#[allow(unused)]
mod attr_impl {
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
bitflags! {
#[derive(Default)]
pub struct ArgAttribute: u16 {
const ByVal = 1 << 0;
const NoAlias = 1 << 1;
const NoCapture = 1 << 2;
const NonNull = 1 << 3;
const ReadOnly = 1 << 4;
const SExt = 1 << 5;
const StructRet = 1 << 6;
const ZExt = 1 << 7;
const InReg = 1 << 8;
}
}
}
/// A compact representation of LLVM attributes (at least those relevant for this module)
/// that can be manipulated without interacting with LLVM's Attribute machinery.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct ArgAttributes {
pub regular: ArgAttribute,
pub pointee_size: Size,
pub pointee_align: Option<Align>
}
impl ArgAttributes {
pub fn new() -> Self {
ArgAttributes {
regular: ArgAttribute::default(),
pointee_size: Size::from_bytes(0),
pointee_align: None,
}
}
pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
self.regular = self.regular | attr;
self
}
pub fn contains(&self, attr: ArgAttribute) -> bool {
self.regular.contains(attr)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum RegKind {
Integer,
Float,
Vector
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Reg {
pub kind: RegKind,
pub size: Size,
}
macro_rules! reg_ctor {
($name:ident, $kind:ident, $bits:expr) => {
pub fn $name() -> Reg {
Reg {
kind: RegKind::$kind,
size: Size::from_bits($bits)
}
}
}
}
impl Reg {
reg_ctor!(i8, Integer, 8);
reg_ctor!(i16, Integer, 16);
reg_ctor!(i32, Integer, 32);
reg_ctor!(i64, Integer, 64);
reg_ctor!(f32, Float, 32);
reg_ctor!(f64, Float, 64);
}
impl Reg {
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
let dl = cx.data_layout();
match self.kind {
RegKind::Integer => {
match self.size.bits() {
1 => dl.i1_align,
2...8 => dl.i8_align,
9...16 => dl.i16_align,
17...32 => dl.i32_align,
33...64 => dl.i64_align,
65...128 => dl.i128_align,
_ => panic!("unsupported integer: {:?}", self)
}
}
RegKind::Float => {
match self.size.bits() {
32 => dl.f32_align,
64 => dl.f64_align,
_ => panic!("unsupported float: {:?}", self)
}
}
RegKind::Vector => dl.vector_align(self.size)
}
}
}
/// An argument passed entirely registers with the
/// same kind (e.g. HFA / HVA on PPC64 and AArch64).
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Uniform {
pub unit: Reg,
/// The total size of the argument, which can be:
/// * equal to `unit.size` (one scalar/vector)
/// * a multiple of `unit.size` (an array of scalar/vectors)
/// * if `unit.kind` is `Integer`, the last element
/// can be shorter, i.e. `{ i64, i64, i32 }` for
/// 64-bit integers with a total size of 20 bytes
pub total: Size,
}
impl From<Reg> for Uniform {
fn from(unit: Reg) -> Uniform {
Uniform {
unit,
total: unit.size
}
}
}
impl Uniform {
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
self.unit.align(cx)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct CastTarget {
pub prefix: [Option<RegKind>; 8],
pub prefix_chunk: Size,
pub rest: Uniform,
}
impl From<Reg> for CastTarget {
fn from(unit: Reg) -> CastTarget {
CastTarget::from(Uniform::from(unit))
}
}
impl From<Uniform> for CastTarget {
fn from(uniform: Uniform) -> CastTarget {
CastTarget {
prefix: [None; 8],
prefix_chunk: Size::from_bytes(0),
rest: uniform
}
}
}
impl CastTarget {
pub fn pair(a: Reg, b: Reg) -> CastTarget {
CastTarget {
prefix: [Some(a.kind), None, None, None, None, None, None, None],
prefix_chunk: a.size,
rest: Uniform::from(b)
}
}
pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
(self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64)
.abi_align(self.rest.align(cx)) + self.rest.total
}
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
self.prefix.iter()
.filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx)))
.fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)),
|acc, align| acc.max(align))
}
}

View File

@ -16,6 +16,8 @@ use spec::Target;
use std::cmp;
use std::ops::{Add, Sub, Mul, AddAssign, RangeInclusive};
pub mod call;
/// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout)
/// for a target, which contains everything needed to compute layouts.
pub struct TargetDataLayout {

View File

@ -31,8 +31,9 @@
#![feature(inclusive_range)]
#![feature(slice_patterns)]
#[macro_use]
extern crate bitflags;
extern crate syntax;
extern crate rand;
extern crate serialize;
#[macro_use] extern crate log;

View File

@ -10,7 +10,6 @@ crate-type = ["dylib"]
test = false
[dependencies]
bitflags = "1.0"
cc = "1.0.1"
flate2 = "1.0"
jobserver = "0.1.5"

View File

@ -37,53 +37,14 @@ use type_::Type;
use type_of::{LayoutLlvmExt, PointerKind};
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, Align, Size, TyLayout};
use rustc::ty::layout::{HasDataLayout, LayoutOf};
use rustc::ty::layout::{self, LayoutOf, Size, TyLayout};
use libc::c_uint;
use std::cmp;
pub use syntax::abi::Abi;
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum PassMode {
/// Ignore the argument (useful for empty struct).
Ignore,
/// Pass the argument directly.
Direct(ArgAttributes),
/// Pass a pair's elements directly in two arguments.
Pair(ArgAttributes, ArgAttributes),
/// Pass the argument after casting it, to either
/// a single uniform or a pair of registers.
Cast(CastTarget),
/// Pass the argument indirectly via a hidden pointer.
Indirect(ArgAttributes),
}
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
// of this module
pub use self::attr_impl::ArgAttribute;
#[allow(non_upper_case_globals)]
#[allow(unused)]
mod attr_impl {
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
bitflags! {
#[derive(Default)]
pub struct ArgAttribute: u16 {
const ByVal = 1 << 0;
const NoAlias = 1 << 1;
const NoCapture = 1 << 2;
const NonNull = 1 << 3;
const ReadOnly = 1 << 4;
const SExt = 1 << 5;
const StructRet = 1 << 6;
const ZExt = 1 << 7;
const InReg = 1 << 8;
}
}
}
pub use rustc_target::abi::call::*;
macro_rules! for_each_kind {
($flags: ident, $f: ident, $($kind: ident),+) => ({
@ -91,41 +52,24 @@ macro_rules! for_each_kind {
})
}
impl ArgAttribute {
trait ArgAttributeExt {
fn for_each_kind<F>(&self, f: F) where F: FnMut(llvm::Attribute);
}
impl ArgAttributeExt for ArgAttribute {
fn for_each_kind<F>(&self, mut f: F) where F: FnMut(llvm::Attribute) {
for_each_kind!(self, f,
ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
}
}
/// A compact representation of LLVM attributes (at least those relevant for this module)
/// that can be manipulated without interacting with LLVM's Attribute machinery.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct ArgAttributes {
regular: ArgAttribute,
pointee_size: Size,
pointee_align: Option<Align>
pub trait ArgAttributesExt {
fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef);
fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef);
}
impl ArgAttributes {
fn new() -> Self {
ArgAttributes {
regular: ArgAttribute::default(),
pointee_size: Size::from_bytes(0),
pointee_align: None,
}
}
pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
self.regular = self.regular | attr;
self
}
pub fn contains(&self, attr: ArgAttribute) -> bool {
self.regular.contains(attr)
}
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
impl ArgAttributesExt for ArgAttributes {
fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
let mut regular = self.regular;
unsafe {
let deref = self.pointee_size.bytes();
@ -150,7 +94,7 @@ impl ArgAttributes {
}
}
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
let mut regular = self.regular;
unsafe {
let deref = self.pointee_size.bytes();
@ -175,67 +119,13 @@ impl ArgAttributes {
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum RegKind {
Integer,
Float,
Vector
pub trait LlvmType {
fn llvm_type(&self, cx: &CodegenCx) -> Type;
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Reg {
pub kind: RegKind,
pub size: Size,
}
macro_rules! reg_ctor {
($name:ident, $kind:ident, $bits:expr) => {
pub fn $name() -> Reg {
Reg {
kind: RegKind::$kind,
size: Size::from_bits($bits)
}
}
}
}
impl Reg {
reg_ctor!(i8, Integer, 8);
reg_ctor!(i16, Integer, 16);
reg_ctor!(i32, Integer, 32);
reg_ctor!(i64, Integer, 64);
reg_ctor!(f32, Float, 32);
reg_ctor!(f64, Float, 64);
}
impl Reg {
pub fn align(&self, cx: &CodegenCx) -> Align {
let dl = cx.data_layout();
match self.kind {
RegKind::Integer => {
match self.size.bits() {
1 => dl.i1_align,
2...8 => dl.i8_align,
9...16 => dl.i16_align,
17...32 => dl.i32_align,
33...64 => dl.i64_align,
65...128 => dl.i128_align,
_ => bug!("unsupported integer: {:?}", self)
}
}
RegKind::Float => {
match self.size.bits() {
32 => dl.f32_align,
64 => dl.f64_align,
_ => bug!("unsupported float: {:?}", self)
}
}
RegKind::Vector => dl.vector_align(self.size)
}
}
pub fn llvm_type(&self, cx: &CodegenCx) -> Type {
impl LlvmType for Reg {
fn llvm_type(&self, cx: &CodegenCx) -> Type {
match self.kind {
RegKind::Integer => Type::ix(cx, self.size.bits()),
RegKind::Float => {
@ -252,36 +142,6 @@ impl Reg {
}
}
/// An argument passed entirely registers with the
/// same kind (e.g. HFA / HVA on PPC64 and AArch64).
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Uniform {
pub unit: Reg,
/// The total size of the argument, which can be:
/// * equal to `unit.size` (one scalar/vector)
/// * a multiple of `unit.size` (an array of scalar/vectors)
/// * if `unit.kind` is `Integer`, the last element
/// can be shorter, i.e. `{ i64, i64, i32 }` for
/// 64-bit integers with a total size of 20 bytes
pub total: Size,
}
impl From<Reg> for Uniform {
fn from(unit: Reg) -> Uniform {
Uniform {
unit,
total: unit.size
}
}
}
impl Uniform {
pub fn align(&self, cx: &CodegenCx) -> Align {
self.unit.align(cx)
}
}
pub trait LayoutExt<'tcx> {
fn is_aggregate(&self) -> bool;
fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg>;
@ -381,51 +241,8 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> {
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct CastTarget {
pub prefix: [Option<RegKind>; 8],
pub prefix_chunk: Size,
pub rest: Uniform,
}
impl From<Reg> for CastTarget {
fn from(unit: Reg) -> CastTarget {
CastTarget::from(Uniform::from(unit))
}
}
impl From<Uniform> for CastTarget {
fn from(uniform: Uniform) -> CastTarget {
CastTarget {
prefix: [None; 8],
prefix_chunk: Size::from_bytes(0),
rest: uniform
}
}
}
impl CastTarget {
pub fn pair(a: Reg, b: Reg) -> CastTarget {
CastTarget {
prefix: [Some(a.kind), None, None, None, None, None, None, None],
prefix_chunk: a.size,
rest: Uniform::from(b)
}
}
pub fn size(&self, cx: &CodegenCx) -> Size {
(self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64)
.abi_align(self.rest.align(cx)) + self.rest.total
}
pub fn align(&self, cx: &CodegenCx) -> Align {
self.prefix.iter()
.filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx)))
.fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)),
|acc, align| acc.max(align))
}
pub fn llvm_type(&self, cx: &CodegenCx) -> Type {
impl LlvmType for CastTarget {
fn llvm_type(&self, cx: &CodegenCx) -> Type {
let rest_ll_unit = self.rest.unit.llvm_type(cx);
let rest_count = self.rest.total.bytes() / self.rest.unit.size.bytes();
let rem_bytes = self.rest.total.bytes() % self.rest.unit.size.bytes();

View File

@ -13,7 +13,7 @@
use intrinsics::{self, Intrinsic};
use llvm;
use llvm::{ValueRef};
use abi::{Abi, FnType, PassMode};
use abi::{Abi, FnType, LlvmType, PassMode};
use mir::place::PlaceRef;
use mir::operand::{OperandRef, OperandValue};
use base::*;

View File

@ -33,8 +33,6 @@
use rustc::dep_graph::WorkProduct;
use syntax_pos::symbol::Symbol;
#[macro_use]
extern crate bitflags;
extern crate flate2;
extern crate libc;
#[macro_use] extern crate rustc;

View File

@ -13,7 +13,7 @@ use rustc::middle::lang_items;
use rustc::ty::{self, TypeFoldable};
use rustc::ty::layout::{self, LayoutOf};
use rustc::mir;
use abi::{Abi, FnType, ArgType, PassMode};
use abi::{Abi, FnType, ArgType, LlvmType, PassMode};
use base;
use callee;
use builder::Builder;