wasmtime_internal_cranelift/
builder.rs1use crate::isa_builder::IsaBuilder;
7use cranelift_codegen::{
8 CodegenResult,
9 isa::{self, OwnedTargetIsa},
10};
11use std::fmt;
12use std::path;
13use std::sync::Arc;
14use target_lexicon::Triple;
15use wasmtime_environ::error::Result;
16use wasmtime_environ::{CacheStore, CompilerBuilder, Setting, Tunables};
17
18struct Builder {
19 tunables: Option<Tunables>,
20 inner: IsaBuilder<CodegenResult<OwnedTargetIsa>>,
21 emit_debug_checks: bool,
22 linkopts: LinkOptions,
23 cache_store: Option<Arc<dyn CacheStore>>,
24 clif_dir: Option<path::PathBuf>,
25 wmemcheck: bool,
26}
27
28#[derive(Clone, Default)]
29pub struct LinkOptions {
30 pub padding_between_functions: usize,
34
35 pub force_jump_veneers: bool,
39}
40
41pub fn builder(triple: Option<Triple>) -> Result<Box<dyn CompilerBuilder>> {
42 let mut builder = Builder {
43 tunables: None,
44 inner: IsaBuilder::new(triple, |triple| isa::lookup(triple).map_err(|e| e.into()))?,
45 linkopts: LinkOptions::default(),
46 cache_store: None,
47 clif_dir: None,
48 wmemcheck: false,
49 emit_debug_checks: false,
50 };
51
52 builder.set("enable_verifier", "false").unwrap();
53 builder.set("opt_level", "speed").unwrap();
54
55 if cfg!(miri) {
59 builder.set("opt_level", "none").unwrap();
60 builder.set("regalloc_algorithm", "single_pass").unwrap();
61 }
62
63 Ok(Box::new(builder))
64}
65
66impl CompilerBuilder for Builder {
67 fn triple(&self) -> &target_lexicon::Triple {
68 self.inner.triple()
69 }
70
71 fn clif_dir(&mut self, path: &path::Path) -> Result<()> {
72 self.clif_dir = Some(path.to_path_buf());
73 Ok(())
74 }
75
76 fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {
77 self.inner.target(target)?;
78 Ok(())
79 }
80
81 fn set(&mut self, name: &str, value: &str) -> Result<()> {
82 match name {
84 "wasmtime_linkopt_padding_between_functions" => {
85 self.linkopts.padding_between_functions = value.parse()?;
86 }
87 "wasmtime_linkopt_force_jump_veneer" => {
88 self.linkopts.force_jump_veneers = value.parse()?;
89 }
90 "wasmtime_inlining_intra_module" => {
91 self.tunables.as_mut().unwrap().inlining_intra_module = value.parse()?;
92 }
93 "wasmtime_inlining_small_callee_size" => {
94 self.tunables.as_mut().unwrap().inlining_small_callee_size = value.parse()?;
95 }
96 "wasmtime_inlining_sum_size_threshold" => {
97 self.tunables.as_mut().unwrap().inlining_sum_size_threshold = value.parse()?;
98 }
99 "wasmtime_debug_checks" => {
100 self.emit_debug_checks = true;
101 }
102 _ => {
103 self.inner.set(name, value)?;
104 }
105 }
106 Ok(())
107 }
108
109 fn enable(&mut self, name: &str) -> Result<()> {
110 self.inner.enable(name)
111 }
112
113 fn set_tunables(&mut self, tunables: Tunables) -> Result<()> {
114 self.tunables = Some(tunables);
115 Ok(())
116 }
117
118 fn tunables(&self) -> Option<&Tunables> {
119 self.tunables.as_ref()
120 }
121
122 fn build(&self) -> Result<Box<dyn wasmtime_environ::Compiler>> {
123 let isa = self.inner.build()?;
124 Ok(Box::new(crate::compiler::Compiler::new(
125 self.tunables
126 .as_ref()
127 .expect("set_tunables not called")
128 .clone(),
129 isa,
130 self.cache_store.clone(),
131 self.emit_debug_checks,
132 self.linkopts.clone(),
133 self.clif_dir.clone(),
134 self.wmemcheck,
135 )))
136 }
137
138 fn settings(&self) -> Vec<Setting> {
139 self.inner.settings()
140 }
141
142 fn enable_incremental_compilation(
143 &mut self,
144 cache_store: Arc<dyn wasmtime_environ::CacheStore>,
145 ) -> Result<()> {
146 self.cache_store = Some(cache_store);
147 Ok(())
148 }
149
150 fn wmemcheck(&mut self, enable: bool) {
151 self.wmemcheck = enable;
152 }
153}
154
155impl fmt::Debug for Builder {
156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 f.debug_struct("Builder")
158 .field("shared_flags", &self.inner.shared_flags().to_string())
159 .finish()
160 }
161}