Reorganize and refactor source tree (#324)

With RFC 2325 looking close to being accepted, I took a crack at
reorganizing this repository to being more amenable for inclusion in
libstd/libcore. My current plan is to add stdsimd as a submodule in
rust-lang/rust and then use `#[path]` to include the modules directly
into libstd/libcore.

Before this commit, however, the source code of coresimd/stdsimd
themselves were not quite ready for this. Imports wouldn't compile for
one reason or another, and the organization was also different than the
RFC itself!

In addition to moving a lot of files around, this commit has the
following major changes:

* The `cfg_feature_enabled!` macro is now renamed to
  `is_target_feature_detected!`
* The `vendor` module is now called `arch`.
* Under the `arch` module is a suite of modules like `x86`, `x86_64`,
  etc. One per `cfg!(target_arch)`.
* The `is_target_feature_detected!` macro was removed from coresimd.
  Unfortunately libcore has no ability to export unstable macros, so for
  now all feature detection is canonicalized in stdsimd.

The `coresimd` and `stdsimd` crates have been updated to the planned
organization in RFC 2325 as well. The runtime bits saw the largest
amount of refactoring, seeing a good deal of simplification without the
core/std split.
This commit is contained in:
Alex Crichton
2018-02-18 10:07:35 +09:00
committed by GitHub
parent d097221faf
commit 39b5ec91ae
123 changed files with 1852 additions and 2051 deletions

View File

@@ -0,0 +1,100 @@
//! Implementation of the `#[simd_test]` macro
//!
//! This macro expands to a `#[test]` function which tests the local machine
//! for the appropriate cfg before calling the inner test function.
#![feature(proc_macro)]
extern crate proc_macro;
extern crate proc_macro2;
#[macro_use]
extern crate quote;
use proc_macro2::{Term, TokenNode, TokenStream, TokenTree};
use proc_macro2::Literal;
fn string(s: &str) -> TokenTree {
TokenNode::Literal(Literal::string(s)).into()
}
#[proc_macro_attribute]
pub fn simd_test(
attr: proc_macro::TokenStream, item: proc_macro::TokenStream
) -> proc_macro::TokenStream {
let tokens = TokenStream::from(attr).into_iter().collect::<Vec<_>>();
if tokens.len() != 2 {
panic!("expected #[simd_test = \"feature\"]");
}
match tokens[0].kind {
TokenNode::Op('=', _) => {}
_ => panic!("expected #[simd_test = \"feature\"]"),
}
let target_features = match tokens[1].kind {
TokenNode::Literal(ref l) => l.to_string(),
_ => panic!("expected #[simd_test = \"feature\"]"),
};
let target_features: Vec<String> = target_features
.replace('"', "")
.replace('+', "")
.split(',')
.map(|v| String::from(v))
.collect();
let enable_feature = match tokens[1].kind {
TokenNode::Literal(ref l) => l.to_string(),
_ => panic!("expected #[simd_test = \"feature\"]"),
};
let enable_feature = enable_feature
.trim_left_matches('"')
.trim_right_matches('"');
let enable_feature = string(enable_feature);
let item = TokenStream::from(item);
let name = find_name(item.clone());
let name: TokenStream = name.as_str().parse().unwrap();
let mut cfg_target_features = quote::Tokens::new();
use quote::ToTokens;
for feature in target_features {
let q = quote_spanned! {
proc_macro2::Span::call_site() =>
is_target_feature_detected!(#feature) &&
};
q.to_tokens(&mut cfg_target_features);
}
let q = quote!{ true };
q.to_tokens(&mut cfg_target_features);
let ret: TokenStream = quote_spanned! {
proc_macro2::Span::call_site() =>
#[allow(non_snake_case)]
#[test]
fn #name() {
if #cfg_target_features {
return unsafe { #name() };
} else {
::stdsimd_test::assert_skip_test_ok(stringify!(#name));
}
#[target_feature(enable = #enable_feature)]
#item
}
}.into();
ret.into()
}
fn find_name(item: TokenStream) -> Term {
let mut tokens = item.into_iter();
while let Some(tok) = tokens.next() {
if let TokenNode::Term(word) = tok.kind {
if word.as_str() == "fn" {
break;
}
}
}
match tokens.next().map(|t| t.kind) {
Some(TokenNode::Term(word)) => word,
_ => panic!("failed to find function name"),
}
}