Skip to content

Commit 6bdd1e5

Browse files
committed
Auto merge of #27169 - huonw:simd, r=<try>
This implements rust-lang/rfcs#1199 (except for doing all the platform intrinsics). Things remaining for SIMD (not necessarily in this PR): - [x] I (@huonw) am signed up to ensure the compiler matches the RFC, when it lands - [x] the platform specific intrinsics aren't properly type checked at the moment (LLVM will throw a "random" assertion) - [ ] there's a lot of useful intrinsics that are missing, including whole platforms (mips, powerpc) - [ ] the target-feature `cfg` detection/adding is not so great at the moment - [x] I think the platform specific intrinsics should go in their own `extern` ABI (i.e. not `"rust-intrinsic"`) (I'm adjusting the RFC to reflect the latter.) I think it would be very nice for this to land without requiring the RFC to land first, because of the first point, and because this is the only way for any further work to happen/be experimented with, without requiring people to build/install/multirust a compiler from a custom branch. r? @alexcrichton
2 parents e822a18 + 3d5cb38 commit 6bdd1e5

File tree

77 files changed

+2984
-1031
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+2984
-1031
lines changed

mk/crates.mk

+4-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ TARGET_CRATES := libc std flate arena term \
5656
alloc_system
5757
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
5858
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
59-
rustc_data_structures
59+
rustc_data_structures rustc_platform_intrinsics
6060
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
6161
TOOLS := compiletest rustdoc rustc rustbook error-index-generator
6262

@@ -74,15 +74,16 @@ DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_bo
7474
rustc_trans rustc_privacy rustc_lint
7575

7676
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
77-
log syntax serialize rustc_llvm
78-
DEPS_rustc_typeck := rustc syntax
77+
log syntax serialize rustc_llvm rustc_platform_intrinsics
78+
DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics
7979
DEPS_rustc_borrowck := rustc log graphviz syntax
8080
DEPS_rustc_resolve := rustc log syntax
8181
DEPS_rustc_privacy := rustc log syntax
8282
DEPS_rustc_lint := rustc log syntax
8383
DEPS_rustc := syntax flate arena serialize getopts rbml \
8484
log graphviz rustc_llvm rustc_back rustc_data_structures
8585
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
86+
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
8687
DEPS_rustc_back := std syntax rustc_llvm flate log libc
8788
DEPS_rustc_data_structures := std log serialize
8889
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \

src/libcore/lib.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@
7878
#![feature(optin_builtin_traits)]
7979
#![feature(reflect)]
8080
#![feature(rustc_attrs)]
81-
#![feature(simd)]
81+
#![cfg_attr(stage0, feature(simd))]
82+
#![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))]
8283
#![feature(staged_api)]
8384
#![feature(unboxed_closures)]
8485

@@ -150,7 +151,13 @@ pub mod iter;
150151
pub mod option;
151152
pub mod raw;
152153
pub mod result;
154+
155+
#[cfg(stage0)]
156+
#[path = "simd_old.rs"]
157+
pub mod simd;
158+
#[cfg(not(stage0))]
153159
pub mod simd;
160+
154161
pub mod slice;
155162
pub mod str;
156163
pub mod hash;

src/libcore/simd.rs

+62-24
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,12 @@
1010

1111
//! SIMD vectors.
1212
//!
13-
//! These types can be used for accessing basic SIMD operations. Each of them
14-
//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div,
15-
//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently
13+
//! These types can be used for accessing basic SIMD operations. Currently
1614
//! comparison operators are not implemented. To use SSE3+, you must enable
1715
//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
1816
//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
1917
//! provided beyond this module.
2018
//!
21-
//! ```rust
22-
//! #![feature(core_simd)]
23-
//!
24-
//! fn main() {
25-
//! use std::simd::f32x4;
26-
//! let a = f32x4(40.0, 41.0, 42.0, 43.0);
27-
//! let b = f32x4(1.0, 1.1, 3.4, 9.8);
28-
//! println!("{:?}", a + b);
29-
//! }
30-
//! ```
31-
//!
3219
//! # Stability Note
3320
//!
3421
//! These are all experimental. The interface may change entirely, without
@@ -37,64 +24,115 @@
3724
#![unstable(feature = "core_simd",
3825
reason = "needs an RFC to flesh out the design",
3926
issue = "27731")]
27+
#![deprecated(since = "1.3.0",
28+
reason = "use the external `simd` crate instead")]
4029

4130
#![allow(non_camel_case_types)]
4231
#![allow(missing_docs)]
32+
#![allow(deprecated)]
33+
34+
use ops::{Add, Sub, Mul, Div, Shl, Shr, BitAnd, BitOr, BitXor};
35+
36+
macro_rules! argh {
37+
() => {
38+
extern "platform-intrinsic" {
39+
fn simd_add<T>(x: T, y: T) -> T;
40+
fn simd_sub<T>(x: T, y: T) -> T;
41+
fn simd_mul<T>(x: T, y: T) -> T;
42+
fn simd_div<T>(x: T, y: T) -> T;
43+
fn simd_shl<T>(x: T, y: T) -> T;
44+
fn simd_shr<T>(x: T, y: T) -> T;
45+
fn simd_and<T>(x: T, y: T) -> T;
46+
fn simd_or<T>(x: T, y: T) -> T;
47+
fn simd_xor<T>(x: T, y: T) -> T;
48+
}
49+
}
50+
}
51+
argh!();
4352

44-
#[simd]
53+
#[repr(simd)]
4554
#[derive(Copy, Clone, Debug)]
4655
#[repr(C)]
4756
pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
4857
pub i8, pub i8, pub i8, pub i8,
4958
pub i8, pub i8, pub i8, pub i8,
5059
pub i8, pub i8, pub i8, pub i8);
5160

52-
#[simd]
61+
#[repr(simd)]
5362
#[derive(Copy, Clone, Debug)]
5463
#[repr(C)]
5564
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
5665
pub i16, pub i16, pub i16, pub i16);
5766

58-
#[simd]
67+
#[repr(simd)]
5968
#[derive(Copy, Clone, Debug)]
6069
#[repr(C)]
6170
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
6271

63-
#[simd]
72+
#[repr(simd)]
6473
#[derive(Copy, Clone, Debug)]
6574
#[repr(C)]
6675
pub struct i64x2(pub i64, pub i64);
6776

68-
#[simd]
77+
#[repr(simd)]
6978
#[derive(Copy, Clone, Debug)]
7079
#[repr(C)]
7180
pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
7281
pub u8, pub u8, pub u8, pub u8,
7382
pub u8, pub u8, pub u8, pub u8,
7483
pub u8, pub u8, pub u8, pub u8);
7584

76-
#[simd]
85+
#[repr(simd)]
7786
#[derive(Copy, Clone, Debug)]
7887
#[repr(C)]
7988
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
8089
pub u16, pub u16, pub u16, pub u16);
8190

82-
#[simd]
91+
#[repr(simd)]
8392
#[derive(Copy, Clone, Debug)]
8493
#[repr(C)]
8594
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
8695

87-
#[simd]
96+
#[repr(simd)]
8897
#[derive(Copy, Clone, Debug)]
8998
#[repr(C)]
9099
pub struct u64x2(pub u64, pub u64);
91100

92-
#[simd]
101+
#[repr(simd)]
93102
#[derive(Copy, Clone, Debug)]
94103
#[repr(C)]
95104
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
96105

97-
#[simd]
106+
#[repr(simd)]
98107
#[derive(Copy, Clone, Debug)]
99108
#[repr(C)]
100109
pub struct f64x2(pub f64, pub f64);
110+
111+
macro_rules! impl_traits {
112+
($($trayt: ident, $method: ident, $func: ident: $($ty: ty),*;)*) => {
113+
$($(
114+
impl $trayt<$ty> for $ty {
115+
type Output = Self;
116+
fn $method(self, other: Self) -> Self {
117+
unsafe {
118+
$func(self, other)
119+
}
120+
}
121+
}
122+
)*)*
123+
}
124+
}
125+
126+
impl_traits! {
127+
Add, add, simd_add: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
128+
Sub, sub, simd_sub: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
129+
Mul, mul, simd_mul: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
130+
131+
Div, div, simd_div: f32x4, f64x2;
132+
133+
Shl, shl, simd_shl: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
134+
Shr, shr, simd_shr: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
135+
BitAnd, bitand, simd_and: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
136+
BitOr, bitor, simd_or: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
137+
BitXor, bitxor, simd_xor: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
138+
}

src/libcore/simd_old.rs

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
//! These types can be used for accessing basic SIMD operations. Each of them
14+
//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div,
15+
//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently
16+
//! comparison operators are not implemented. To use SSE3+, you must enable
17+
//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
18+
//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
19+
//! provided beyond this module.
20+
//!
21+
//! ```rust
22+
//! # #![feature(core_simd)]
23+
//! fn main() {
24+
//! use std::simd::f32x4;
25+
//! let a = f32x4(40.0, 41.0, 42.0, 43.0);
26+
//! let b = f32x4(1.0, 1.1, 3.4, 9.8);
27+
//! println!("{:?}", a + b);
28+
//! }
29+
//! ```
30+
//!
31+
//! # Stability Note
32+
//!
33+
//! These are all experimental. The interface may change entirely, without
34+
//! warning.
35+
36+
#![unstable(feature = "core_simd",
37+
reason = "needs an RFC to flesh out the design")]
38+
39+
#![allow(non_camel_case_types)]
40+
#![allow(missing_docs)]
41+
42+
#[simd]
43+
#[derive(Copy, Clone, Debug)]
44+
#[repr(C)]
45+
pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
46+
pub i8, pub i8, pub i8, pub i8,
47+
pub i8, pub i8, pub i8, pub i8,
48+
pub i8, pub i8, pub i8, pub i8);
49+
50+
#[simd]
51+
#[derive(Copy, Clone, Debug)]
52+
#[repr(C)]
53+
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
54+
pub i16, pub i16, pub i16, pub i16);
55+
56+
#[simd]
57+
#[derive(Copy, Clone, Debug)]
58+
#[repr(C)]
59+
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
60+
61+
#[simd]
62+
#[derive(Copy, Clone, Debug)]
63+
#[repr(C)]
64+
pub struct i64x2(pub i64, pub i64);
65+
66+
#[simd]
67+
#[derive(Copy, Clone, Debug)]
68+
#[repr(C)]
69+
pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
70+
pub u8, pub u8, pub u8, pub u8,
71+
pub u8, pub u8, pub u8, pub u8,
72+
pub u8, pub u8, pub u8, pub u8);
73+
74+
#[simd]
75+
#[derive(Copy, Clone, Debug)]
76+
#[repr(C)]
77+
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
78+
pub u16, pub u16, pub u16, pub u16);
79+
80+
#[simd]
81+
#[derive(Copy, Clone, Debug)]
82+
#[repr(C)]
83+
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
84+
85+
#[simd]
86+
#[derive(Copy, Clone, Debug)]
87+
#[repr(C)]
88+
pub struct u64x2(pub u64, pub u64);
89+
90+
#[simd]
91+
#[derive(Copy, Clone, Debug)]
92+
#[repr(C)]
93+
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
94+
95+
#[simd]
96+
#[derive(Copy, Clone, Debug)]
97+
#[repr(C)]
98+
pub struct f64x2(pub f64, pub f64);

src/librustc/metadata/creader.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
704704
}
705705

706706
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
707-
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
707+
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic || fm.abi == abi::PlatformIntrinsic {
708708
return;
709709
}
710710

src/librustc/metadata/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
15011501
encode_family(rbml_w, FN_FAMILY);
15021502
encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id);
15031503
encode_name(rbml_w, nitem.ident.name);
1504-
if abi == abi::RustIntrinsic {
1504+
if abi == abi::RustIntrinsic || abi == abi::PlatformIntrinsic {
15051505
encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem));
15061506
}
15071507
encode_attributes(rbml_w, &*nitem.attrs);

src/librustc/middle/ty.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3312,10 +3312,10 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
33123312
variants: Vec<VariantDefData<'tcx, 'container>>) -> Self {
33133313
let mut flags = AdtFlags::NO_ADT_FLAGS;
33143314
let attrs = tcx.get_attrs(did);
3315-
if attrs.iter().any(|item| item.check_name("fundamental")) {
3315+
if attr::contains_name(&attrs, "fundamental") {
33163316
flags = flags | AdtFlags::IS_FUNDAMENTAL;
33173317
}
3318-
if attrs.iter().any(|item| item.check_name("simd")) {
3318+
if tcx.lookup_simd(did) {
33193319
flags = flags | AdtFlags::IS_SIMD;
33203320
}
33213321
if Some(did) == tcx.lang_items.phantom_data() {
@@ -6116,6 +6116,7 @@ impl<'tcx> ctxt<'tcx> {
61166116
/// Determine whether an item is annotated with `#[simd]`
61176117
pub fn lookup_simd(&self, did: DefId) -> bool {
61186118
self.has_attr(did, "simd")
6119+
|| self.lookup_repr_hints(did).contains(&attr::ReprSimd)
61196120
}
61206121

61216122
/// Obtain the representation annotation for a struct definition.

src/librustc_driver/driver.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
406406
//
407407
// baz! should not use this definition unless foo is enabled.
408408

409-
krate = time(time_passes, "configuration 1", move ||
410-
syntax::config::strip_unconfigured_items(sess.diagnostic(), krate));
409+
let mut feature_gated_cfgs = vec![];
410+
krate = time(time_passes, "configuration 1", ||
411+
syntax::config::strip_unconfigured_items(sess.diagnostic(), krate,
412+
&mut feature_gated_cfgs));
411413

412414
*sess.crate_types.borrow_mut() =
413415
collect_crate_types(sess, &krate.attrs);
@@ -511,6 +513,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
511513
cfg,
512514
macros,
513515
syntax_exts,
516+
&mut feature_gated_cfgs,
514517
krate);
515518
if cfg!(windows) {
516519
env::set_var("PATH", &_old_path);
@@ -536,7 +539,17 @@ pub fn phase_2_configure_and_expand(sess: &Session,
536539

537540
// strip again, in case expansion added anything with a #[cfg].
538541
krate = time(time_passes, "configuration 2", ||
539-
syntax::config::strip_unconfigured_items(sess.diagnostic(), krate));
542+
syntax::config::strip_unconfigured_items(sess.diagnostic(), krate,
543+
&mut feature_gated_cfgs));
544+
545+
time(time_passes, "gated configuration checking", || {
546+
let features = sess.features.borrow();
547+
feature_gated_cfgs.sort();
548+
feature_gated_cfgs.dedup();
549+
for cfg in &feature_gated_cfgs {
550+
cfg.check_and_emit(sess.diagnostic(), &features);
551+
}
552+
});
540553

541554
krate = time(time_passes, "maybe building test harness", ||
542555
syntax::test::modify_for_testing(&sess.parse_sess,

0 commit comments

Comments
 (0)