Skip to content

Commit 79cbc8c

Browse files
committed
---
yaml --- r: 172773 b: refs/heads/try c: 6ef0840 h: refs/heads/master i: 172771: 0b7ff40 v: v3
1 parent ce1e823 commit 79cbc8c

File tree

7 files changed

+58
-9
lines changed

7 files changed

+58
-9
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 170c4399e614fe599c3d41306b3429ca8b3b68c6
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 5b3cd3900ceda838f5798c30ab96ceb41f962534
5-
refs/heads/try: 2100b10c4c61ac7c0fe67ae4c9a390eaf3708ae4
5+
refs/heads/try: 6ef08406dccdeeb828a6cfc7658ac149900e73ad
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
88
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596

branches/try/src/librustc_trans/trans/base.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,11 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
10541054
C_undef(type_of::type_of(cx.ccx(), t))
10551055
} else if ty::type_is_bool(t) {
10561056
Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, llvm::False), Type::i1(cx.ccx()))
1057+
} else if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() {
1058+
// We want to pass small aggregates as immediate values, but using an aggregate LLVM type
1059+
// for this leads to bad optimizations, so its arg type is an appropriately sized integer
1060+
// and we have to convert it
1061+
Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to()))
10571062
} else if ty::type_is_char(t) {
10581063
// a char is a Unicode codepoint, and so takes values from 0
10591064
// to 0x10FFFF inclusive only.
@@ -1065,9 +1070,14 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
10651070

10661071
/// Helper for storing values in memory. Does the necessary conversion if the in-memory type
10671072
/// differs from the type used for SSA values.
1068-
pub fn store_ty(cx: Block, v: ValueRef, dst: ValueRef, t: Ty) {
1073+
pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t: Ty<'tcx>) {
10691074
if ty::type_is_bool(t) {
10701075
Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst);
1076+
} else if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() {
1077+
// We want to pass small aggregates as immediate values, but using an aggregate LLVM type
1078+
// for this leads to bad optimizations, so its arg type is an appropriately sized integer
1079+
// and we have to convert it
1080+
Store(cx, v, BitCast(cx, dst, type_of::arg_type_of(cx.ccx(), t).ptr_to()));
10711081
} else {
10721082
Store(cx, v, dst);
10731083
};

branches/try/src/librustc_trans/trans/foreign.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,13 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
736736
if ty::type_is_bool(rust_ty) {
737737
let tmp = builder.load_range_assert(llforeign_arg, 0, 2, llvm::False);
738738
builder.trunc(tmp, Type::i1(ccx))
739+
} else if type_of::type_of(ccx, rust_ty).is_aggregate() {
740+
// We want to pass small aggregates as immediate values, but using an aggregate
741+
// LLVM type for this leads to bad optimizations, so its arg type is an
742+
// appropriately sized integer and we have to convert it
743+
let tmp = builder.bitcast(llforeign_arg,
744+
type_of::arg_type_of(ccx, rust_ty).ptr_to());
745+
builder.load(tmp)
739746
} else {
740747
builder.load(llforeign_arg)
741748
}
@@ -834,10 +841,10 @@ fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
834841
fn_sig: &ty::FnSig<'tcx>,
835842
arg_tys: &[Ty<'tcx>])
836843
-> LlvmSignature {
837-
let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
844+
let llarg_tys = arg_tys.iter().map(|&arg| foreign_arg_type_of(ccx, arg)).collect();
838845
let (llret_ty, ret_def) = match fn_sig.output {
839846
ty::FnConverging(ret_ty) =>
840-
(type_of::arg_type_of(ccx, ret_ty), !return_type_is_void(ccx, ret_ty)),
847+
(type_of::foreign_arg_type_of(ccx, ret_ty), !return_type_is_void(ccx, ret_ty)),
841848
ty::FnDiverging =>
842849
(Type::nil(ccx), false)
843850
};

branches/try/src/librustc_trans/trans/glue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
138138
-> Block<'blk, 'tcx> {
139139
let _icx = push_ctxt("drop_ty_immediate");
140140
let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
141-
Store(bcx, v, vp);
141+
store_ty(bcx, v, vp, t);
142142
drop_ty(bcx, vp, t, source_location)
143143
}
144144

branches/try/src/librustc_trans/trans/intrinsic.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
357357
&ccx.link_meta().crate_hash);
358358
// NB: This needs to be kept in lockstep with the TypeId struct in
359359
// the intrinsic module
360-
C_named_struct(llret_ty, &[C_u64(ccx, hash)])
360+
C_u64(ccx, hash)
361361
}
362362
(_, "init") => {
363363
let tp_ty = *substs.types.get(FnSpace, 0);
364-
let lltp_ty = type_of::type_of(ccx, tp_ty);
364+
let lltp_ty = type_of::arg_type_of(ccx, tp_ty);
365365
if return_type_is_void(ccx, tp_ty) {
366366
C_nil(ccx)
367367
} else {
@@ -686,6 +686,11 @@ fn with_overflow_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, name: &'static st
686686
let ret = C_undef(type_of::type_of(bcx.ccx(), t));
687687
let ret = InsertValue(bcx, ret, result, 0);
688688
let ret = InsertValue(bcx, ret, overflow, 1);
689-
690-
ret
689+
if type_is_immediate(bcx.ccx(), t) {
690+
let tmp = alloc_ty(bcx, t, "tmp");
691+
Store(bcx, ret, tmp);
692+
load_ty(bcx, tmp, t)
693+
} else {
694+
ret
695+
}
691696
}

branches/try/src/librustc_trans/trans/type_.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ impl Type {
8282
ty!(llvm::LLVMInt64TypeInContext(ccx.llcx()))
8383
}
8484

85+
// Creates an integer type with the given number of bits, e.g. i24
86+
pub fn ix(ccx: &CrateContext, num_bits: u64) -> Type {
87+
ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), num_bits as c_uint))
88+
}
89+
8590
pub fn f32(ccx: &CrateContext) -> Type {
8691
ty!(llvm::LLVMFloatTypeInContext(ccx.llcx()))
8792
}
@@ -260,6 +265,13 @@ impl Type {
260265
ty!(llvm::LLVMPointerType(self.to_ref(), 0))
261266
}
262267

268+
pub fn is_aggregate(&self) -> bool {
269+
match self.kind() {
270+
TypeKind::Struct | TypeKind::Array => true,
271+
_ => false
272+
}
273+
}
274+
263275
pub fn is_packed(&self) -> bool {
264276
unsafe {
265277
llvm::LLVMIsPackedStruct(self.to_ref()) == True

branches/try/src/librustc_trans/trans/type_of.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,24 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
243243
llsizingty
244244
}
245245

246+
pub fn foreign_arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
247+
if ty::type_is_bool(t) {
248+
Type::i1(cx)
249+
} else {
250+
type_of(cx, t)
251+
}
252+
}
253+
246254
pub fn arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
247255
if ty::type_is_bool(t) {
248256
Type::i1(cx)
257+
} else if type_is_immediate(cx, t) && type_of(cx, t).is_aggregate() {
258+
// We want to pass small aggregates as immediate values, but using an aggregate LLVM type
259+
// for this leads to bad optimizations, so its arg type is an appropriately sized integer
260+
match machine::llsize_of_alloc(cx, sizing_type_of(cx, t)) {
261+
0 => type_of(cx, t),
262+
n => Type::ix(cx, n * 8),
263+
}
249264
} else {
250265
type_of(cx, t)
251266
}

0 commit comments

Comments
 (0)