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         "avoid_div_traps",
89         "Generate explicit checks around native division instructions to avoid their trapping.",
90         r#"
91             Generate explicit checks around native division instructions to
92             avoid their trapping.
93 
94             On ISAs like ARM where the native division instructions don't trap,
95             this setting has no effect - explicit checks are always inserted.
96         "#,
97         false,
98     );
99 
100     settings.add_bool(
101         "enable_float",
102         "Enable the use of floating-point instructions.",
103         r#"
104             Disabling use of floating-point instructions is not yet implemented.
105         "#,
106         true,
107     );
108 
109     settings.add_bool(
110         "enable_nan_canonicalization",
111         "Enable NaN canonicalization.",
112         r#"
113             This replaces NaNs with a single canonical value, for users requiring
114             entirely deterministic WebAssembly computation. This is not required
115             by the WebAssembly spec, so it is not enabled by default.
116         "#,
117         false,
118     );
119 
120     settings.add_bool(
121         "enable_pinned_reg",
122         "Enable the use of the pinned register.",
123         r#"
124             This register is excluded from register allocation, and is completely under the control of
125             the end-user. It is possible to read it via the get_pinned_reg instruction, and to set it
126             with the set_pinned_reg instruction.
127         "#,
128         false,
129     );
130 
131     settings.add_bool(
132         "use_pinned_reg_as_heap_base",
133         "Use the pinned register as the heap base.",
134         r#"
135             Enabling this requires the enable_pinned_reg setting to be set to true. It enables a custom
136             legalization of the `heap_addr` instruction so it will use the pinned register as the heap
137             base, instead of fetching it from a global value.
138 
139             Warning! Enabling this means that the pinned register *must* be maintained to contain the
140             heap base address at all times, during the lifetime of a function. Using the pinned
141             register for other purposes when this is set is very likely to cause crashes.
142         "#,
143         false,
144     );
145 
146     settings.add_bool(
147         "enable_simd",
148         "Enable the use of SIMD instructions.",
149         "",
150         false,
151     );
152 
153     settings.add_bool(
154         "enable_atomics",
155         "Enable the use of atomic instructions",
156         "",
157         true,
158     );
159 
160     settings.add_bool(
161         "enable_safepoints",
162         "Enable safepoint instruction insertions.",
163         r#"
164             This will allow the emit_stack_maps() function to insert the safepoint
165             instruction on top of calls and interrupt traps in order to display the
166             live reference values at that point in the program.
167         "#,
168         false,
169     );
170 
171     settings.add_enum(
172         "tls_model",
173         "Defines the model used to perform TLS accesses.",
174         "",
175         vec!["none", "elf_gd", "macho", "coff"],
176     );
177 
178     settings.add_enum(
179         "libcall_call_conv",
180         "Defines the calling convention to use for LibCalls call expansion.",
181         r#"
182             This may be different from the ISA default calling convention.
183 
184             The default value is to use the same calling convention as the ISA
185             default calling convention.
186 
187             This list should be kept in sync with the list of calling
188             conventions available in isa/call_conv.rs.
189         "#,
190         vec![
191             "isa_default",
192             "fast",
193             "cold",
194             "system_v",
195             "windows_fastcall",
196             "apple_aarch64",
197             "probestack",
198         ],
199     );
200 
201     settings.add_bool(
202         "enable_llvm_abi_extensions",
203         "Enable various ABI extensions defined by LLVM's behavior.",
204         r#"
205             In some cases, LLVM's implementation of an ABI (calling convention)
206             goes beyond a standard and supports additional argument types or
207             behavior. This option instructs Cranelift codegen to follow LLVM's
208             behavior where applicable.
209 
210             Currently, this applies only to Windows Fastcall on x86-64, and
211             allows an `i128` argument to be spread across two 64-bit integer
212             registers. The Fastcall implementation otherwise does not support
213             `i128` arguments, and will panic if they are present and this
214             option is not set.
215         "#,
216         false,
217     );
218 
219     settings.add_bool(
220         "unwind_info",
221         "Generate unwind information.",
222         r#"
223             This increases metadata size and compile time, but allows for the
224             debugger to trace frames, is needed for GC tracing that relies on
225             libunwind (such as in Wasmtime), and is unconditionally needed on
226             certain platforms (such as Windows) that must always be able to unwind.
227           "#,
228         true,
229     );
230 
231     settings.add_bool(
232         "preserve_frame_pointers",
233         "Preserve frame pointers",
234         r#"
235             Preserving frame pointers -- even inside leaf functions -- makes it
236             easy to capture the stack of a running program, without requiring any
237             side tables or metadata (like `.eh_frame` sections). Many sampling
238             profilers and similar tools walk frame pointers to capture stacks.
239             Enabling this option will play nice with those tools.
240         "#,
241         false,
242     );
243 
244     settings.add_bool(
245         "machine_code_cfg_info",
246         "Generate CFG metadata for machine code.",
247         r#"
248             This increases metadata size and compile time, but allows for the
249             embedder to more easily post-process or analyze the generated
250             machine code. It provides code offsets for the start of each
251             basic block in the generated machine code, and a list of CFG
252             edges (with blocks identified by start offsets) between them.
253             This is useful for, e.g., machine-code analyses that verify certain
254             properties of the generated code.
255         "#,
256         false,
257     );
258 
259     // Stack probing options.
260 
261     settings.add_bool(
262         "enable_probestack",
263         "Enable the use of stack probes for supported calling conventions.",
264         "",
265         true,
266     );
267 
268     settings.add_bool(
269         "probestack_func_adjusts_sp",
270         "Enable if the stack probe adjusts the stack pointer.",
271         "",
272         false,
273     );
274 
275     settings.add_num(
276         "probestack_size_log2",
277         "The log2 of the size of the stack guard region.",
278         r#"
279             Stack frames larger than this size will have stack overflow checked
280             by calling the probestack function.
281 
282             The default is 12, which translates to a size of 4096.
283         "#,
284         12,
285     );
286 
287     // Jump table options.
288 
289     settings.add_bool(
290         "enable_jump_tables",
291         "Enable the use of jump tables in generated machine code.",
292         "",
293         true,
294     );
295 
296     // Spectre options.
297 
298     settings.add_bool(
299         "enable_heap_access_spectre_mitigation",
300         "Enable Spectre mitigation on heap bounds checks.",
301         r#"
302             This is a no-op for any heap that needs no bounds checks; e.g.,
303             if the limit is static and the guard region is large enough that
304             the index cannot reach past it.
305 
306             This option is enabled by default because it is highly
307             recommended for secure sandboxing. The embedder should consider
308             the security implications carefully before disabling this option.
309         "#,
310         true,
311     );
312 
313     settings.add_bool(
314         "enable_table_access_spectre_mitigation",
315         "Enable Spectre mitigation on table bounds checks.",
316         r#"
317             This option uses a conditional move to ensure that when a table
318             access index is bounds-checked and a conditional branch is used
319             for the out-of-bounds case, a misspeculation of that conditional
320             branch (falsely predicted in-bounds) will select an in-bounds
321             index to load on the speculative path.
322 
323             This option is enabled by default because it is highly
324             recommended for secure sandboxing. The embedder should consider
325             the security implications carefully before disabling this option.
326         "#,
327         true,
328     );
329 
330     settings.build()
331 }
332