Skip to content

Commit 84813d3

Browse files
committed
Merge branch 'master' of git://github.com/rust-lang/rust into rust
2 parents 8e42f1e + 9d2e9b9 commit 84813d3

File tree

10 files changed

+76
-15
lines changed

10 files changed

+76
-15
lines changed

src/libcollections/string.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ impl String {
302302
/// assert_eq!(String::from_utf16_lossy(v),
303303
/// "𝄞mus\u{FFFD}ic\u{FFFD}".to_string());
304304
/// ```
305+
#[inline]
305306
#[stable]
306307
pub fn from_utf16_lossy(v: &[u16]) -> String {
307308
unicode_str::utf16_items(v).map(|c| c.to_char_lossy()).collect()
@@ -556,6 +557,7 @@ impl String {
556557
/// assert_eq!(s.remove(1), 'o');
557558
/// assert_eq!(s.remove(0), 'o');
558559
/// ```
560+
#[inline]
559561
#[stable]
560562
pub fn remove(&mut self, idx: uint) -> char {
561563
let len = self.len();
@@ -582,6 +584,7 @@ impl String {
582584
///
583585
/// If `idx` does not lie on a character boundary or is out of bounds, then
584586
/// this function will panic.
587+
#[inline]
585588
#[stable]
586589
pub fn insert(&mut self, idx: uint, ch: char) {
587590
let len = self.len();
@@ -618,6 +621,7 @@ impl String {
618621
/// }
619622
/// assert_eq!(s.as_slice(), "olleh");
620623
/// ```
624+
#[inline]
621625
#[stable]
622626
pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
623627
&mut self.vec
@@ -645,6 +649,7 @@ impl String {
645649
/// v.push('a');
646650
/// assert!(!v.is_empty());
647651
/// ```
652+
#[inline]
648653
#[stable]
649654
pub fn is_empty(&self) -> bool { self.len() == 0 }
650655

@@ -801,6 +806,7 @@ impl Str for String {
801806

802807
#[stable]
803808
impl Default for String {
809+
#[inline]
804810
#[stable]
805811
fn default() -> String {
806812
String::new()
@@ -809,13 +815,15 @@ impl Default for String {
809815

810816
#[stable]
811817
impl fmt::String for String {
818+
#[inline]
812819
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
813820
fmt::String::fmt(&**self, f)
814821
}
815822
}
816823

817824
#[unstable = "waiting on fmt stabilization"]
818825
impl fmt::Show for String {
826+
#[inline]
819827
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
820828
fmt::Show::fmt(&**self, f)
821829
}
@@ -842,6 +850,7 @@ impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for String {
842850
impl<'a> Add<&'a str> for String {
843851
type Output = String;
844852

853+
#[inline]
845854
fn add(mut self, other: &str) -> String {
846855
self.push_str(other);
847856
self
@@ -881,6 +890,7 @@ impl ops::Index<ops::FullRange> for String {
881890
impl ops::Deref for String {
882891
type Target = str;
883892

893+
#[inline]
884894
fn deref<'a>(&'a self) -> &'a str {
885895
unsafe { mem::transmute(&self.vec[]) }
886896
}
@@ -895,6 +905,7 @@ pub struct DerefString<'a> {
895905
impl<'a> Deref for DerefString<'a> {
896906
type Target = String;
897907

908+
#[inline]
898909
fn deref<'b>(&'b self) -> &'b String {
899910
unsafe { mem::transmute(&*self.x) }
900911
}
@@ -933,6 +944,7 @@ pub trait ToString {
933944
}
934945

935946
impl<T: fmt::String + ?Sized> ToString for T {
947+
#[inline]
936948
fn to_string(&self) -> String {
937949
use core::fmt::Writer;
938950
let mut buf = String::new();
@@ -943,12 +955,14 @@ impl<T: fmt::String + ?Sized> ToString for T {
943955
}
944956

945957
impl IntoCow<'static, String, str> for String {
958+
#[inline]
946959
fn into_cow(self) -> CowString<'static> {
947960
Cow::Owned(self)
948961
}
949962
}
950963

951964
impl<'a> IntoCow<'a, String, str> for &'a str {
965+
#[inline]
952966
fn into_cow(self) -> CowString<'a> {
953967
Cow::Borrowed(self)
954968
}
@@ -966,6 +980,7 @@ impl<'a> Str for CowString<'a> {
966980
}
967981

968982
impl fmt::Writer for String {
983+
#[inline]
969984
fn write_str(&mut self, s: &str) -> fmt::Result {
970985
self.push_str(s);
971986
Ok(())

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
};

src/librustc_trans/trans/common.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,7 @@ fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
222222
match ty.sty {
223223
ty::ty_struct(def_id, substs) => {
224224
let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
225-
fields.len() == 1 &&
226-
fields[0].name ==
227-
token::special_idents::unnamed_field.name &&
228-
type_is_immediate(ccx, fields[0].mt.ty)
225+
fields.len() == 1 && type_is_immediate(ccx, fields[0].mt.ty)
229226
}
230227
_ => false
231228
}
@@ -247,7 +244,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
247244
return false;
248245
}
249246
match ty.sty {
250-
ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) |
247+
ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) | ty::ty_vec(_, Some(_)) |
251248
ty::ty_unboxed_closure(..) => {
252249
let llty = sizing_type_of(ccx, ty);
253250
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())

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
};

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

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
}

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

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
}

src/test/run-pass/unwind-unique.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ fn f() {
1919
}
2020

2121
pub fn main() {
22-
let _t = Thread::spawn(f);
22+
let _t = Thread::scoped(f);
2323
}

src/test/run-pass/weak-lang-item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extern crate "weak-lang-items" as other;
1515
use std::thread::Thread;
1616

1717
fn main() {
18-
let _ = Thread::spawn(move|| {
18+
let _ = Thread::scoped(move|| {
1919
other::foo()
2020
});
2121
}

0 commit comments

Comments
 (0)