mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-05 12:18:30 +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 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();
|
||||||
|
|||||||
@@ -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::{
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user