/src/wasmer/target/x86_64-unknown-linux-gnu/release/build/cranelift-codegen-bbdde6853ee6ef31/out/settings.rs
Line | Count | Source (jump to first uncovered line) |
1 | | #[derive(Clone, Hash)] |
2 | | /// Flags group `shared`. |
3 | | pub struct Flags { |
4 | | bytes: [u8; 9], |
5 | | } |
6 | | impl Flags { |
7 | | /// Create flags shared settings group. |
8 | | #[allow(unused_variables)] |
9 | 10.0k | pub fn new(builder: Builder) -> Self { |
10 | 10.0k | let bvec = builder.state_for("shared"); |
11 | 10.0k | let mut shared = Self { bytes: [0; 9] }; |
12 | 10.0k | debug_assert_eq!(bvec.len(), 9); |
13 | 10.0k | shared.bytes[0..9].copy_from_slice(&bvec); |
14 | 10.0k | shared |
15 | 10.0k | } |
16 | | } |
17 | | impl Flags { |
18 | | /// Iterates the setting values. |
19 | 0 | pub fn iter(&self) -> impl Iterator<Item = Value> { |
20 | 0 | let mut bytes = [0; 9]; |
21 | 0 | bytes.copy_from_slice(&self.bytes[0..9]); |
22 | 0 | DESCRIPTORS.iter().filter_map(move |d| { |
23 | 0 | let values = match &d.detail { |
24 | 0 | detail::Detail::Preset => return None, |
25 | 0 | detail::Detail::Enum { last, enumerators } => Some(TEMPLATE.enums(*last, *enumerators)), |
26 | 0 | _ => None |
27 | | }; |
28 | 0 | Some(Value{ name: d.name, detail: d.detail, values, value: bytes[d.offset as usize] }) |
29 | 0 | }) |
30 | 0 | } |
31 | | } |
32 | | /// Values for `shared.opt_level`. |
33 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
34 | | pub enum OptLevel { |
35 | | /// `none`. |
36 | | None, |
37 | | /// `speed`. |
38 | | Speed, |
39 | | /// `speed_and_size`. |
40 | | SpeedAndSize, |
41 | | } |
42 | | impl OptLevel { |
43 | | /// Returns a slice with all possible [OptLevel] values. |
44 | 0 | pub fn all() -> &'static [OptLevel] { |
45 | 0 | &[ |
46 | 0 | Self::None, |
47 | 0 | Self::Speed, |
48 | 0 | Self::SpeedAndSize, |
49 | 0 | ] |
50 | 0 | } |
51 | | } |
52 | | impl fmt::Display for OptLevel { |
53 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
54 | 0 | f.write_str(match *self { |
55 | 0 | Self::None => "none", |
56 | 0 | Self::Speed => "speed", |
57 | 0 | Self::SpeedAndSize => "speed_and_size", |
58 | | }) |
59 | 0 | } |
60 | | } |
61 | | impl core::str::FromStr for OptLevel { |
62 | | type Err = (); |
63 | 0 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
64 | 0 | match s { |
65 | 0 | "none" => Ok(Self::None), |
66 | 0 | "speed" => Ok(Self::Speed), |
67 | 0 | "speed_and_size" => Ok(Self::SpeedAndSize), |
68 | 0 | _ => Err(()), |
69 | | } |
70 | 0 | } |
71 | | } |
72 | | /// Values for `shared.tls_model`. |
73 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
74 | | pub enum TlsModel { |
75 | | /// `none`. |
76 | | None, |
77 | | /// `elf_gd`. |
78 | | ElfGd, |
79 | | /// `macho`. |
80 | | Macho, |
81 | | /// `coff`. |
82 | | Coff, |
83 | | } |
84 | | impl TlsModel { |
85 | | /// Returns a slice with all possible [TlsModel] values. |
86 | 0 | pub fn all() -> &'static [TlsModel] { |
87 | 0 | &[ |
88 | 0 | Self::None, |
89 | 0 | Self::ElfGd, |
90 | 0 | Self::Macho, |
91 | 0 | Self::Coff, |
92 | 0 | ] |
93 | 0 | } |
94 | | } |
95 | | impl fmt::Display for TlsModel { |
96 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
97 | 0 | f.write_str(match *self { |
98 | 0 | Self::None => "none", |
99 | 0 | Self::ElfGd => "elf_gd", |
100 | 0 | Self::Macho => "macho", |
101 | 0 | Self::Coff => "coff", |
102 | | }) |
103 | 0 | } |
104 | | } |
105 | | impl core::str::FromStr for TlsModel { |
106 | | type Err = (); |
107 | 0 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
108 | 0 | match s { |
109 | 0 | "none" => Ok(Self::None), |
110 | 0 | "elf_gd" => Ok(Self::ElfGd), |
111 | 0 | "macho" => Ok(Self::Macho), |
112 | 0 | "coff" => Ok(Self::Coff), |
113 | 0 | _ => Err(()), |
114 | | } |
115 | 0 | } |
116 | | } |
117 | | /// Values for `shared.libcall_call_conv`. |
118 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
119 | | pub enum LibcallCallConv { |
120 | | /// `isa_default`. |
121 | | IsaDefault, |
122 | | /// `fast`. |
123 | | Fast, |
124 | | /// `cold`. |
125 | | Cold, |
126 | | /// `system_v`. |
127 | | SystemV, |
128 | | /// `windows_fastcall`. |
129 | | WindowsFastcall, |
130 | | /// `apple_aarch64`. |
131 | | AppleAarch64, |
132 | | /// `probestack`. |
133 | | Probestack, |
134 | | } |
135 | | impl LibcallCallConv { |
136 | | /// Returns a slice with all possible [LibcallCallConv] values. |
137 | 0 | pub fn all() -> &'static [LibcallCallConv] { |
138 | 0 | &[ |
139 | 0 | Self::IsaDefault, |
140 | 0 | Self::Fast, |
141 | 0 | Self::Cold, |
142 | 0 | Self::SystemV, |
143 | 0 | Self::WindowsFastcall, |
144 | 0 | Self::AppleAarch64, |
145 | 0 | Self::Probestack, |
146 | 0 | ] |
147 | 0 | } |
148 | | } |
149 | | impl fmt::Display for LibcallCallConv { |
150 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
151 | 0 | f.write_str(match *self { |
152 | 0 | Self::IsaDefault => "isa_default", |
153 | 0 | Self::Fast => "fast", |
154 | 0 | Self::Cold => "cold", |
155 | 0 | Self::SystemV => "system_v", |
156 | 0 | Self::WindowsFastcall => "windows_fastcall", |
157 | 0 | Self::AppleAarch64 => "apple_aarch64", |
158 | 0 | Self::Probestack => "probestack", |
159 | | }) |
160 | 0 | } |
161 | | } |
162 | | impl core::str::FromStr for LibcallCallConv { |
163 | | type Err = (); |
164 | 0 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
165 | 0 | match s { |
166 | 0 | "isa_default" => Ok(Self::IsaDefault), |
167 | 0 | "fast" => Ok(Self::Fast), |
168 | 0 | "cold" => Ok(Self::Cold), |
169 | 0 | "system_v" => Ok(Self::SystemV), |
170 | 0 | "windows_fastcall" => Ok(Self::WindowsFastcall), |
171 | 0 | "apple_aarch64" => Ok(Self::AppleAarch64), |
172 | 0 | "probestack" => Ok(Self::Probestack), |
173 | 0 | _ => Err(()), |
174 | | } |
175 | 0 | } |
176 | | } |
177 | | /// Values for `shared.probestack_strategy`. |
178 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
179 | | pub enum ProbestackStrategy { |
180 | | /// `outline`. |
181 | | Outline, |
182 | | /// `inline`. |
183 | | Inline, |
184 | | } |
185 | | impl ProbestackStrategy { |
186 | | /// Returns a slice with all possible [ProbestackStrategy] values. |
187 | 0 | pub fn all() -> &'static [ProbestackStrategy] { |
188 | 0 | &[ |
189 | 0 | Self::Outline, |
190 | 0 | Self::Inline, |
191 | 0 | ] |
192 | 0 | } |
193 | | } |
194 | | impl fmt::Display for ProbestackStrategy { |
195 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
196 | 0 | f.write_str(match *self { |
197 | 0 | Self::Outline => "outline", |
198 | 0 | Self::Inline => "inline", |
199 | | }) |
200 | 0 | } |
201 | | } |
202 | | impl core::str::FromStr for ProbestackStrategy { |
203 | | type Err = (); |
204 | 0 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
205 | 0 | match s { |
206 | 0 | "outline" => Ok(Self::Outline), |
207 | 0 | "inline" => Ok(Self::Inline), |
208 | 0 | _ => Err(()), |
209 | | } |
210 | 0 | } |
211 | | } |
212 | | /// User-defined settings. |
213 | | #[allow(dead_code)] |
214 | | impl Flags { |
215 | | /// Get a view of the boolean predicates. |
216 | 0 | pub fn predicate_view(&self) -> crate::settings::PredicateView { |
217 | 0 | crate::settings::PredicateView::new(&self.bytes[5..]) |
218 | 0 | } |
219 | | /// Dynamic numbered predicate getter. |
220 | 7.62M | fn numbered_predicate(&self, p: usize) -> bool { |
221 | 7.62M | self.bytes[5 + p / 8] & (1 << (p % 8)) != 0 |
222 | 7.62M | } |
223 | | /// Optimization level for generated code. |
224 | | /// |
225 | | /// Supported levels: |
226 | | /// |
227 | | /// - `none`: Minimise compile time by disabling most optimizations. |
228 | | /// - `speed`: Generate the fastest possible code |
229 | | /// - `speed_and_size`: like "speed", but also perform transformations aimed at reducing code size. |
230 | 139k | pub fn opt_level(&self) -> OptLevel { |
231 | 139k | match self.bytes[0] { |
232 | | 0 => { |
233 | 0 | OptLevel::None |
234 | | } |
235 | | 1 => { |
236 | 139k | OptLevel::Speed |
237 | | } |
238 | | 2 => { |
239 | 0 | OptLevel::SpeedAndSize |
240 | | } |
241 | | _ => { |
242 | 0 | panic!("Invalid enum value") |
243 | | } |
244 | | } |
245 | 139k | } |
246 | | /// Defines the model used to perform TLS accesses. |
247 | 229k | pub fn tls_model(&self) -> TlsModel { |
248 | 229k | match self.bytes[1] { |
249 | | 3 => { |
250 | 0 | TlsModel::Coff |
251 | | } |
252 | | 1 => { |
253 | 0 | TlsModel::ElfGd |
254 | | } |
255 | | 2 => { |
256 | 0 | TlsModel::Macho |
257 | | } |
258 | | 0 => { |
259 | 229k | TlsModel::None |
260 | | } |
261 | | _ => { |
262 | 0 | panic!("Invalid enum value") |
263 | | } |
264 | | } |
265 | 229k | } |
266 | | /// Defines the calling convention to use for LibCalls call expansion. |
267 | | /// |
268 | | /// This may be different from the ISA default calling convention. |
269 | | /// |
270 | | /// The default value is to use the same calling convention as the ISA |
271 | | /// default calling convention. |
272 | | /// |
273 | | /// This list should be kept in sync with the list of calling |
274 | | /// conventions available in isa/call_conv.rs. |
275 | 0 | pub fn libcall_call_conv(&self) -> LibcallCallConv { |
276 | 0 | match self.bytes[2] { |
277 | | 5 => { |
278 | 0 | LibcallCallConv::AppleAarch64 |
279 | | } |
280 | | 2 => { |
281 | 0 | LibcallCallConv::Cold |
282 | | } |
283 | | 1 => { |
284 | 0 | LibcallCallConv::Fast |
285 | | } |
286 | | 0 => { |
287 | 0 | LibcallCallConv::IsaDefault |
288 | | } |
289 | | 6 => { |
290 | 0 | LibcallCallConv::Probestack |
291 | | } |
292 | | 3 => { |
293 | 0 | LibcallCallConv::SystemV |
294 | | } |
295 | | 4 => { |
296 | 0 | LibcallCallConv::WindowsFastcall |
297 | | } |
298 | | _ => { |
299 | 0 | panic!("Invalid enum value") |
300 | | } |
301 | | } |
302 | 0 | } |
303 | | /// The log2 of the size of the stack guard region. |
304 | | /// |
305 | | /// Stack frames larger than this size will have stack overflow checked |
306 | | /// by calling the probestack function. |
307 | | /// |
308 | | /// The default is 12, which translates to a size of 4096. |
309 | 139k | pub fn probestack_size_log2(&self) -> u8 { |
310 | 139k | self.bytes[3] |
311 | 139k | } |
312 | | /// Controls what kinds of stack probes are emitted. |
313 | | /// |
314 | | /// Supported strategies: |
315 | | /// |
316 | | /// - `outline`: Always emits stack probes as calls to a probe stack function. |
317 | | /// - `inline`: Always emits inline stack probes. |
318 | 0 | pub fn probestack_strategy(&self) -> ProbestackStrategy { |
319 | 0 | match self.bytes[4] { |
320 | | 1 => { |
321 | 0 | ProbestackStrategy::Inline |
322 | | } |
323 | | 0 => { |
324 | 0 | ProbestackStrategy::Outline |
325 | | } |
326 | | _ => { |
327 | 0 | panic!("Invalid enum value") |
328 | | } |
329 | | } |
330 | 0 | } |
331 | | /// Enable the symbolic checker for register allocation. |
332 | | /// |
333 | | /// This performs a verification that the register allocator preserves |
334 | | /// equivalent dataflow with respect to the original (pre-regalloc) |
335 | | /// program. This analysis is somewhat expensive. However, if it succeeds, |
336 | | /// it provides independent evidence (by a carefully-reviewed, from-first-principles |
337 | | /// analysis) that no regalloc bugs were triggered for the particular compilations |
338 | | /// performed. This is a valuable assurance to have as regalloc bugs can be |
339 | | /// very dangerous and difficult to debug. |
340 | 139k | pub fn regalloc_checker(&self) -> bool { |
341 | 139k | self.numbered_predicate(0) |
342 | 139k | } |
343 | | /// Enable verbose debug logs for regalloc2. |
344 | | /// |
345 | | /// This adds extra logging for regalloc2 output, that is quite valuable to understand |
346 | | /// decisions taken by the register allocator as well as debugging it. It is disabled by |
347 | | /// default, as it can cause many log calls which can slow down compilation by a large |
348 | | /// amount. |
349 | 139k | pub fn regalloc_verbose_logs(&self) -> bool { |
350 | 139k | self.numbered_predicate(1) |
351 | 139k | } |
352 | | /// Do redundant-load optimizations with alias analysis. |
353 | | /// |
354 | | /// This enables the use of a simple alias analysis to optimize away redundant loads. |
355 | | /// Only effective when `opt_level` is `speed` or `speed_and_size`. |
356 | 139k | pub fn enable_alias_analysis(&self) -> bool { |
357 | 139k | self.numbered_predicate(2) |
358 | 139k | } |
359 | | /// Enable egraph-based optimization. |
360 | | /// |
361 | | /// This enables an optimization phase that converts CLIF to an egraph (equivalence graph) |
362 | | /// representation, performs various rewrites, and then converts it back. This can result in |
363 | | /// better optimization, but is currently considered experimental. |
364 | 1.48M | pub fn use_egraphs(&self) -> bool { |
365 | 1.48M | self.numbered_predicate(3) |
366 | 1.48M | } |
367 | | /// Run the Cranelift IR verifier at strategic times during compilation. |
368 | | /// |
369 | | /// This makes compilation slower but catches many bugs. The verifier is always enabled by |
370 | | /// default, which is useful during development. |
371 | 1.39M | pub fn enable_verifier(&self) -> bool { |
372 | 1.39M | self.numbered_predicate(4) |
373 | 1.39M | } |
374 | | /// Enable Position-Independent Code generation. |
375 | 20.0k | pub fn is_pic(&self) -> bool { |
376 | 20.0k | self.numbered_predicate(5) |
377 | 20.0k | } |
378 | | /// Use colocated libcalls. |
379 | | /// |
380 | | /// Generate code that assumes that libcalls can be declared "colocated", |
381 | | /// meaning they will be defined along with the current function, such that |
382 | | /// they can use more efficient addressing. |
383 | 0 | pub fn use_colocated_libcalls(&self) -> bool { |
384 | 0 | self.numbered_predicate(6) |
385 | 0 | } |
386 | | /// Generate explicit checks around native division instructions to avoid their trapping. |
387 | | /// |
388 | | /// Generate explicit checks around native division instructions to |
389 | | /// avoid their trapping. |
390 | | /// |
391 | | /// On ISAs like ARM where the native division instructions don't trap, |
392 | | /// this setting has no effect - explicit checks are always inserted. |
393 | 2.85k | pub fn avoid_div_traps(&self) -> bool { |
394 | 2.85k | self.numbered_predicate(7) |
395 | 2.85k | } |
396 | | /// Enable the use of floating-point instructions. |
397 | | /// |
398 | | /// Disabling use of floating-point instructions is not yet implemented. |
399 | 0 | pub fn enable_float(&self) -> bool { |
400 | 0 | self.numbered_predicate(8) |
401 | 0 | } |
402 | | /// Enable NaN canonicalization. |
403 | | /// |
404 | | /// This replaces NaNs with a single canonical value, for users requiring |
405 | | /// entirely deterministic WebAssembly computation. This is not required |
406 | | /// by the WebAssembly spec, so it is not enabled by default. |
407 | 139k | pub fn enable_nan_canonicalization(&self) -> bool { |
408 | 139k | self.numbered_predicate(9) |
409 | 139k | } |
410 | | /// Enable the use of the pinned register. |
411 | | /// |
412 | | /// This register is excluded from register allocation, and is completely under the control of |
413 | | /// the end-user. It is possible to read it via the get_pinned_reg instruction, and to set it |
414 | | /// with the set_pinned_reg instruction. |
415 | 3.10M | pub fn enable_pinned_reg(&self) -> bool { |
416 | 3.10M | self.numbered_predicate(10) |
417 | 3.10M | } |
418 | | /// Use the pinned register as the heap base. |
419 | | /// |
420 | | /// Enabling this requires the enable_pinned_reg setting to be set to true. It enables a custom |
421 | | /// legalization of the `heap_addr` instruction so it will use the pinned register as the heap |
422 | | /// base, instead of fetching it from a global value. |
423 | | /// |
424 | | /// Warning! Enabling this means that the pinned register *must* be maintained to contain the |
425 | | /// heap base address at all times, during the lifetime of a function. Using the pinned |
426 | | /// register for other purposes when this is set is very likely to cause crashes. |
427 | 0 | pub fn use_pinned_reg_as_heap_base(&self) -> bool { |
428 | 0 | self.numbered_predicate(11) |
429 | 0 | } |
430 | | /// Enable the use of SIMD instructions. |
431 | 110k | pub fn enable_simd(&self) -> bool { |
432 | 110k | self.numbered_predicate(12) |
433 | 110k | } |
434 | | /// Enable the use of atomic instructions |
435 | 0 | pub fn enable_atomics(&self) -> bool { |
436 | 0 | self.numbered_predicate(13) |
437 | 0 | } |
438 | | /// Enable safepoint instruction insertions. |
439 | | /// |
440 | | /// This will allow the emit_stack_maps() function to insert the safepoint |
441 | | /// instruction on top of calls and interrupt traps in order to display the |
442 | | /// live reference values at that point in the program. |
443 | 0 | pub fn enable_safepoints(&self) -> bool { |
444 | 0 | self.numbered_predicate(14) |
445 | 0 | } |
446 | | /// Enable various ABI extensions defined by LLVM's behavior. |
447 | | /// |
448 | | /// In some cases, LLVM's implementation of an ABI (calling convention) |
449 | | /// goes beyond a standard and supports additional argument types or |
450 | | /// behavior. This option instructs Cranelift codegen to follow LLVM's |
451 | | /// behavior where applicable. |
452 | | /// |
453 | | /// Currently, this applies only to Windows Fastcall on x86-64, and |
454 | | /// allows an `i128` argument to be spread across two 64-bit integer |
455 | | /// registers. The Fastcall implementation otherwise does not support |
456 | | /// `i128` arguments, and will panic if they are present and this |
457 | | /// option is not set. |
458 | 0 | pub fn enable_llvm_abi_extensions(&self) -> bool { |
459 | 0 | self.numbered_predicate(15) |
460 | 0 | } |
461 | | /// Generate unwind information. |
462 | | /// |
463 | | /// This increases metadata size and compile time, but allows for the |
464 | | /// debugger to trace frames, is needed for GC tracing that relies on |
465 | | /// libunwind (such as in Wasmtime), and is unconditionally needed on |
466 | | /// certain platforms (such as Windows) that must always be able to unwind. |
467 | 329k | pub fn unwind_info(&self) -> bool { |
468 | 329k | self.numbered_predicate(16) |
469 | 329k | } |
470 | | /// Preserve frame pointers |
471 | | /// |
472 | | /// Preserving frame pointers -- even inside leaf functions -- makes it |
473 | | /// easy to capture the stack of a running program, without requiring any |
474 | | /// side tables or metadata (like `.eh_frame` sections). Many sampling |
475 | | /// profilers and similar tools walk frame pointers to capture stacks. |
476 | | /// Enabling this option will play nice with those tools. |
477 | 139k | pub fn preserve_frame_pointers(&self) -> bool { |
478 | 139k | self.numbered_predicate(17) |
479 | 139k | } |
480 | | /// Generate CFG metadata for machine code. |
481 | | /// |
482 | | /// This increases metadata size and compile time, but allows for the |
483 | | /// embedder to more easily post-process or analyze the generated |
484 | | /// machine code. It provides code offsets for the start of each |
485 | | /// basic block in the generated machine code, and a list of CFG |
486 | | /// edges (with blocks identified by start offsets) between them. |
487 | | /// This is useful for, e.g., machine-code analyses that verify certain |
488 | | /// properties of the generated code. |
489 | 139k | pub fn machine_code_cfg_info(&self) -> bool { |
490 | 139k | self.numbered_predicate(18) |
491 | 139k | } |
492 | | /// Enable the use of stack probes for supported calling conventions. |
493 | 139k | pub fn enable_probestack(&self) -> bool { |
494 | 139k | self.numbered_predicate(19) |
495 | 139k | } |
496 | | /// Enable if the stack probe adjusts the stack pointer. |
497 | 139k | pub fn probestack_func_adjusts_sp(&self) -> bool { |
498 | 139k | self.numbered_predicate(20) |
499 | 139k | } |
500 | | /// Enable the use of jump tables in generated machine code. |
501 | 0 | pub fn enable_jump_tables(&self) -> bool { |
502 | 0 | self.numbered_predicate(21) |
503 | 0 | } |
504 | | /// Enable Spectre mitigation on heap bounds checks. |
505 | | /// |
506 | | /// This is a no-op for any heap that needs no bounds checks; e.g., |
507 | | /// if the limit is static and the guard region is large enough that |
508 | | /// the index cannot reach past it. |
509 | | /// |
510 | | /// This option is enabled by default because it is highly |
511 | | /// recommended for secure sandboxing. The embedder should consider |
512 | | /// the security implications carefully before disabling this option. |
513 | 50.4k | pub fn enable_heap_access_spectre_mitigation(&self) -> bool { |
514 | 50.4k | self.numbered_predicate(22) |
515 | 50.4k | } |
516 | | /// Enable Spectre mitigation on table bounds checks. |
517 | | /// |
518 | | /// This option uses a conditional move to ensure that when a table |
519 | | /// access index is bounds-checked and a conditional branch is used |
520 | | /// for the out-of-bounds case, a misspeculation of that conditional |
521 | | /// branch (falsely predicted in-bounds) will select an in-bounds |
522 | | /// index to load on the speculative path. |
523 | | /// |
524 | | /// This option is enabled by default because it is highly |
525 | | /// recommended for secure sandboxing. The embedder should consider |
526 | | /// the security implications carefully before disabling this option. |
527 | 5.89k | pub fn enable_table_access_spectre_mitigation(&self) -> bool { |
528 | 5.89k | self.numbered_predicate(23) |
529 | 5.89k | } |
530 | | /// Enable additional checks for debugging the incremental compilation cache. |
531 | | /// |
532 | | /// Enables additional checks that are useful during development of the incremental |
533 | | /// compilation cache. This should be mostly useful for Cranelift hackers, as well as for |
534 | | /// helping to debug false incremental cache positives for embedders. |
535 | | /// |
536 | | /// This option is disabled by default and requires enabling the "incremental-cache" Cargo |
537 | | /// feature in cranelift-codegen. |
538 | 0 | pub fn enable_incremental_compilation_cache_checks(&self) -> bool { |
539 | 0 | self.numbered_predicate(24) |
540 | 0 | } |
541 | | } |
542 | | static DESCRIPTORS: [detail::Descriptor; 30] = [ |
543 | | detail::Descriptor { |
544 | | name: "opt_level", |
545 | | description: "Optimization level for generated code.", |
546 | | offset: 0, |
547 | | detail: detail::Detail::Enum { last: 2, enumerators: 0 }, |
548 | | }, |
549 | | detail::Descriptor { |
550 | | name: "tls_model", |
551 | | description: "Defines the model used to perform TLS accesses.", |
552 | | offset: 1, |
553 | | detail: detail::Detail::Enum { last: 3, enumerators: 3 }, |
554 | | }, |
555 | | detail::Descriptor { |
556 | | name: "libcall_call_conv", |
557 | | description: "Defines the calling convention to use for LibCalls call expansion.", |
558 | | offset: 2, |
559 | | detail: detail::Detail::Enum { last: 6, enumerators: 7 }, |
560 | | }, |
561 | | detail::Descriptor { |
562 | | name: "probestack_size_log2", |
563 | | description: "The log2 of the size of the stack guard region.", |
564 | | offset: 3, |
565 | | detail: detail::Detail::Num, |
566 | | }, |
567 | | detail::Descriptor { |
568 | | name: "probestack_strategy", |
569 | | description: "Controls what kinds of stack probes are emitted.", |
570 | | offset: 4, |
571 | | detail: detail::Detail::Enum { last: 1, enumerators: 14 }, |
572 | | }, |
573 | | detail::Descriptor { |
574 | | name: "regalloc_checker", |
575 | | description: "Enable the symbolic checker for register allocation.", |
576 | | offset: 5, |
577 | | detail: detail::Detail::Bool { bit: 0 }, |
578 | | }, |
579 | | detail::Descriptor { |
580 | | name: "regalloc_verbose_logs", |
581 | | description: "Enable verbose debug logs for regalloc2.", |
582 | | offset: 5, |
583 | | detail: detail::Detail::Bool { bit: 1 }, |
584 | | }, |
585 | | detail::Descriptor { |
586 | | name: "enable_alias_analysis", |
587 | | description: "Do redundant-load optimizations with alias analysis.", |
588 | | offset: 5, |
589 | | detail: detail::Detail::Bool { bit: 2 }, |
590 | | }, |
591 | | detail::Descriptor { |
592 | | name: "use_egraphs", |
593 | | description: "Enable egraph-based optimization.", |
594 | | offset: 5, |
595 | | detail: detail::Detail::Bool { bit: 3 }, |
596 | | }, |
597 | | detail::Descriptor { |
598 | | name: "enable_verifier", |
599 | | description: "Run the Cranelift IR verifier at strategic times during compilation.", |
600 | | offset: 5, |
601 | | detail: detail::Detail::Bool { bit: 4 }, |
602 | | }, |
603 | | detail::Descriptor { |
604 | | name: "is_pic", |
605 | | description: "Enable Position-Independent Code generation.", |
606 | | offset: 5, |
607 | | detail: detail::Detail::Bool { bit: 5 }, |
608 | | }, |
609 | | detail::Descriptor { |
610 | | name: "use_colocated_libcalls", |
611 | | description: "Use colocated libcalls.", |
612 | | offset: 5, |
613 | | detail: detail::Detail::Bool { bit: 6 }, |
614 | | }, |
615 | | detail::Descriptor { |
616 | | name: "avoid_div_traps", |
617 | | description: "Generate explicit checks around native division instructions to avoid their trapping.", |
618 | | offset: 5, |
619 | | detail: detail::Detail::Bool { bit: 7 }, |
620 | | }, |
621 | | detail::Descriptor { |
622 | | name: "enable_float", |
623 | | description: "Enable the use of floating-point instructions.", |
624 | | offset: 6, |
625 | | detail: detail::Detail::Bool { bit: 0 }, |
626 | | }, |
627 | | detail::Descriptor { |
628 | | name: "enable_nan_canonicalization", |
629 | | description: "Enable NaN canonicalization.", |
630 | | offset: 6, |
631 | | detail: detail::Detail::Bool { bit: 1 }, |
632 | | }, |
633 | | detail::Descriptor { |
634 | | name: "enable_pinned_reg", |
635 | | description: "Enable the use of the pinned register.", |
636 | | offset: 6, |
637 | | detail: detail::Detail::Bool { bit: 2 }, |
638 | | }, |
639 | | detail::Descriptor { |
640 | | name: "use_pinned_reg_as_heap_base", |
641 | | description: "Use the pinned register as the heap base.", |
642 | | offset: 6, |
643 | | detail: detail::Detail::Bool { bit: 3 }, |
644 | | }, |
645 | | detail::Descriptor { |
646 | | name: "enable_simd", |
647 | | description: "Enable the use of SIMD instructions.", |
648 | | offset: 6, |
649 | | detail: detail::Detail::Bool { bit: 4 }, |
650 | | }, |
651 | | detail::Descriptor { |
652 | | name: "enable_atomics", |
653 | | description: "Enable the use of atomic instructions", |
654 | | offset: 6, |
655 | | detail: detail::Detail::Bool { bit: 5 }, |
656 | | }, |
657 | | detail::Descriptor { |
658 | | name: "enable_safepoints", |
659 | | description: "Enable safepoint instruction insertions.", |
660 | | offset: 6, |
661 | | detail: detail::Detail::Bool { bit: 6 }, |
662 | | }, |
663 | | detail::Descriptor { |
664 | | name: "enable_llvm_abi_extensions", |
665 | | description: "Enable various ABI extensions defined by LLVM's behavior.", |
666 | | offset: 6, |
667 | | detail: detail::Detail::Bool { bit: 7 }, |
668 | | }, |
669 | | detail::Descriptor { |
670 | | name: "unwind_info", |
671 | | description: "Generate unwind information.", |
672 | | offset: 7, |
673 | | detail: detail::Detail::Bool { bit: 0 }, |
674 | | }, |
675 | | detail::Descriptor { |
676 | | name: "preserve_frame_pointers", |
677 | | description: "Preserve frame pointers", |
678 | | offset: 7, |
679 | | detail: detail::Detail::Bool { bit: 1 }, |
680 | | }, |
681 | | detail::Descriptor { |
682 | | name: "machine_code_cfg_info", |
683 | | description: "Generate CFG metadata for machine code.", |
684 | | offset: 7, |
685 | | detail: detail::Detail::Bool { bit: 2 }, |
686 | | }, |
687 | | detail::Descriptor { |
688 | | name: "enable_probestack", |
689 | | description: "Enable the use of stack probes for supported calling conventions.", |
690 | | offset: 7, |
691 | | detail: detail::Detail::Bool { bit: 3 }, |
692 | | }, |
693 | | detail::Descriptor { |
694 | | name: "probestack_func_adjusts_sp", |
695 | | description: "Enable if the stack probe adjusts the stack pointer.", |
696 | | offset: 7, |
697 | | detail: detail::Detail::Bool { bit: 4 }, |
698 | | }, |
699 | | detail::Descriptor { |
700 | | name: "enable_jump_tables", |
701 | | description: "Enable the use of jump tables in generated machine code.", |
702 | | offset: 7, |
703 | | detail: detail::Detail::Bool { bit: 5 }, |
704 | | }, |
705 | | detail::Descriptor { |
706 | | name: "enable_heap_access_spectre_mitigation", |
707 | | description: "Enable Spectre mitigation on heap bounds checks.", |
708 | | offset: 7, |
709 | | detail: detail::Detail::Bool { bit: 6 }, |
710 | | }, |
711 | | detail::Descriptor { |
712 | | name: "enable_table_access_spectre_mitigation", |
713 | | description: "Enable Spectre mitigation on table bounds checks.", |
714 | | offset: 7, |
715 | | detail: detail::Detail::Bool { bit: 7 }, |
716 | | }, |
717 | | detail::Descriptor { |
718 | | name: "enable_incremental_compilation_cache_checks", |
719 | | description: "Enable additional checks for debugging the incremental compilation cache.", |
720 | | offset: 8, |
721 | | detail: detail::Detail::Bool { bit: 0 }, |
722 | | }, |
723 | | ]; |
724 | | static ENUMERATORS: [&str; 16] = [ |
725 | | "none", |
726 | | "speed", |
727 | | "speed_and_size", |
728 | | "none", |
729 | | "elf_gd", |
730 | | "macho", |
731 | | "coff", |
732 | | "isa_default", |
733 | | "fast", |
734 | | "cold", |
735 | | "system_v", |
736 | | "windows_fastcall", |
737 | | "apple_aarch64", |
738 | | "probestack", |
739 | | "outline", |
740 | | "inline", |
741 | | ]; |
742 | | static HASH_TABLE: [u16; 64] = [ |
743 | | 0xffff, |
744 | | 0xffff, |
745 | | 0xffff, |
746 | | 1, |
747 | | 7, |
748 | | 0xffff, |
749 | | 28, |
750 | | 16, |
751 | | 17, |
752 | | 22, |
753 | | 25, |
754 | | 0xffff, |
755 | | 29, |
756 | | 0xffff, |
757 | | 19, |
758 | | 0xffff, |
759 | | 15, |
760 | | 0xffff, |
761 | | 0xffff, |
762 | | 0xffff, |
763 | | 0xffff, |
764 | | 0xffff, |
765 | | 0xffff, |
766 | | 0xffff, |
767 | | 0xffff, |
768 | | 0xffff, |
769 | | 0xffff, |
770 | | 4, |
771 | | 0, |
772 | | 10, |
773 | | 0xffff, |
774 | | 0xffff, |
775 | | 0xffff, |
776 | | 24, |
777 | | 0xffff, |
778 | | 14, |
779 | | 20, |
780 | | 9, |
781 | | 18, |
782 | | 0xffff, |
783 | | 5, |
784 | | 0xffff, |
785 | | 0xffff, |
786 | | 21, |
787 | | 3, |
788 | | 0xffff, |
789 | | 8, |
790 | | 0xffff, |
791 | | 0xffff, |
792 | | 27, |
793 | | 23, |
794 | | 12, |
795 | | 26, |
796 | | 6, |
797 | | 11, |
798 | | 2, |
799 | | 0xffff, |
800 | | 0xffff, |
801 | | 0xffff, |
802 | | 0xffff, |
803 | | 0xffff, |
804 | | 0xffff, |
805 | | 13, |
806 | | 0xffff, |
807 | | ]; |
808 | | static PRESETS: [(u8, u8); 0] = [ |
809 | | ]; |
810 | | static TEMPLATE: detail::Template = detail::Template { |
811 | | name: "shared", |
812 | | descriptors: &DESCRIPTORS, |
813 | | enumerators: &ENUMERATORS, |
814 | | hash_table: &HASH_TABLE, |
815 | | defaults: &[0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x21, 0xe1, 0x00], |
816 | | presets: &PRESETS, |
817 | | }; |
818 | | /// Create a `settings::Builder` for the shared settings group. |
819 | 10.0k | pub fn builder() -> Builder { |
820 | 10.0k | Builder::new(&TEMPLATE) |
821 | 10.0k | } |
822 | | impl fmt::Display for Flags { |
823 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
824 | 0 | writeln!(f, "[shared]")?; |
825 | 0 | for d in &DESCRIPTORS { |
826 | 0 | if !d.detail.is_preset() { |
827 | 0 | write!(f, "{} = ", d.name)?; |
828 | 0 | TEMPLATE.format_toml_value(d.detail, self.bytes[d.offset as usize], f)?; |
829 | 0 | writeln!(f)?; |
830 | 0 | } |
831 | | } |
832 | 0 | Ok(()) |
833 | 0 | } |
834 | | } |