Add a method to share Config across machines (#2608)

With `Module::{serialize,deserialize}` it should be possible to share
wasmtime modules across machines or CPUs. Serialization, however, embeds
a hash of all configuration values, including cranelift compilation
settings. By default wasmtime's selection of the native ISA would enable
ISA flags according to CPU features available on the host, but the same
CPU features may not be available across two machines.

This commit adds a `Config::cranelift_clear_cpu_flags` method which
allows clearing the target-specific ISA flags that are automatically
inferred by default for the native CPU. Options can then be
incrementally built back up as-desired with teh `cranelift_other_flag`
method.
This commit is contained in:
Alex Crichton
2021-01-26 15:59:12 -06:00
committed by GitHub
parent e594c43d50
commit 503129ad91
16 changed files with 125 additions and 11 deletions

View File

@@ -418,7 +418,7 @@ fn gen_display(group: &SettingGroup, fmt: &mut Formatter) {
fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
// Generate struct.
fmtln!(fmt, "#[derive(Clone)]");
fmtln!(fmt, "#[derive(Clone, Hash)]");
fmt.doc_comment(format!("Flags group `{}`.", group.name));
fmtln!(fmt, "pub struct Flags {");
fmt.indent(|fmt| {

View File

@@ -8,6 +8,7 @@ use crate::result::CodegenResult;
use crate::settings;
use alloc::boxed::Box;
use core::hash::{Hash, Hasher};
use regalloc::{PrettyPrint, RealRegUniverse};
use target_lexicon::{Aarch64Architecture, Architecture, Triple};
@@ -95,6 +96,10 @@ impl MachBackend for AArch64Backend {
&self.flags
}
fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.flags.hash(&mut hasher);
}
fn reg_universe(&self) -> &RealRegUniverse {
&self.reg_universe
}

View File

@@ -8,6 +8,7 @@ use crate::result::CodegenResult;
use crate::settings;
use alloc::boxed::Box;
use core::hash::{Hash, Hasher};
use regalloc::{PrettyPrint, RealRegUniverse};
use target_lexicon::{Architecture, ArmArchitecture, Triple};
@@ -90,6 +91,10 @@ impl MachBackend for Arm32Backend {
&self.flags
}
fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.flags.hash(&mut hasher);
}
fn reg_universe(&self) -> &RealRegUniverse {
&self.reg_universe
}

View File

@@ -69,6 +69,7 @@ use alloc::boxed::Box;
use core::any::Any;
use core::fmt;
use core::fmt::{Debug, Formatter};
use core::hash::Hasher;
use target_lexicon::{triple, Architecture, PointerWidth, Triple};
use thiserror::Error;
@@ -265,6 +266,10 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
/// Get the ISA-independent flags that were used to make this trait object.
fn flags(&self) -> &settings::Flags;
/// Hashes all flags, both ISA-independent and ISA-specific, into the
/// specified hasher.
fn hash_all_flags(&self, hasher: &mut dyn Hasher);
/// Get the default calling convention of this target.
fn default_call_conv(&self) -> CallConv {
CallConv::triple_default(self.triple())

View File

@@ -19,6 +19,7 @@ use alloc::borrow::Cow;
use alloc::boxed::Box;
use core::any::Any;
use core::fmt;
use core::hash::{Hash, Hasher};
use target_lexicon::{PointerWidth, Triple};
#[allow(dead_code)]
@@ -69,6 +70,11 @@ impl TargetIsa for Isa {
&self.shared_flags
}
fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.shared_flags.hash(&mut hasher);
self.isa_flags.hash(&mut hasher);
}
fn register_info(&self) -> RegInfo {
registers::INFO.clone()
}

View File

@@ -11,6 +11,7 @@ use crate::machinst::{compile, MachBackend, MachCompileResult, TargetIsaAdapter,
use crate::result::CodegenResult;
use crate::settings::{self as shared_settings, Flags};
use alloc::boxed::Box;
use core::hash::{Hash, Hasher};
use regalloc::{PrettyPrint, RealRegUniverse, Reg};
use target_lexicon::Triple;
@@ -82,6 +83,11 @@ impl MachBackend for X64Backend {
&self.flags
}
fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.flags.hash(&mut hasher);
self.x64_flags.hash(&mut hasher);
}
fn name(&self) -> &'static str {
"x64"
}

View File

@@ -25,6 +25,7 @@ use alloc::borrow::Cow;
use alloc::boxed::Box;
use core::any::Any;
use core::fmt;
use core::hash::{Hash, Hasher};
use target_lexicon::{PointerWidth, Triple};
#[allow(dead_code)]
@@ -78,6 +79,11 @@ impl TargetIsa for Isa {
&self.shared_flags
}
fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.shared_flags.hash(&mut hasher);
self.isa_flags.hash(&mut hasher);
}
fn uses_cpu_flags(&self) -> bool {
true
}

View File

@@ -14,6 +14,7 @@ use crate::regalloc::RegDiversions;
use crate::isa::unwind::systemv::RegisterMappingError;
use core::any::Any;
use core::hash::Hasher;
use std::borrow::Cow;
use std::fmt;
use target_lexicon::Triple;
@@ -58,6 +59,10 @@ impl TargetIsa for TargetIsaAdapter {
self.backend.flags()
}
fn hash_all_flags(&self, hasher: &mut dyn Hasher) {
self.backend.hash_all_flags(hasher)
}
fn register_info(&self) -> RegInfo {
// Called from function's Display impl, so we need a stub here.
RegInfo {

View File

@@ -76,6 +76,7 @@ use regalloc::{
RealReg, RealRegUniverse, Reg, RegClass, RegUsageMapper, SpillSlot, VirtualReg, Writable,
};
use smallvec::{smallvec, SmallVec};
use std::hash::Hasher;
use std::string::String;
use target_lexicon::Triple;
@@ -373,6 +374,10 @@ pub trait MachBackend {
/// Return flags for this backend.
fn flags(&self) -> &Flags;
/// Hashes all flags, both ISA-independent and ISA-specific, into the
/// specified hasher.
fn hash_all_flags(&self, hasher: &mut dyn Hasher);
/// Return triple for this backend.
fn triple(&self) -> Triple;

View File

@@ -188,7 +188,7 @@ pub type SetResult<T> = Result<T, SetError>;
/// The settings objects themselves are generated and appear in the `isa/*/settings.rs` modules.
/// Each settings object provides a `predicate_view()` method that makes it possible to query
/// ISA predicates by number.
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Hash)]
pub struct PredicateView<'a>(&'a [u8]);
impl<'a> PredicateView<'a> {

View File

@@ -34,7 +34,7 @@ use raw_cpuid::CpuId;
/// machine, or `Err(())` if the host machine is not supported
/// in the current configuration.
pub fn builder() -> Result<isa::Builder, &'static str> {
builder_with_backend_variant(isa::BackendVariant::Any)
builder_with_options(isa::BackendVariant::Any, true)
}
/// Return an `isa` builder configured for the current host
@@ -44,8 +44,9 @@ pub fn builder() -> Result<isa::Builder, &'static str> {
/// Selects the given backend variant specifically; this is
/// useful when more than oen backend exists for a given target
/// (e.g., on x86-64).
pub fn builder_with_backend_variant(
pub fn builder_with_options(
variant: isa::BackendVariant,
infer_native_flags: bool,
) -> Result<isa::Builder, &'static str> {
let mut isa_builder =
isa::lookup_variant(Triple::host(), variant).map_err(|err| match err {
@@ -55,7 +56,7 @@ pub fn builder_with_backend_variant(
isa::LookupError::Unsupported => "unsupported architecture",
})?;
if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
if infer_native_flags && cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
parse_x86_cpuid(&mut isa_builder)?;
}