1 use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
2 
3 pub(crate) fn define() -> SettingGroup {
4     let mut settings = SettingGroupBuilder::new("shared");
5 
6     settings.add_bool(
7         "regalloc_checker",
8         "Enable the symbolic checker for register allocation.",
9         r#"
10             This performs a verification that the register allocator preserves
11             equivalent dataflow with respect to the original (pre-regalloc)
12             program. This analysis is somewhat expensive. However, if it succeeds,
13             it provides independent evidence (by a carefully-reviewed, from-first-principles
14             analysis) that no regalloc bugs were triggered for the particular compilations
15             performed. This is a valuable assurance to have as regalloc bugs can be
16             very dangerous and difficult to debug.
17         "#,
18         false,
19     );
20 
21     settings.add_bool(
22         "regalloc_verbose_logs",
23         "Enable verbose debug logs for regalloc2.",
24         r#"
25             This adds extra logging for regalloc2 output, that is quite valuable to understand
26             decisions taken by the register allocator as well as debugging it. It is disabled by
27             default, as it can cause many log calls which can slow down compilation by a large
28             amount.
29         "#,
30         false,
31     );
32 
33     settings.add_enum(
34         "opt_level",
35         "Optimization level for generated code.",
36         r#"
37             Supported levels:
38 
39             - `none`: Minimise compile time by disabling most optimizations.
40             - `speed`: Generate the fastest possible code
41             - `speed_and_size`: like "speed", but also perform transformations aimed at reducing code size.
42         "#,
43         vec!["none", "speed", "speed_and_size"],
44     );
45 
46     settings.add_bool(
47         "enable_alias_analysis",
48         "Do redundant-load optimizations with alias analysis.",
49         r#"
50             This enables the use of a simple alias analysis to optimize away redundant loads.
51             Only effective when `opt_level` is `speed` or `speed_and_size`.
52         "#,
53         true,
54     );
55 
56     settings.add_bool(
57         "enable_verifier",
58         "Run the Cranelift IR verifier at strategic times during compilation.",
59         r#"
60             This makes compilation slower but catches many bugs. The verifier is always enabled by
61             default, which is useful during development.
62         "#,
63         true,
64     );
65 
66     // Note that Cranelift doesn't currently need an is_pie flag, because PIE is
67     // just PIC where symbols can't be pre-empted, which can be expressed with the
68     // `colocated` flag on external functions and global values.
69     settings.add_bool(
70         "is_pic",
71         "Enable Position-Independent Code generation.",
72         "",
73         false,
74     );
75 
76     settings.add_bool(
77         "use_colocated_libcalls",
78         "Use colocated libcalls.",
79         r#"
80             Generate code that assumes that libcalls can be declared "colocated",
81             meaning they will be defined along with the current function, such that
82             they can use more efficient addressing.
83         "#,
84         false,
85     );
86 
87     settings.add_bool(
88         "enable_float",
89         "Enable the use of floating-point instructions.",
90         r#"
91             Disabling use of floating-point instructions is not yet implemented.
92         "#,
93         true,
94     );
95 
96     settings.add_bool(
97         "enable_nan_canonicalization",
98         "Enable NaN canonicalization.",
99         r#"
100             This replaces NaNs with a single canonical value, for users requiring
101             entirely deterministic WebAssembly computation. This is not required
102             by the WebAssembly spec, so it is not enabled by default.
103         "#,
104         false,
105     );
106 
107     settings.add_bool(
108         "enable_pinned_reg",
109         "Enable the use of the pinned register.",
110         r#"
111             This register is excluded from register allocation, and is completely under the control of
112             the end-user. It is possible to read it via the get_pinned_reg instruction, and to set it
113             with the set_pinned_reg instruction.
114         "#,
115         false,
116     );
117 
118     settings.add_bool(
119         "enable_atomics",
120         "Enable the use of atomic instructions",
121         "",
122         true,
123     );
124 
125     settings.add_bool(
126         "enable_safepoints",
127         "Enable safepoint instruction insertions.",
128         r#"
129             This will allow the emit_stack_maps() function to insert the safepoint
130             instruction on top of calls and interrupt traps in order to display the
131             live reference values at that point in the program.
132         "#,
133         false,
134     );
135 
136     settings.add_enum(
137         "tls_model",
138         "Defines the model used to perform TLS accesses.",
139         "",
140         vec!["none", "elf_gd", "macho", "coff"],
141     );
142 
143     settings.add_enum(
144         "libcall_call_conv",
145         "Defines the calling convention to use for LibCalls call expansion.",
146         r#"
147             This may be different from the ISA default calling convention.
148 
149             The default value is to use the same calling convention as the ISA
150             default calling convention.
151 
152             This list should be kept in sync with the list of calling
153             conventions available in isa/call_conv.rs.
154         "#,
155         vec![
156             "isa_default",
157             "fast",
158             "cold",
159             "system_v",
160             "windows_fastcall",
161             "apple_aarch64",
162             "probestack",
163         ],
164     );
165 
166     settings.add_bool(
167         "enable_llvm_abi_extensions",
168         "Enable various ABI extensions defined by LLVM's behavior.",
169         r#"
170             In some cases, LLVM's implementation of an ABI (calling convention)
171             goes beyond a standard and supports additional argument types or
172             behavior. This option instructs Cranelift codegen to follow LLVM's
173             behavior where applicable.
174 
175             Currently, this applies only to Windows Fastcall on x86-64, and
176             allows an `i128` argument to be spread across two 64-bit integer
177             registers. The Fastcall implementation otherwise does not support
178             `i128` arguments, and will panic if they are present and this
179             option is not set.
180         "#,
181         false,
182     );
183 
184     settings.add_bool(
185         "unwind_info",
186         "Generate unwind information.",
187         r#"
188             This increases metadata size and compile time, but allows for the
189             debugger to trace frames, is needed for GC tracing that relies on
190             libunwind (such as in Wasmtime), and is unconditionally needed on
191             certain platforms (such as Windows) that must always be able to unwind.
192           "#,
193         true,
194     );
195 
196     settings.add_bool(
197         "preserve_frame_pointers",
198         "Preserve frame pointers",
199         r#"
200             Preserving frame pointers -- even inside leaf functions -- makes it
201             easy to capture the stack of a running program, without requiring any
202             side tables or metadata (like `.eh_frame` sections). Many sampling
203             profilers and similar tools walk frame pointers to capture stacks.
204             Enabling this option will play nice with those tools.
205         "#,
206         false,
207     );
208 
209     settings.add_bool(
210         "machine_code_cfg_info",
211         "Generate CFG metadata for machine code.",
212         r#"
213             This increases metadata size and compile time, but allows for the
214             embedder to more easily post-process or analyze the generated
215             machine code. It provides code offsets for the start of each
216             basic block in the generated machine code, and a list of CFG
217             edges (with blocks identified by start offsets) between them.
218             This is useful for, e.g., machine-code analyses that verify certain
219             properties of the generated code.
220         "#,
221         false,
222     );
223 
224     // Stack probing options.
225 
226     settings.add_bool(
227         "enable_probestack",
228         "Enable the use of stack probes for supported calling conventions.",
229         "",
230         false,
231     );
232 
233     settings.add_bool(
234         "probestack_func_adjusts_sp",
235         "Enable if the stack probe adjusts the stack pointer.",
236         "",
237         false,
238     );
239 
240     settings.add_num(
241         "probestack_size_log2",
242         "The log2 of the size of the stack guard region.",
243         r#"
244             Stack frames larger than this size will have stack overflow checked
245             by calling the probestack function.
246 
247             The default is 12, which translates to a size of 4096.
248         "#,
249         12,
250     );
251 
252     settings.add_enum(
253         "probestack_strategy",
254         "Controls what kinds of stack probes are emitted.",
255         r#"
256             Supported strategies:
257 
258             - `outline`: Always emits stack probes as calls to a probe stack function.
259             - `inline`: Always emits inline stack probes.
260         "#,
261         vec!["outline", "inline"],
262     );
263 
264     // Jump table options.
265 
266     settings.add_bool(
267         "enable_jump_tables",
268         "Enable the use of jump tables in generated machine code.",
269         "",
270         true,
271     );
272 
273     // Spectre options.
274 
275     settings.add_bool(
276         "enable_heap_access_spectre_mitigation",
277         "Enable Spectre mitigation on heap bounds checks.",
278         r#"
279             This is a no-op for any heap that needs no bounds checks; e.g.,
280             if the limit is static and the guard region is large enough that
281             the index cannot reach past it.
282 
283             This option is enabled by default because it is highly
284             recommended for secure sandboxing. The embedder should consider
285             the security implications carefully before disabling this option.
286         "#,
287         true,
288     );
289 
290     settings.add_bool(
291         "enable_table_access_spectre_mitigation",
292         "Enable Spectre mitigation on table bounds checks.",
293         r#"
294             This option uses a conditional move to ensure that when a table
295             access index is bounds-checked and a conditional branch is used
296             for the out-of-bounds case, a misspeculation of that conditional
297             branch (falsely predicted in-bounds) will select an in-bounds
298             index to load on the speculative path.
299 
300             This option is enabled by default because it is highly
301             recommended for secure sandboxing. The embedder should consider
302             the security implications carefully before disabling this option.
303         "#,
304         true,
305     );
306 
307     settings.add_bool(
308         "enable_incremental_compilation_cache_checks",
309         "Enable additional checks for debugging the incremental compilation cache.",
310         r#"
311             Enables additional checks that are useful during development of the incremental
312             compilation cache. This should be mostly useful for Cranelift hackers, as well as for
313             helping to debug false incremental cache positives for embedders.
314 
315             This option is disabled by default and requires enabling the "incremental-cache" Cargo
316             feature in cranelift-codegen.
317         "#,
318         false,
319     );
320 
321     settings.add_num(
322         "bb_padding_log2_minus_one",
323         "The log2 of the size to insert dummy padding between basic blocks",
324         r#"
325             This is a debugging option for stressing various cases during code
326             generation without requiring large functions. This will insert
327             0-byte padding between basic blocks of the specified size.
328 
329             The amount of padding inserted two raised to the power of this value
330             minus one. If this value is 0 then no padding is inserted.
331 
332             The default for this option is 0 to insert no padding as it's only
333             intended for testing and development.
334         "#,
335         0,
336     );
337 
338     // When adding new settings please check if they can also be added
339     // in cranelift/fuzzgen/src/lib.rs for fuzzing.
340     settings.build()
341 }
342