Skip to content

SIMD for Rust #5841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcore/num/int-template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) {
/// Computes the bitwise complement
#[inline(always)]
pub fn compl(i: T) -> T {
-1 as T ^ i
i ^ (-1 as T)
}

/// Computes the absolute value
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ fn enc_sty(w: @io::Writer, cx: @ctxt, st: ty::sty) {
w.write_char('v');
enc_vstore(w, cx, v);
}
ty::ty_multi(*) => {
fail!();
}
ty::ty_unboxed_vec(mt) => { w.write_char('U'); enc_mt(w, cx, mt); }
ty::ty_closure(ref f) => {
w.write_char('f');
Expand Down
20 changes: 14 additions & 6 deletions src/librustc/middle/trans/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -963,20 +963,28 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
}

pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
Index: ValueRef) {
Index: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return; }
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
count_insn(cx, "insertelement");
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname())
}
}

pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
Mask: ValueRef) {
Mask: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return; }
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
count_insn(cx, "shufflevector");
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname())
}
}

pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
unsafe {
let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts));
let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0));
ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts)))
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,12 @@ pub fn T_array(t: TypeRef, n: uint) -> TypeRef {
}
}

pub fn T_vector(t: TypeRef, n: uint) -> TypeRef {
unsafe {
return llvm::LLVMVectorType(t, n as c_uint);
}
}

// Interior vector.
pub fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef {
return T_struct(~[T_int(targ_cfg), // fill
Expand Down
8 changes: 7 additions & 1 deletion src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,7 @@ fn trans_eager_binop(bcx: block,
if ty::type_is_bot(lhs_t) { rhs_t }
else { lhs_t }
};
let is_float = ty::type_is_fp(intype);
let is_float = ty::type_uses_fp(intype);

let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs);

Expand Down Expand Up @@ -1589,6 +1589,7 @@ pub enum cast_kind {
cast_integral,
cast_float,
cast_enum,
cast_multi,
cast_other,
}

Expand All @@ -1601,6 +1602,7 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind {
ty::ty_uint(*) => cast_integral,
ty::ty_bool => cast_integral,
ty::ty_enum(*) => cast_enum,
ty::ty_multi(*) => cast_multi,
_ => cast_other
}
}
Expand Down Expand Up @@ -1662,6 +1664,10 @@ fn trans_imm_cast(bcx: block, expr: @ast::expr,
_ => ccx.sess.bug(~"translating unsupported cast.")
}
}
(cast_integral, cast_multi) |
(cast_float, cast_multi) => {
VectorSplat(bcx, ty::multi_size(t_out), llexpr)
}
_ => ccx.sess.bug(~"translating unsupported cast.")
};
return immediate_rvalue_bcx(bcx, newval, t_out);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/trans/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ pub impl Reflector {
let extra = extra + self.c_mt(mt);
self.visit(~"evec_" + name, extra)
}
ty::ty_multi(*) => {
fail!();
}
ty::ty_box(ref mt) => {
let extra = self.c_mt(mt);
self.visit(~"box", extra)
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/middle/trans/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_evec(mt, ty::vstore_fixed(size)) => {
T_array(sizing_type_of(cx, mt.ty), size)
}
ty::ty_multi(t, n) => {
T_vector(sizing_type_of(cx, t), n)
}

ty::ty_unboxed_vec(mt) => T_vec(cx, sizing_type_of(cx, mt.ty)),

Expand Down Expand Up @@ -253,6 +256,10 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
T_array(type_of(cx, mt.ty), n)
}

ty::ty_multi(t, n) => {
T_vector(type_of(cx, t), n)
}

ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store),
Expand Down
60 changes: 58 additions & 2 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ pub enum sty {
ty_box(mt),
ty_uniq(mt),
ty_evec(mt, vstore),
ty_multi(t, uint),
ty_ptr(mt),
ty_rptr(Region, mt),
ty_bare_fn(BareFnTy),
Expand Down Expand Up @@ -1009,6 +1010,9 @@ fn mk_t(cx: ctxt, st: sty) -> t {
&ty_ptr(ref m) | &ty_unboxed_vec(ref m) => {
flags |= get(m.ty).flags;
}
&ty_multi(t, _) => {
flags |= get(t).flags;
}
&ty_rptr(r, ref m) => {
flags |= rflags(r);
flags |= get(m.ty).flags;
Expand Down Expand Up @@ -1188,6 +1192,10 @@ pub fn mk_evec(cx: ctxt, tm: mt, t: vstore) -> t {
mk_t(cx, ty_evec(tm, t))
}

pub fn mk_multi(cx: ctxt, ty: t, n: uint) -> t {
mk_t(cx, ty_multi(ty, n))
}

pub fn mk_unboxed_vec(cx: ctxt, tm: mt) -> t {
mk_t(cx, ty_unboxed_vec(tm))
}
Expand Down Expand Up @@ -1274,6 +1282,9 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) {
ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_uniq(ref tm) => {
maybe_walk_ty(tm.ty, f);
}
ty_multi(t, _) => {
maybe_walk_ty(t, f);
}
ty_enum(_, ref substs) | ty_struct(_, ref substs) |
ty_trait(_, ref substs, _, _) => {
for (*substs).tps.each |subty| { maybe_walk_ty(*subty, f); }
Expand Down Expand Up @@ -1337,6 +1348,9 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
ty_evec(ref tm, vst) => {
ty_evec(mt {ty: fldop(tm.ty), mutbl: tm.mutbl}, vst)
}
ty_multi(t, n) => {
ty_multi(fldop(t), n)
}
ty_enum(tid, ref substs) => {
ty_enum(tid, fold_substs(substs, fldop))
}
Expand Down Expand Up @@ -1567,6 +1581,13 @@ pub fn type_is_sequence(ty: t) -> bool {
}
}

pub fn type_is_multi(ty: t) -> bool {
match get(ty).sty {
ty_multi(*) => true,
_ => false
}
}

pub fn type_is_str(ty: t) -> bool {
match get(ty).sty {
ty_estr(_) => true,
Expand All @@ -1583,6 +1604,20 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t {
}
}

pub fn multi_type(ty: t) -> t {
match get(ty).sty {
ty_multi(t, _) => t,
_ => fail!(~"multi_type called on invalid type")
}
}

pub fn multi_size(ty: t) -> uint {
match get(ty).sty {
ty_multi(_, n) => n,
_ => fail!(~"multi_size called on invalid type")
}
}

pub fn get_element_type(ty: t, i: uint) -> t {
match get(ty).sty {
ty_tup(ref ts) => return ts[i],
Expand Down Expand Up @@ -1666,8 +1701,8 @@ pub fn type_is_scalar(ty: t) -> bool {
}

pub fn type_is_immediate(ty: t) -> bool {
return type_is_scalar(ty) || type_is_boxed(ty) ||
type_is_unique(ty) || type_is_region_ptr(ty);
return type_is_scalar(ty) || type_is_multi(ty) ||
type_is_boxed(ty) || type_is_unique(ty) || type_is_region_ptr(ty);
}

pub fn type_needs_drop(cx: ctxt, ty: t) -> bool {
Expand Down Expand Up @@ -2025,6 +2060,10 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
TC_NONE
}

ty_multi(t, _) => {
tc_ty(cx, t, cache)
}

ty_struct(did, ref substs) => {
let flds = struct_fields(cx, did, substs);
let mut res = flds.foldl(
Expand Down Expand Up @@ -2236,6 +2275,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
ty_opaque_box |
ty_opaque_closure_ptr(_) |
ty_evec(_, _) |
ty_multi(_, _) |
ty_unboxed_vec(_) => {
false
}
Expand Down Expand Up @@ -2370,6 +2410,14 @@ pub fn type_is_fp(ty: t) -> bool {
}
}

pub fn type_uses_fp(ty: t) -> bool {
match get(ty).sty {
ty_infer(FloatVar(_)) | ty_float(_) => true,
ty_multi(t, _) => type_uses_fp(t),
_ => false
}
}

pub fn type_is_numeric(ty: t) -> bool {
return type_is_integral(ty) || type_is_fp(ty);
}
Expand Down Expand Up @@ -2412,6 +2460,9 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
ty_evec(ref mt, vstore_fixed(_)) | ty_unboxed_vec(ref mt) => {
result = type_is_pod(cx, mt.ty);
}
ty_multi(t, _) => {
result = type_is_pod(cx, t);
}
ty_param(_) => result = false,
ty_opaque_closure_ptr(_) => result = true,
ty_struct(did, ref substs) => {
Expand Down Expand Up @@ -2657,6 +2708,9 @@ impl to_bytes::IterBytes for sty {
ty_tup(ref ts) =>
to_bytes::iter_bytes_2(&10u8, ts, lsb0, f),

ty_multi(ref t, ref n) =>
to_bytes::iter_bytes_3(&11u8, t, n, lsb0, f),

ty_bare_fn(ref ft) =>
to_bytes::iter_bytes_2(&12u8, ft, lsb0, f),

Expand Down Expand Up @@ -3315,6 +3369,7 @@ pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
ty_box(_) => ~"@-ptr",
ty_uniq(_) => ~"~-ptr",
ty_evec(_, _) => ~"vector",
ty_multi(_, _) => ~"SIMD vector",
ty_unboxed_vec(_) => ~"unboxed vector",
ty_ptr(_) => ~"*-ptr",
ty_rptr(_, _) => ~"&-ptr",
Expand Down Expand Up @@ -4096,6 +4151,7 @@ pub fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool {
ty_bool => tycat_bool,
ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
ty_multi(ty, _) => tycat(ty),
ty_tup(_) | ty_enum(_, _) => tycat_struct,
ty_bot => tycat_bot,
_ => tycat_other
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,9 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
}
}
}
ast::ty_multi(t, n) => {
ty::mk_multi(tcx, ast_ty_to_ty(self, rscope, t), n)
}
ast::ty_infer => {
// ty_infer should only appear as the type of arguments or return
// values in a fn_expr, or as the type of local variables. Both of
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,8 @@ pub impl<'self> LookupContext<'self> {
ty_infer(IntVar(_)) |
ty_infer(FloatVar(_)) |
ty_self(_) | ty_param(*) | ty_nil | ty_bot | ty_bool |
ty_int(*) | ty_uint(*) |
ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) |
ty_int(*) | ty_uint(*) | ty_float(*) | ty_multi(*) |
ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) |
ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => {
self.search_for_some_kind_of_autorefd_method(
AutoPtr, autoderefs, [m_const, m_imm, m_mutbl],
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2636,6 +2636,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
if type_is_c_like_enum(fcx,expr.span,t_e)
&& t_1_is_scalar {
/* this case is allowed */
} else if ty::type_is_multi(t_1) {
demand::suptype(fcx, e.span,
ty::multi_type(t_1), t_e);
} else if type_is_region_ptr(fcx, expr.span, t_e) &&
type_is_unsafe_ptr(fcx, expr.span, t_1) {

Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use middle::ty::{lookup_item_type, subst};
use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err};
use middle::ty::{ty_estr, ty_evec, ty_float, ty_infer, ty_int, ty_nil};
use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr};
use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup, ty_multi};
use middle::ty::{ty_type, ty_uint, ty_uniq, ty_bare_fn, ty_closure};
use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec};
use middle::ty::{type_is_ty_var};
Expand Down Expand Up @@ -90,8 +90,8 @@ pub fn get_base_type(inference_context: @mut InferCtxt,
ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | ty_float(*) |
ty_estr(*) | ty_evec(*) | ty_bare_fn(*) | ty_closure(*) | ty_tup(*) |
ty_infer(*) | ty_param(*) | ty_self(*) | ty_type | ty_opaque_box |
ty_opaque_closure_ptr(*) | ty_unboxed_vec(*) | ty_err | ty_box(_) |
ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => {
ty_opaque_closure_ptr(*) | ty_unboxed_vec(*) | ty_multi(*) | ty_err |
ty_box(*) | ty_uniq(*) | ty_ptr(*) | ty_rptr(*) => {
debug!("(getting base type) no base type; found %?",
get(original_type).sty);
None
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use middle::ty::{br_fresh, ctxt, field, method};
use middle::ty::{mt, t, param_bound, param_ty};
use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region,
re_empty};
use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum};
use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum, ty_multi};
use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_bare_fn, ty_closure};
use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq};
Expand Down Expand Up @@ -457,6 +457,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
vstore_ty_to_str(cx, mt, vs)
}
ty_estr(vs) => fmt!("%s%s", vstore_to_str(cx, vs), ~"str"),
ty_multi(t, n) => fmt!("%s^%u", ty_to_str(cx, t), n),
ty_opaque_box => ~"@?",
ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"closure&",
ty_opaque_closure_ptr(ast::ManagedSigil) => ~"closure@",
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,7 @@ pub enum ty_ {
ty_uniq(mt),
ty_vec(mt),
ty_fixed_length_vec(mt, @expr),
ty_multi(@Ty, uint),
ty_ptr(mt),
ty_rptr(Option<@Lifetime>, mt),
ty_closure(@TyClosure),
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
fld.fold_expr(e)
)
}
ty_multi(t, n) => ty_multi(fld.fold_ty(t), n),
ty_mac(ref mac) => ty_mac(fold_mac(*mac))
}
}
Expand Down
Loading