Skip to content

Commit af29883

Browse files
committed
---
yaml --- r: 60107 b: refs/heads/master c: da2ac90 h: refs/heads/master i: 60105: a9d2b05 60103: 9d0c68e v: v3
1 parent 7691046 commit af29883

File tree

14 files changed

+224
-52
lines changed

14 files changed

+224
-52
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 0c02d0f92ecabb9486482c3e4d660e736346803b
2+
refs/heads/master: da2ac908126ec52e60e621416ce84284e7b77e51
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2d28d645422c1617be58c8ca7ad9a457264ca850
55
refs/heads/try: c50a9d5b664478e533ba1d1d353213d70c8ad589

trunk/src/libcore/iter.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ breaking out of iteration. The adaptors in the module work with any such iterato
1717
tied to specific traits. For example:
1818
1919
~~~~
20-
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
20+
use core::iter::iter_to_vec;
21+
println(iter_to_vec(|f| uint::range(0, 20, f)).to_str());
2122
~~~~
2223
2324
An external iterator object implementing the interface in the `iterator` module can be used as an
@@ -54,12 +55,12 @@ pub trait Times {
5455
*
5556
* ~~~
5657
* let xs = ~[1, 2, 3];
57-
* let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
58+
* let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) };
5859
* assert_eq!(xs, ys);
5960
* ~~~
6061
*/
6162
#[inline(always)]
62-
pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] {
63+
pub fn iter_to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] {
6364
let mut v = ~[];
6465
for iter |x| { v.push(x) }
6566
v
@@ -184,9 +185,9 @@ mod tests {
184185
use prelude::*;
185186

186187
#[test]
187-
fn test_to_vec() {
188+
fn test_iter_to_vec() {
188189
let xs = ~[1, 2, 3];
189-
let ys = do to_vec |f| { xs.each(|x| f(*x)) };
190+
let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) };
190191
assert_eq!(xs, ys);
191192
}
192193

trunk/src/libcore/iterator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ mod tests {
378378
#[test]
379379
fn test_counter_to_vec() {
380380
let mut it = Counter::new(0, 5).take(10);
381-
let xs = iter::to_vec(|f| it.advance(f));
381+
let xs = iter::iter_to_vec(|f| it.advance(f));
382382
assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
383383
}
384384

trunk/src/libcore/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub mod weak_task;
3030
pub mod exchange_alloc;
3131
#[path = "unstable/intrinsics.rs"]
3232
pub mod intrinsics;
33+
#[path = "unstable/simd.rs"]
34+
pub mod simd;
3335
#[path = "unstable/extfmt.rs"]
3436
pub mod extfmt;
3537
#[path = "unstable/lang.rs"]

trunk/src/libcore/unstable/simd.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! SIMD vectors
12+
13+
#[allow(non_camel_case_types)];
14+
15+
#[simd]
16+
pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
17+
18+
#[simd]
19+
pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
20+
21+
#[simd]
22+
pub struct i32x4(i32, i32, i32, i32);
23+
24+
#[simd]
25+
pub struct i64x2(i64, i64);
26+
27+
#[simd]
28+
pub struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
29+
30+
#[simd]
31+
pub struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
32+
33+
#[simd]
34+
pub struct u32x4(u32, u32, u32, u32);
35+
36+
#[simd]
37+
pub struct u64x2(u64, u64);
38+
39+
#[simd]
40+
pub struct f32x4(f32, f32, f32, f32);
41+
42+
#[simd]
43+
pub struct f64x2(f64, f64);

trunk/src/librustc/middle/trans/build.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -963,20 +963,28 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
963963
}
964964
965965
pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
966-
Index: ValueRef) {
966+
Index: ValueRef) -> ValueRef {
967967
unsafe {
968-
if cx.unreachable { return; }
968+
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
969969
count_insn(cx, "insertelement");
970-
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
970+
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname())
971971
}
972972
}
973973
974974
pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
975-
Mask: ValueRef) {
975+
Mask: ValueRef) -> ValueRef {
976976
unsafe {
977-
if cx.unreachable { return; }
977+
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
978978
count_insn(cx, "shufflevector");
979-
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
979+
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname())
980+
}
981+
}
982+
983+
pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
984+
unsafe {
985+
let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts));
986+
let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0));
987+
ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts)))
980988
}
981989
}
982990

trunk/src/librustc/middle/trans/common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,12 @@ pub fn T_array(t: TypeRef, n: uint) -> TypeRef {
984984
}
985985
}
986986

987+
pub fn T_vector(t: TypeRef, n: uint) -> TypeRef {
988+
unsafe {
989+
return llvm::LLVMVectorType(t, n as c_uint);
990+
}
991+
}
992+
987993
// Interior vector.
988994
pub fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef {
989995
return T_struct(~[T_int(targ_cfg), // fill

trunk/src/librustc/middle/trans/type_of.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,15 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
155155
}
156156

157157
ty::ty_struct(did, _) => {
158-
let repr = adt::represent_type(cx, t);
159-
let packed = ty::lookup_packed(cx.tcx, did);
160-
T_struct(adt::sizing_fields_of(cx, repr), packed)
158+
if ty::type_is_simd(cx.tcx, t) {
159+
let et = ty::simd_type(cx.tcx, t);
160+
let n = ty::simd_size(cx.tcx, t);
161+
T_vector(type_of(cx, et), n)
162+
} else {
163+
let repr = adt::represent_type(cx, t);
164+
let packed = ty::lookup_packed(cx.tcx, did);
165+
T_struct(adt::sizing_fields_of(cx, repr), packed)
166+
}
161167
}
162168

163169
ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => {
@@ -263,14 +269,19 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
263269
}
264270
ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx),
265271
ty::ty_struct(did, ref substs) => {
266-
// Only create the named struct, but don't fill it in. We fill it
267-
// in *after* placing it into the type cache. This prevents
268-
// infinite recursion with recursive struct types.
269-
270-
common::T_named_struct(llvm_type_name(cx,
271-
a_struct,
272-
did,
273-
/*bad*/ copy substs.tps))
272+
if ty::type_is_simd(cx.tcx, t) {
273+
let et = ty::simd_type(cx.tcx, t);
274+
let n = ty::simd_size(cx.tcx, t);
275+
T_vector(type_of(cx, et), n)
276+
} else {
277+
// Only create the named struct, but don't fill it in. We fill it
278+
// in *after* placing it into the type cache. This prevents
279+
// infinite recursion with recursive struct types.
280+
T_named_struct(llvm_type_name(cx,
281+
a_struct,
282+
did,
283+
/*bad*/ copy substs.tps))
284+
}
274285
}
275286
ty::ty_self(*) => cx.tcx.sess.unimpl(~"type_of: ty_self"),
276287
ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"),
@@ -289,10 +300,12 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
289300
}
290301

291302
ty::ty_struct(did, _) => {
292-
let repr = adt::represent_type(cx, t);
293-
let packed = ty::lookup_packed(cx.tcx, did);
294-
common::set_struct_body(llty, adt::fields_of(cx, repr),
295-
packed);
303+
if !ty::type_is_simd(cx.tcx, t) {
304+
let repr = adt::represent_type(cx, t);
305+
let packed = ty::lookup_packed(cx.tcx, did);
306+
common::set_struct_body(llty, adt::fields_of(cx, repr),
307+
packed);
308+
}
296309
}
297310
_ => ()
298311
}

trunk/src/librustc/middle/ty.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,13 @@ pub fn type_is_sequence(ty: t) -> bool {
15671567
}
15681568
}
15691569

1570+
pub fn type_is_simd(cx: ctxt, ty: t) -> bool {
1571+
match get(ty).sty {
1572+
ty_struct(did, _) => lookup_simd(cx, did),
1573+
_ => false
1574+
}
1575+
}
1576+
15701577
pub fn type_is_str(ty: t) -> bool {
15711578
match get(ty).sty {
15721579
ty_estr(_) => true,
@@ -1583,6 +1590,26 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t {
15831590
}
15841591
}
15851592

1593+
pub fn simd_type(cx: ctxt, ty: t) -> t {
1594+
match get(ty).sty {
1595+
ty_struct(did, ref substs) => {
1596+
let fields = lookup_struct_fields(cx, did);
1597+
lookup_field_type(cx, did, fields[0].id, substs)
1598+
}
1599+
_ => fail!(~"simd_type called on invalid type")
1600+
}
1601+
}
1602+
1603+
pub fn simd_size(cx: ctxt, ty: t) -> uint {
1604+
match get(ty).sty {
1605+
ty_struct(did, _) => {
1606+
let fields = lookup_struct_fields(cx, did);
1607+
fields.len()
1608+
}
1609+
_ => fail!(~"simd_size called on invalid type")
1610+
}
1611+
}
1612+
15861613
pub fn get_element_type(ty: t, i: uint) -> t {
15871614
match get(ty).sty {
15881615
ty_tup(ref ts) => return ts[i],
@@ -2381,6 +2408,14 @@ pub fn type_is_signed(ty: t) -> bool {
23812408
}
23822409
}
23832410
2411+
pub fn type_is_machine(ty: t) -> bool {
2412+
match get(ty).sty {
2413+
ty_int(ast::ty_i) | ty_uint(ast::ty_u) | ty_float(ast::ty_f) => false,
2414+
ty_int(*) | ty_uint(*) | ty_float(*) => true,
2415+
_ => false
2416+
}
2417+
}
2418+
23842419
// Whether a type is Plain Old Data -- meaning it does not contain pointers
23852420
// that the cycle collector might care about.
23862421
pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
@@ -3896,7 +3931,7 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
38963931
attrs: ref attrs,
38973932
_
38983933
}, _)) => attr::attrs_contains_name(*attrs, attr),
3899-
_ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item",
3934+
_ => tcx.sess.bug(fmt!("has_attr: %? is not an item",
39003935
did))
39013936
}
39023937
} else {
@@ -3908,11 +3943,16 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
39083943
}
39093944
}
39103945
3911-
/// Determine whether an item is annotated with `#[packed]` or not
3946+
/// Determine whether an item is annotated with `#[packed]`
39123947
pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
39133948
has_attr(tcx, did, "packed")
39143949
}
39153950
3951+
/// Determine whether an item is annotated with `#[simd]`
3952+
pub fn lookup_simd(tcx: ctxt, did: def_id) -> bool {
3953+
has_attr(tcx, did, "simd")
3954+
}
3955+
39163956
// Look up a field ID, whether or not it's local
39173957
// Takes a list of type substs in case the struct is generic
39183958
pub fn lookup_field_type(tcx: ctxt,

trunk/src/librustc/middle/typeck/check/mod.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,14 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt,
561561
}
562562

563563
pub fn check_struct(ccx: @mut CrateCtxt, id: ast::node_id, span: span) {
564+
let tcx = ccx.tcx;
565+
564566
// Check that the class is instantiable
565-
check_instantiable(ccx.tcx, span, id);
567+
check_instantiable(tcx, span, id);
568+
569+
if ty::lookup_simd(tcx, local_def(id)) {
570+
check_simd(tcx, span, id);
571+
}
566572
}
567573

568574
pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
@@ -3034,6 +3040,35 @@ pub fn check_instantiable(tcx: ty::ctxt,
30343040
}
30353041
}
30363042

3043+
pub fn check_simd(tcx: ty::ctxt, sp: span, id: ast::node_id) {
3044+
let t = ty::node_id_to_type(tcx, id);
3045+
if ty::type_needs_subst(t) {
3046+
tcx.sess.span_err(sp, "SIMD vector cannot be generic");
3047+
return;
3048+
}
3049+
match ty::get(t).sty {
3050+
ty::ty_struct(did, ref substs) => {
3051+
let fields = ty::lookup_struct_fields(tcx, did);
3052+
if fields.is_empty() {
3053+
tcx.sess.span_err(sp, "SIMD vector cannot be empty");
3054+
return;
3055+
}
3056+
let e = ty::lookup_field_type(tcx, did, fields[0].id, substs);
3057+
if !vec::all(fields,
3058+
|f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
3059+
tcx.sess.span_err(sp, "SIMD vector should be homogeneous");
3060+
return;
3061+
}
3062+
if !ty::type_is_machine(e) {
3063+
tcx.sess.span_err(sp, "SIMD vector element type should be \
3064+
machine type");
3065+
return;
3066+
}
3067+
}
3068+
_ => ()
3069+
}
3070+
}
3071+
30373072
pub fn check_enum_variants(ccx: @mut CrateCtxt,
30383073
sp: span,
30393074
vs: &[ast::variant],

trunk/src/libstd/fileinput.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ struct FileInput_ {
145145
// "self.fi." -> "self." and renaming FileInput_. Documentation above
146146
// will likely have to be updated to use `let mut in = ...`.
147147
pub struct FileInput {
148-
priv mut fi: FileInput_
148+
priv fi: @mut FileInput_
149149
}
150150

151151
impl FileInput {
@@ -170,7 +170,7 @@ impl FileInput {
170170
pub fn from_vec_raw(files: ~[Option<Path>])
171171
-> FileInput {
172172
FileInput{
173-
fi: FileInput_ {
173+
fi: @mut FileInput_ {
174174
files: files,
175175
current_reader: None,
176176
state: FileInputState {

0 commit comments

Comments
 (0)