From 0ed4495ac4c262a8361dded6900e4e69b1faaee1 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Wed, 8 May 2013 02:09:19 +0900 Subject: [PATCH] Generate LLVM SIMD vector types --- src/librustc/middle/trans/type_of.rs | 43 ++++++++++++++++++---------- src/librustc/middle/ty.rs | 27 +++++++++++++++++ 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index fc27c11c06f..b8e0b58f866 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -155,9 +155,15 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { } ty::ty_struct(did, _) => { - let repr = adt::represent_type(cx, t); - let packed = ty::lookup_packed(cx.tcx, did); - T_struct(adt::sizing_fields_of(cx, repr), packed) + if ty::type_is_simd(cx.tcx, t) { + let et = ty::simd_type(cx.tcx, t); + let n = ty::simd_size(cx.tcx, t); + T_vector(type_of(cx, et), n) + } else { + let repr = adt::represent_type(cx, t); + let packed = ty::lookup_packed(cx.tcx, did); + T_struct(adt::sizing_fields_of(cx, repr), packed) + } } 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 { } ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx), ty::ty_struct(did, ref substs) => { - // Only create the named struct, but don't fill it in. We fill it - // in *after* placing it into the type cache. This prevents - // infinite recursion with recursive struct types. - - common::T_named_struct(llvm_type_name(cx, - a_struct, - did, - /*bad*/ copy substs.tps)) + if ty::type_is_simd(cx.tcx, t) { + let et = ty::simd_type(cx.tcx, t); + let n = ty::simd_size(cx.tcx, t); + T_vector(type_of(cx, et), n) + } else { + // Only create the named struct, but don't fill it in. We fill it + // in *after* placing it into the type cache. This prevents + // infinite recursion with recursive struct types. + T_named_struct(llvm_type_name(cx, + a_struct, + did, + /*bad*/ copy substs.tps)) + } } ty::ty_self(*) => cx.tcx.sess.unimpl(~"type_of: ty_self"), 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 { } ty::ty_struct(did, _) => { - let repr = adt::represent_type(cx, t); - let packed = ty::lookup_packed(cx.tcx, did); - common::set_struct_body(llty, adt::fields_of(cx, repr), - packed); + if !ty::type_is_simd(cx.tcx, t) { + let repr = adt::represent_type(cx, t); + let packed = ty::lookup_packed(cx.tcx, did); + common::set_struct_body(llty, adt::fields_of(cx, repr), + packed); + } } _ => () } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 2b46497b77d..4d1d271698c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1567,6 +1567,13 @@ pub fn type_is_sequence(ty: t) -> bool { } } +pub fn type_is_simd(cx: ctxt, ty: t) -> bool { + match get(ty).sty { + ty_struct(did, _) => lookup_simd(cx, did), + _ => false + } +} + pub fn type_is_str(ty: t) -> bool { match get(ty).sty { ty_estr(_) => true, @@ -1583,6 +1590,26 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t { } } +pub fn simd_type(cx: ctxt, ty: t) -> t { + match get(ty).sty { + ty_struct(did, ref substs) => { + let fields = lookup_struct_fields(cx, did); + lookup_field_type(cx, did, fields[0].id, substs) + } + _ => fail!(~"simd_type called on invalid type") + } +} + +pub fn simd_size(cx: ctxt, ty: t) -> uint { + match get(ty).sty { + ty_struct(did, _) => { + let fields = lookup_struct_fields(cx, did); + fields.len() + } + _ => fail!(~"simd_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],