Skip to content

Commit f0636b6

Browse files
committed
rustc_trans: use ty::layout for ABI computation instead of LLVM types.
1 parent 43b227f commit f0636b6

22 files changed

+992
-1672
lines changed

src/librustc_trans/abi.rs

+400-185
Large diffs are not rendered by default.

src/librustc_trans/adt.rs

+7-17
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,6 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
9595
generic_type_of(cx, t, None, false, false)
9696
}
9797

98-
99-
// Pass dst=true if the type you are passing is a DST. Yes, we could figure
100-
// this out, but if you call this on an unsized type without realising it, you
101-
// are going to get the wrong type (it will not include the unsized parts of it).
102-
pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
103-
t: Ty<'tcx>, dst: bool) -> Type {
104-
generic_type_of(cx, t, None, true, dst)
105-
}
106-
10798
pub fn incomplete_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
10899
t: Ty<'tcx>, name: &str) -> Type {
109100
generic_type_of(cx, t, Some(name), false, false)
@@ -149,7 +140,11 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
149140
};
150141
let nnty = monomorphize::field_ty(cx.tcx(), substs,
151142
&def.variants[nndiscr as usize].fields[0]);
152-
type_of::sizing_type_of(cx, nnty)
143+
if let layout::Scalar { value: layout::Pointer, .. } = *cx.layout_of(nnty) {
144+
Type::i8p(cx)
145+
} else {
146+
type_of::type_of(cx, nnty)
147+
}
153148
}
154149
layout::StructWrappedNullablePointer { nndiscr, ref nonnull, .. } => {
155150
let fields = compute_fields(cx, t, nndiscr as usize, false);
@@ -181,10 +176,6 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
181176
}
182177
}
183178
}
184-
layout::Vector { element, count } => {
185-
let elem_ty = Type::from_primitive(cx, element);
186-
Type::vector(&elem_ty, count)
187-
}
188179
layout::UntaggedUnion { ref variants, .. }=> {
189180
// Use alignment-sized ints to fill all the union storage.
190181
let size = variants.stride().bytes();
@@ -258,11 +249,10 @@ fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
258249

259250
fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fields: &Vec<Ty<'tcx>>,
260251
variant: &layout::Struct,
261-
sizing: bool, dst: bool) -> Vec<Type> {
252+
sizing: bool, _dst: bool) -> Vec<Type> {
262253
let fields = variant.field_index_by_increasing_offset().map(|i| fields[i as usize]);
263254
if sizing {
264-
fields.filter(|ty| !dst || cx.shared().type_is_sized(*ty))
265-
.map(|ty| type_of::sizing_type_of(cx, ty)).collect()
255+
bug!()
266256
} else {
267257
fields.map(|ty| type_of::in_memory_type_of(cx, ty)).collect()
268258
}

src/librustc_trans/cabi_aarch64.rs

+57-121
Original file line numberDiff line numberDiff line change
@@ -8,163 +8,99 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![allow(non_upper_case_globals)]
12-
13-
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
14-
use abi::{self, FnType, ArgType};
11+
use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform};
1512
use context::CrateContext;
16-
use type_::Type;
17-
18-
fn ty_size(ty: Type) -> usize {
19-
abi::ty_size(ty, 8)
20-
}
21-
22-
fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> {
23-
fn check_array(ty: Type) -> Option<(Type, u64)> {
24-
let len = ty.array_length() as u64;
25-
if len == 0 {
26-
return None
27-
}
28-
let elt = ty.element_type();
29-
30-
// if our element is an HFA/HVA, so are we; multiply members by our len
31-
is_homogenous_aggregate_ty(elt).map(|(base_ty, members)| (base_ty, len * members))
32-
}
33-
34-
fn check_struct(ty: Type) -> Option<(Type, u64)> {
35-
let str_tys = ty.field_types();
36-
if str_tys.len() == 0 {
37-
return None
38-
}
39-
40-
let mut prev_base_ty = None;
41-
let mut members = 0;
42-
for opt_homog_agg in str_tys.iter().map(|t| is_homogenous_aggregate_ty(*t)) {
43-
match (prev_base_ty, opt_homog_agg) {
44-
// field isn't itself an HFA, so we aren't either
45-
(_, None) => return None,
46-
47-
// first field - store its type and number of members
48-
(None, Some((field_ty, field_members))) => {
49-
prev_base_ty = Some(field_ty);
50-
members = field_members;
51-
},
5213

53-
// 2nd or later field - give up if it's a different type; otherwise incr. members
54-
(Some(prev_ty), Some((field_ty, field_members))) => {
55-
if prev_ty != field_ty {
56-
return None;
57-
}
58-
members += field_members;
59-
}
60-
}
61-
}
62-
63-
// Because of previous checks, we know prev_base_ty is Some(...) because
64-
// 1. str_tys has at least one element; and
65-
// 2. prev_base_ty was filled in (or we would've returned early)
66-
let (base_ty, members) = (prev_base_ty.unwrap(), members);
14+
fn is_homogenous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>)
15+
-> Option<Uniform> {
16+
arg.layout.homogenous_aggregate(ccx).and_then(|unit| {
17+
let size = arg.layout.size(ccx);
6718

68-
// Ensure there is no padding.
69-
if ty_size(ty) == ty_size(base_ty) * (members as usize) {
70-
Some((base_ty, members))
71-
} else {
72-
None
19+
// Ensure we have at most four uniquely addressable members.
20+
if size > unit.size.checked_mul(4, ccx).unwrap() {
21+
return None;
7322
}
74-
}
7523

76-
let homog_agg = match ty.kind() {
77-
Float => Some((ty, 1)),
78-
Double => Some((ty, 1)),
79-
Array => check_array(ty),
80-
Struct => check_struct(ty),
81-
Vector => match ty_size(ty) {
82-
4|8 => Some((ty, 1)),
83-
_ => None
84-
},
85-
_ => None
86-
};
24+
let valid_unit = match unit.kind {
25+
RegKind::Integer => false,
26+
RegKind::Float => true,
27+
RegKind::Vector => size.bits() == 64 || size.bits() == 128
28+
};
8729

88-
// Ensure we have at most four uniquely addressable members
89-
homog_agg.and_then(|(base_ty, members)| {
90-
if members > 0 && members <= 4 {
91-
Some((base_ty, members))
30+
if valid_unit {
31+
Some(Uniform {
32+
unit,
33+
total: size
34+
})
9235
} else {
9336
None
9437
}
9538
})
9639
}
9740

98-
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
99-
if is_reg_ty(ret.ty) {
41+
fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
42+
if !ret.layout.is_aggregate() {
10043
ret.extend_integer_width_to(32);
10144
return;
10245
}
103-
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(ret.ty) {
104-
ret.cast = Some(Type::array(&base_ty, members));
46+
if let Some(uniform) = is_homogenous_aggregate(ccx, ret) {
47+
ret.cast_to(ccx, uniform);
10548
return;
10649
}
107-
let size = ty_size(ret.ty);
108-
if size <= 16 {
109-
let llty = if size <= 1 {
110-
Type::i8(ccx)
111-
} else if size <= 2 {
112-
Type::i16(ccx)
113-
} else if size <= 4 {
114-
Type::i32(ccx)
115-
} else if size <= 8 {
116-
Type::i64(ccx)
50+
let size = ret.layout.size(ccx);
51+
let bits = size.bits();
52+
if bits <= 128 {
53+
let unit = if bits <= 8 {
54+
Reg::i8()
55+
} else if bits <= 16 {
56+
Reg::i16()
57+
} else if bits <= 32 {
58+
Reg::i32()
11759
} else {
118-
Type::array(&Type::i64(ccx), ((size + 7 ) / 8 ) as u64)
60+
Reg::i64()
11961
};
120-
ret.cast = Some(llty);
62+
63+
ret.cast_to(ccx, Uniform {
64+
unit,
65+
total: size
66+
});
12167
return;
12268
}
12369
ret.make_indirect(ccx);
12470
}
12571

126-
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) {
127-
if is_reg_ty(arg.ty) {
72+
fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) {
73+
if !arg.layout.is_aggregate() {
12874
arg.extend_integer_width_to(32);
12975
return;
13076
}
131-
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(arg.ty) {
132-
arg.cast = Some(Type::array(&base_ty, members));
77+
if let Some(uniform) = is_homogenous_aggregate(ccx, arg) {
78+
arg.cast_to(ccx, uniform);
13379
return;
13480
}
135-
let size = ty_size(arg.ty);
136-
if size <= 16 {
137-
let llty = if size == 0 {
138-
Type::array(&Type::i64(ccx), 0)
139-
} else if size == 1 {
140-
Type::i8(ccx)
141-
} else if size == 2 {
142-
Type::i16(ccx)
143-
} else if size <= 4 {
144-
Type::i32(ccx)
145-
} else if size <= 8 {
146-
Type::i64(ccx)
81+
let size = arg.layout.size(ccx);
82+
let bits = size.bits();
83+
if bits <= 128 {
84+
let unit = if bits <= 8 {
85+
Reg::i8()
86+
} else if bits <= 16 {
87+
Reg::i16()
88+
} else if bits <= 32 {
89+
Reg::i32()
14790
} else {
148-
Type::array(&Type::i64(ccx), ((size + 7 ) / 8 ) as u64)
91+
Reg::i64()
14992
};
150-
arg.cast = Some(llty);
93+
94+
arg.cast_to(ccx, Uniform {
95+
unit,
96+
total: size
97+
});
15198
return;
15299
}
153100
arg.make_indirect(ccx);
154101
}
155102

156-
fn is_reg_ty(ty: Type) -> bool {
157-
match ty.kind() {
158-
Integer
159-
| Pointer
160-
| Float
161-
| Double
162-
| Vector => true,
163-
_ => false
164-
}
165-
}
166-
167-
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
103+
pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) {
168104
if !fty.ret.is_ignore() {
169105
classify_ret_ty(ccx, &mut fty.ret);
170106
}

0 commit comments

Comments
 (0)