Skip to content
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

literal: auto enable SIMD on Rust stable 1.27+ #490

Merged
merged 1 commit into from Jun 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -12,6 +12,7 @@ An implementation of regular expressions for Rust. This implementation uses
finite automata and guarantees linear time matching on all inputs.
"""
categories = ["text-processing"]
autotests = false

[badges]
travis-ci = { repository = "rust-lang/regex" }
Expand Down
2 changes: 1 addition & 1 deletion bench/Cargo.toml
Expand Up @@ -18,7 +18,7 @@ libc = "0.2"
onig = { version = "3", optional = true }
libpcre-sys = { version = "0.2", optional = true }
memmap = "0.6"
regex = { version = "1.0.0", path = "..", features = ["unstable"] }
regex = { version = "1.0.0", path = ".." }
regex-syntax = { version = "0.6.0", path = "../regex-syntax" }
serde = "1"
serde_derive = "1"
Expand Down
71 changes: 67 additions & 4 deletions build.rs
Expand Up @@ -11,17 +11,80 @@ fn main() {
.stdout;
let version = String::from_utf8(output).unwrap();

enable_simd_optimizations(&version);
}

fn enable_simd_optimizations(version: &str) {
// If we're using nightly Rust, then we can enable vector optimizations.
// Note that these aren't actually activated unless the `unstable` feature
// is enabled.
//
// We also don't activate these if we've explicitly disabled auto
// optimizations. Disabling auto optimizations is intended for use in
// tests, so that we can reliably test fallback implementations.
if env::var_os("CARGO_CFG_REGEX_DISABLE_AUTO_OPTIMIZATIONS").is_none() {
if version.contains("nightly") {
println!("cargo:rustc-cfg=regex_runtime_teddy_ssse3");
println!("cargo:rustc-cfg=regex_runtime_teddy_avx2");
if env::var_os("CARGO_CFG_REGEX_DISABLE_AUTO_OPTIMIZATIONS").is_some() {
return;
}
let parsed = match Version::parse(&version) {
Ok(parsed) => parsed,
Err(err) => {
eprintln!("failed to parse `rustc --version`: {}", err);
return;
}
};
let minimum = Version { major: 1, minor: 27, patch: 0 };
if version.contains("nightly") || parsed >= minimum {
println!("cargo:rustc-cfg=regex_runtime_teddy_ssse3");
println!("cargo:rustc-cfg=regex_runtime_teddy_avx2");
}
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
struct Version {
major: u32,
minor: u32,
patch: u32,
}

impl Version {
fn parse(mut s: &str) -> Result<Version, String> {
if !s.starts_with("rustc ") {
return Err(format!("unrecognized version string: {}", s));
}
s = &s["rustc ".len()..];

let parts: Vec<&str> = s.split(".").collect();
if parts.len() < 3 {
return Err(format!("not enough version parts: {:?}", parts));
}

let mut num = String::new();
for c in parts[0].chars() {
if !c.is_digit(10) {
break;
}
num.push(c);
}
let major = num.parse::<u32>().map_err(|e| e.to_string())?;

num.clear();
for c in parts[1].chars() {
if !c.is_digit(10) {
break;
}
num.push(c);
}
let minor = num.parse::<u32>().map_err(|e| e.to_string())?;

num.clear();
for c in parts[2].chars() {
if !c.is_digit(10) {
break;
}
num.push(c);
}
let patch = num.parse::<u32>().map_err(|e| e.to_string())?;

Ok(Version { major, minor, patch })
}
}
4 changes: 1 addition & 3 deletions src/lib.rs
Expand Up @@ -521,11 +521,9 @@ another matching engine with fixed memory requirements.
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(feature = "pattern", feature(pattern))]


#[cfg(not(feature = "use_std"))]
compile_error!("`use_std` feature is currently required to build this crate");


extern crate aho_corasick;
extern crate memchr;
extern crate thread_local;
Expand Down Expand Up @@ -669,7 +667,7 @@ mod re_set;
mod re_trait;
mod re_unicode;
mod sparse;
#[cfg(feature = "unstable")]
#[cfg(any(regex_runtime_teddy_ssse3, regex_runtime_teddy_avx2))]
mod vector;

/// The `internal` module exists to support suspicious activity, such as
Expand Down
6 changes: 2 additions & 4 deletions src/literal/teddy_avx2/mod.rs
@@ -1,16 +1,14 @@
pub use self::imp::*;

#[cfg(all(
feature = "unstable",
regex_runtime_teddy_avx2,
any(target_arch = "x86_64"),
target_arch = "x86_64",
))]
mod imp;

#[cfg(not(all(
feature = "unstable",
regex_runtime_teddy_avx2,
any(target_arch = "x86_64"),
target_arch = "x86_64",
)))]
#[path = "fallback.rs"]
mod imp;
6 changes: 2 additions & 4 deletions src/literal/teddy_ssse3/mod.rs
@@ -1,16 +1,14 @@
pub use self::imp::*;

#[cfg(all(
feature = "unstable",
regex_runtime_teddy_ssse3,
any(target_arch = "x86", target_arch = "x86_64"),
target_arch = "x86_64",
))]
mod imp;

#[cfg(not(all(
feature = "unstable",
regex_runtime_teddy_ssse3,
any(target_arch = "x86", target_arch = "x86_64"),
target_arch = "x86_64",
)))]
#[path = "fallback.rs"]
mod imp;
2 changes: 1 addition & 1 deletion src/vector/mod.rs
@@ -1,4 +1,4 @@
#[cfg(target_arch = "x86_64")]
pub mod avx2;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[cfg(any(target_arch = "x86_64"))]
pub mod ssse3;