Added support for custom cpu features

This commit is contained in:
Syrus
2020-06-04 15:50:03 -07:00
parent bfb9f83fdd
commit fa6de35944
4 changed files with 78 additions and 20 deletions

View File

@@ -8,7 +8,7 @@ use itertools::Itertools;
use std::sync::Arc; use std::sync::Arc;
use target_lexicon::Architecture; use target_lexicon::Architecture;
use wasm_common::{FunctionType, LocalFunctionIndex}; use wasm_common::{FunctionType, LocalFunctionIndex};
use wasmer_compiler::{Compiler, CompilerConfig, CpuFeature, Features, Target, Triple}; use wasmer_compiler::{Compiler, CompilerConfig, Features, Target, Triple};
/// The InkWell ModuleInfo type /// The InkWell ModuleInfo type
pub type InkwellModule<'ctx> = inkwell::module::Module<'ctx>; pub type InkwellModule<'ctx> = inkwell::module::Module<'ctx>;
@@ -142,23 +142,11 @@ impl LLVMConfig {
} }
// The CPU features formatted as LLVM strings // The CPU features formatted as LLVM strings
// We can safely map to gcc-like features as the CPUFeatures
// are complaint with the same string representations as gcc.
let llvm_cpu_features = cpu_features let llvm_cpu_features = cpu_features
.iter() .iter()
.map(|feature| match feature { .map(|feature| format!("+{}", feature.to_string()))
CpuFeature::SSE2 => "+sse2",
CpuFeature::SSE3 => "+sse3",
CpuFeature::SSSE3 => "+ssse3",
CpuFeature::SSE41 => "+sse4.1",
CpuFeature::SSE42 => "+sse4.2",
CpuFeature::POPCNT => "+popcnt",
CpuFeature::AVX => "+avx",
CpuFeature::BMI1 => "+bmi",
CpuFeature::BMI2 => "+bmi2",
CpuFeature::AVX2 => "+avx2",
CpuFeature::AVX512DQ => "+avx512dq",
CpuFeature::AVX512VL => "+avx512vl",
CpuFeature::LZCNT => "+lzcnt",
})
.join(","); .join(",");
let llvm_target = InkwellTarget::from_triple(&self.target_triple()).unwrap(); let llvm_target = InkwellTarget::from_triple(&self.target_triple()).unwrap();

View File

@@ -80,7 +80,8 @@ pub use crate::relocation::{Relocation, RelocationKind, RelocationTarget, Reloca
pub use crate::section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex}; pub use crate::section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex};
pub use crate::sourceloc::SourceLoc; pub use crate::sourceloc::SourceLoc;
pub use crate::target::{ pub use crate::target::{
Architecture, BinaryFormat, CallingConvention, CpuFeature, OperatingSystem, Target, Triple, Architecture, BinaryFormat, CallingConvention, CpuFeature, OperatingSystem,
ParseCpuFeatureError, Target, Triple,
}; };
#[cfg(feature = "translator")] #[cfg(feature = "translator")]
pub use crate::translator::{ pub use crate::translator::{

View File

@@ -1,6 +1,9 @@
//! Target configuration //! Target configuration
use enumset::{EnumSet, EnumSetType}; use enumset::{EnumSet, EnumSetType};
use std::str::FromStr;
use std::string::ToString;
pub use target_lexicon::{Architecture, BinaryFormat, CallingConvention, OperatingSystem, Triple}; pub use target_lexicon::{Architecture, BinaryFormat, CallingConvention, OperatingSystem, Triple};
use thiserror::Error;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use raw_cpuid::CpuId; use raw_cpuid::CpuId;
@@ -106,6 +109,65 @@ impl CpuFeature {
} }
} }
/// The error that can happen while parsing a `str`
/// to retrieve a [`CpuFeature`].
#[derive(Error, Debug)]
pub enum ParseCpuFeatureError {
/// The provided string feature doesn't exist
#[error("CpuFeature for the {0} doesn't exist")]
Missing(String),
}
// This options should map exactly the GCC options indicated
// here by architectures:
//
// X86: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
// ARM: https://gcc.gnu.org/onlinedocs/gcc/gcc/ARM-Options.html
// Aarch64: https://gcc.gnu.org/onlinedocs/gcc/gcc/AArch64-Options.html
impl FromStr for CpuFeature {
type Err = ParseCpuFeatureError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"sse2" => Ok(CpuFeature::SSE2),
"sse3" => Ok(CpuFeature::SSE3),
"ssse3" => Ok(CpuFeature::SSSE3),
"sse4.1" => Ok(CpuFeature::SSE41),
"sse4.2" => Ok(CpuFeature::SSE42),
"popcnt" => Ok(CpuFeature::POPCNT),
"avx" => Ok(CpuFeature::AVX),
"bmi" => Ok(CpuFeature::BMI1),
"bmi2" => Ok(CpuFeature::BMI2),
"avx2" => Ok(CpuFeature::AVX2),
"avx512dq" => Ok(CpuFeature::AVX512DQ),
"avx512vl" => Ok(CpuFeature::AVX512VL),
"lzcnt" => Ok(CpuFeature::LZCNT),
_ => Err(ParseCpuFeatureError::Missing(s.to_string())),
}
}
}
impl ToString for CpuFeature {
fn to_string(&self) -> String {
match self {
CpuFeature::SSE2 => "sse2",
CpuFeature::SSE3 => "sse3",
CpuFeature::SSSE3 => "ssse3",
CpuFeature::SSE41 => "sse4.1",
CpuFeature::SSE42 => "sse4.2",
CpuFeature::POPCNT => "popcnt",
CpuFeature::AVX => "avx",
CpuFeature::BMI1 => "bmi",
CpuFeature::BMI2 => "bmi2",
CpuFeature::AVX2 => "avx2",
CpuFeature::AVX512DQ => "avx512dq",
CpuFeature::AVX512VL => "avx512vl",
CpuFeature::LZCNT => "lzcnt",
}
.to_string()
}
}
/// This is the target that we will use for compiling /// This is the target that we will use for compiling
/// the WebAssembly ModuleInfo, and then run it. /// the WebAssembly ModuleInfo, and then run it.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]

View File

@@ -27,6 +27,9 @@ pub struct Compile {
#[structopt(flatten)] #[structopt(flatten)]
compiler: StoreOptions, compiler: StoreOptions,
#[structopt(short = "m", multiple = true)]
cpu_features: Vec<CpuFeature>,
} }
impl Compile { impl Compile {
@@ -37,9 +40,13 @@ impl Compile {
} }
fn inner_execute(&self) -> Result<()> { fn inner_execute(&self) -> Result<()> {
let target = if let Some(ref target_triple) = self.target_triple { let target = if let Some(ref target_triple) = self.target_triple {
let mut features = CpuFeature::set(); let mut features = self
// Cranelift requires SSE2, so we have this "hack" for now until .cpu_features
// we are able to pass custom features .clone()
.into_iter()
.fold(CpuFeature::set(), |a, b| a | b);
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
// usage
features = features | CpuFeature::SSE2; features = features | CpuFeature::SSE2;
Target::new(target_triple.clone(), features) Target::new(target_triple.clone(), features)
} else { } else {