Path: blob/main/crates/cranelift/src/isa_builder.rs
1692 views
use anyhow::Result;1use cranelift_codegen::isa::IsaBuilder as Builder;2use cranelift_codegen::settings::{self, Configurable, Flags, SetError};3use target_lexicon::Triple;4use wasmtime_environ::{Setting, SettingKind};56/// A helper to build an Isa for a compiler implementation.7/// Compiler builders can wrap this to provide better flexibility when setting flags.8///9/// Most methods are mirrored from the `wasmtime_environ::CompilerBuilder` trait, so look there for more10/// information.11pub struct IsaBuilder<T> {12/// The shared flags that all targets share.13shared_flags: settings::Builder,14/// The internal ISA builder for the current target.15inner: Builder<T>,16/// A callback to lookup a new ISA builder for a target.17pub lookup: fn(Triple) -> Result<Builder<T>>,18}1920impl<T> IsaBuilder<T> {21/// Create a new ISA builder with the given lookup function.22pub fn new(triple: Option<Triple>, lookup: fn(Triple) -> Result<Builder<T>>) -> Result<Self> {23let mut flags = settings::builder();2425// We don't use probestack as a stack limit mechanism26flags27.set("enable_probestack", "false")28.expect("should be valid flag");2930let triple_specified = triple.is_some();31let triple = triple.unwrap_or_else(Triple::host);32let mut isa_flags = lookup(triple)?;33if !triple_specified {34cranelift_native::infer_native_flags(&mut isa_flags).unwrap();35}3637Ok(Self {38shared_flags: flags,39inner: isa_flags,40lookup,41})42}4344pub fn triple(&self) -> &target_lexicon::Triple {45self.inner.triple()46}4748pub fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {49self.inner = (self.lookup)(target)?;50Ok(())51}5253pub fn settings(&self) -> Vec<Setting> {54self.inner55.iter()56.map(|s| Setting {57description: s.description,58name: s.name,59values: s.values,60kind: match s.kind {61settings::SettingKind::Preset => SettingKind::Preset,62settings::SettingKind::Enum => SettingKind::Enum,63settings::SettingKind::Num => SettingKind::Num,64settings::SettingKind::Bool => SettingKind::Bool,65},66})67.collect()68}6970pub fn set(&mut self, name: &str, value: &str) -> Result<()> {71if let Err(err) = self.shared_flags.set(name, value) {72match err {73SetError::BadName(_) => {74self.inner.set(name, value)?;75}76_ => return Err(err.into()),77}78}79Ok(())80}8182pub fn enable(&mut self, name: &str) -> Result<()> {83if let Err(err) = self.shared_flags.enable(name) {84match err {85SetError::BadName(_) => {86// Try the target-specific flags.87self.inner.enable(name)?;88}89_ => return Err(err.into()),90}91}92Ok(())93}9495pub fn build(&self) -> T {96self.inner97.finish(settings::Flags::new(self.shared_flags.clone()))98}99100pub fn shared_flags(&self) -> Flags {101settings::Flags::new(self.shared_flags.clone())102}103}104105106