diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-08-14 19:18:24 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-14 19:18:24 -0400 |
commit | 40d24bb085a1a0bd11f7cf4dd87c52de529302ca (patch) | |
tree | 79a015d785f110b572fad85cd7aed70e3f50b260 | |
parent | bb6a1205a0e81271bf90aec33d33e2e3ca0ae7d1 (diff) | |
parent | 6e7d9bebd8c95a8ca7088cf02c17aea811d20783 (diff) |
Auto merge of #1366 - gnzlbg:vec, r=emiliov0.38.0
Map vector types to arrays and pass them by value
This PR maps vector types to arrays and passes them by value (that is, they are passed to C as `[T; N]`. This already allows defining them as a blacklisted opaque type, such that the user can provide its own definition from e.g. `std::arch`.
A subsequent PR should map vector types to unit structs with a private member:
```rust
#[repr(align(16))] pub struct __m128([f32; 4]);
```
to make their alignment at least be correct. This should allow transmuting `std::arch` types to these types properly.
Once that is done, we probably want to detect the canonical vector types (e.g. `__m128`) and pull in the type from `std`/`core`::arch instead.
-rw-r--r-- | src/codegen/impl_debug.rs | 9 | ||||
-rw-r--r-- | src/codegen/impl_partialeq.rs | 7 | ||||
-rw-r--r-- | src/codegen/mod.rs | 3 | ||||
-rw-r--r-- | src/ir/analysis/derive_copy.rs | 1 | ||||
-rw-r--r-- | src/ir/analysis/derive_debug.rs | 1 | ||||
-rw-r--r-- | src/ir/analysis/derive_default.rs | 1 | ||||
-rw-r--r-- | src/ir/analysis/derive_hash.rs | 12 | ||||
-rw-r--r-- | src/ir/analysis/derive_partialeq_or_partialord.rs | 9 | ||||
-rw-r--r-- | src/ir/analysis/has_float.rs | 8 | ||||
-rw-r--r-- | src/ir/analysis/has_type_param_in_array.rs | 1 | ||||
-rw-r--r-- | src/ir/analysis/sizedness.rs | 4 | ||||
-rw-r--r-- | src/ir/ty.rs | 22 | ||||
-rw-r--r-- | tests/expectations/tests/vector.rs | 16 | ||||
-rw-r--r-- | tests/headers/vector.hpp | 6 |
14 files changed, 89 insertions, 11 deletions
diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index ab934ed6..0842d849 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -197,6 +197,15 @@ impl<'a> ImplDebug<'a> for Item { )) } } + TypeKind::Vector(_, len) => { + let self_ids = 0..len; + Some(( + format!("{}({{}})", name), + vec![quote! { + #(format!("{:?}", self.#self_ids)),* + }] + )) + } TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs index a05c65e7..66565db6 100644 --- a/src/codegen/impl_partialeq.rs +++ b/src/codegen/impl_partialeq.rs @@ -115,6 +115,13 @@ fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens &self. #name_ident [..] == &other. #name_ident [..] } }, + TypeKind::Vector(_, len) => { + let self_ids = 0..len; + let other_ids = 0..len; + quote! { + #(self.#self_ids == other.#other_ids &&)* true + } + }, TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index cdf0134a..f596ddda 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -595,6 +595,7 @@ impl CodeGenerator for Type { TypeKind::Float(..) | TypeKind::Complex(..) | TypeKind::Array(..) | + TypeKind::Vector(..) | TypeKind::Pointer(..) | TypeKind::BlockPointer | TypeKind::Reference(..) | @@ -3050,7 +3051,7 @@ impl TryToRustTy for Type { ::#prefix::option::Option<#ty> }) } - TypeKind::Array(item, len) => { + TypeKind::Array(item, len) | TypeKind::Vector(item, len) => { let ty = item.try_to_rust_ty(ctx, &())?; Ok(quote! { [ #ty ; #len ] diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 1e8dc819..abb25174 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -167,6 +167,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { TypeKind::NullPtr | TypeKind::Int(..) | TypeKind::Float(..) | + TypeKind::Vector(..) | TypeKind::Complex(..) | TypeKind::Function(..) | TypeKind::Enum(..) | diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index b191d37d..b0d70f15 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -182,6 +182,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::Function(..) | TypeKind::Enum(..) | TypeKind::Reference(..) | + TypeKind::Vector(..) | TypeKind::BlockPointer | TypeKind::TypeParam | TypeKind::UnresolvedTypeRef(..) | diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index e319166d..a43d7737 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -204,6 +204,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { TypeKind::Function(..) | TypeKind::Int(..) | TypeKind::Float(..) | + TypeKind::Vector(..) | TypeKind::Complex(..) => { trace!(" simple type that can always derive Default"); ConstrainResult::Same diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index c23a891e..fe56ed7c 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -202,6 +202,18 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { self.insert(id) } } + TypeKind::Vector(t, len) => { + if self.cannot_derive_hash.contains(&t.into()) { + trace!( + " vectors of T for which we cannot derive Hash \ + also cannot derive Hash" + ); + return self.insert(id); + } + assert_ne!(len, 0, "vectors cannot have zero length"); + trace!(" vector can derive Hash"); + ConstrainResult::Same + } TypeKind::Pointer(inner) => { let inner_type = diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs index cebdceef..23d55c13 100644 --- a/src/ir/analysis/derive_partialeq_or_partialord.rs +++ b/src/ir/analysis/derive_partialeq_or_partialord.rs @@ -148,7 +148,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { } match *ty.kind() { - // Handle the simple cases. These can derive partialeq without further + // Handle the simple cases. These can derive partialeq/partialord without further // information. TypeKind::Void | TypeKind::NullPtr | @@ -199,6 +199,13 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { return CanDerive::ArrayTooLarge; } } + TypeKind::Vector(..) => { + // FIXME: vectors always can derive PartialEq, but they should + // not derive PartialOrd: + // https://github.com/rust-lang-nursery/packed_simd/issues/48 + trace!(" vectors cannot derive `PartialEq`/`PartialOrd`"); + return CanDerive::No; + } TypeKind::Pointer(inner) => { let inner_type = diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 193862c0..53e6a491 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -148,6 +148,14 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { trace!(" Array with type T that do not have float also do not have float"); ConstrainResult::Same } + TypeKind::Vector(t, _) => { + if self.has_float.contains(&t.into()) { + trace!(" Vector with type T that has float also has float"); + return self.insert(id) + } + trace!(" Vector with type T that do not have float also do not have float"); + ConstrainResult::Same + } TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index aa8d34be..b7afe043 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -130,6 +130,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::NullPtr | TypeKind::Int(..) | TypeKind::Float(..) | + TypeKind::Vector(..) | TypeKind::Complex(..) | TypeKind::Function(..) | TypeKind::Enum(..) | diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs index e82c1798..e49b2570 100644 --- a/src/ir/analysis/sizedness.rs +++ b/src/ir/analysis/sizedness.rs @@ -295,6 +295,10 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> { trace!(" arrays of > 0 elements are not zero-sized"); self.insert(id, SizednessResult::NonZeroSized) } + TypeKind::Vector(..) => { + trace!(" vectors are not zero-sized"); + self.insert(id, SizednessResult::NonZeroSized) + } TypeKind::Comp(ref info) => { trace!(" comp considers its own fields and bases"); diff --git a/src/ir/ty.rs b/src/ir/ty.rs index b805dd62..9cc097d4 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -320,6 +320,7 @@ impl Type { match self.kind { TypeKind::TypeParam | TypeKind::Array(..) | + TypeKind::Vector(..) | TypeKind::Comp(..) | TypeKind::Opaque | TypeKind::Int(..) | @@ -472,6 +473,7 @@ impl TypeKind { TypeKind::Alias(..) => "Alias", TypeKind::TemplateAlias(..) => "TemplateAlias", TypeKind::Array(..) => "Array", + TypeKind::Vector(..) => "Vector", TypeKind::Function(..) => "Function", TypeKind::Enum(..) => "Enum", TypeKind::Pointer(..) => "Pointer", @@ -565,6 +567,7 @@ impl TemplateParameters for TypeKind { TypeKind::Float(_) | TypeKind::Complex(_) | TypeKind::Array(..) | + TypeKind::Vector(..) | TypeKind::Function(_) | TypeKind::Enum(_) | TypeKind::Pointer(_) | @@ -627,6 +630,9 @@ pub enum TypeKind { /// template parameters. TemplateAlias(TypeId, Vec<TypeId>), + /// A packed vector type: element type, number of elements + Vector(TypeId, usize), + /// An array of a type and a length. Array(TypeId, usize), @@ -1148,12 +1154,15 @@ impl Type { TypeKind::Comp(complex) } - // FIXME: We stub vectors as arrays since in 99% of the cases the - // layout is going to be correct, and there's no way we can generate - // vector types properly in Rust for now. - // - // That being said, that should be fixed eventually. - CXType_Vector | + CXType_Vector => { + let inner = Item::from_ty( + ty.elem_type().as_ref().unwrap(), + location, + None, + ctx, + ).expect("Not able to resolve vector element?"); + TypeKind::Vector(inner, ty.num_elements().unwrap()) + } CXType_ConstantArray => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), @@ -1214,6 +1223,7 @@ impl Trace for Type { TypeKind::Pointer(inner) | TypeKind::Reference(inner) | TypeKind::Array(inner, _) | + TypeKind::Vector(inner, _) | TypeKind::Alias(inner) | TypeKind::ResolvedTypeRef(inner) => { tracer.visit_kind(inner.into(), EdgeKind::TypeReference); diff --git a/tests/expectations/tests/vector.rs b/tests/expectations/tests/vector.rs index 357b9ef4..86a9d737 100644 --- a/tests/expectations/tests/vector.rs +++ b/tests/expectations/tests/vector.rs @@ -1,8 +1,11 @@ /* automatically generated by rust-bindgen */ - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -32,3 +35,10 @@ fn bindgen_test_layout_foo() { ) ); } +pub type __m128 = [f32; 4usize]; +pub type __m128d = [f64; 2usize]; +pub type __m128i = [::std::os::raw::c_longlong; 2usize]; +extern "C" { + #[link_name = "\u{1}_Z3fooDv2_xDv2_d"] + pub fn foo(arg1: __m128i, arg2: __m128d) -> __m128; +} diff --git a/tests/headers/vector.hpp b/tests/headers/vector.hpp index 4707f77f..173aa022 100644 --- a/tests/headers/vector.hpp +++ b/tests/headers/vector.hpp @@ -1,3 +1,9 @@ struct foo { __attribute__((__vector_size__(1 * sizeof(long long)))) long long mMember; }; + +typedef float __m128 __attribute__ ((__vector_size__ (16))); +typedef double __m128d __attribute__((__vector_size__(16))); +typedef long long __m128i __attribute__((__vector_size__(16))); + +__m128 foo(__m128i, __m128d); |