mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-05 20:28:23 +00:00
Added support for custom cpu features
This commit is contained in:
@@ -8,7 +8,7 @@ use itertools::Itertools;
|
||||
use std::sync::Arc;
|
||||
use target_lexicon::Architecture;
|
||||
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
|
||||
pub type InkwellModule<'ctx> = inkwell::module::Module<'ctx>;
|
||||
@@ -142,23 +142,11 @@ impl LLVMConfig {
|
||||
}
|
||||
|
||||
// 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
|
||||
.iter()
|
||||
.map(|feature| match feature {
|
||||
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",
|
||||
})
|
||||
.map(|feature| format!("+{}", feature.to_string()))
|
||||
.join(",");
|
||||
|
||||
let llvm_target = InkwellTarget::from_triple(&self.target_triple()).unwrap();
|
||||
|
||||
@@ -80,7 +80,8 @@ pub use crate::relocation::{Relocation, RelocationKind, RelocationTarget, Reloca
|
||||
pub use crate::section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex};
|
||||
pub use crate::sourceloc::SourceLoc;
|
||||
pub use crate::target::{
|
||||
Architecture, BinaryFormat, CallingConvention, CpuFeature, OperatingSystem, Target, Triple,
|
||||
Architecture, BinaryFormat, CallingConvention, CpuFeature, OperatingSystem,
|
||||
ParseCpuFeatureError, Target, Triple,
|
||||
};
|
||||
#[cfg(feature = "translator")]
|
||||
pub use crate::translator::{
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
//! Target configuration
|
||||
use enumset::{EnumSet, EnumSetType};
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
pub use target_lexicon::{Architecture, BinaryFormat, CallingConvention, OperatingSystem, Triple};
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
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
|
||||
/// the WebAssembly ModuleInfo, and then run it.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -27,6 +27,9 @@ pub struct Compile {
|
||||
|
||||
#[structopt(flatten)]
|
||||
compiler: StoreOptions,
|
||||
|
||||
#[structopt(short = "m", multiple = true)]
|
||||
cpu_features: Vec<CpuFeature>,
|
||||
}
|
||||
|
||||
impl Compile {
|
||||
@@ -37,9 +40,13 @@ impl Compile {
|
||||
}
|
||||
fn inner_execute(&self) -> Result<()> {
|
||||
let target = if let Some(ref target_triple) = self.target_triple {
|
||||
let mut features = CpuFeature::set();
|
||||
// Cranelift requires SSE2, so we have this "hack" for now until
|
||||
// we are able to pass custom features
|
||||
let mut features = self
|
||||
.cpu_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;
|
||||
Target::new(target_triple.clone(), features)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user