xref: /wasmtime-44.0.1/cranelift/docs/ir.md (revision 63360659)
1# Cranelift IR Reference
2
3## Foreword
4
5This document is likely to be outdated and missing some important
6information. It is recommended to look at the list of instructions as
7documented in [the `InstBuilder` documentation].
8
9[the `InstBuilder` documentation]: https://docs.rs/cranelift-codegen/latest/cranelift_codegen/ir/trait.InstBuilder.html
10
11## Intro
12
13The Cranelift intermediate representation ([IR]) has two primary forms:
14an *in-memory data structure* that the code generator library is using, and a
15*text format* which is used for test cases and debug output.
16Files containing Cranelift textual IR have the `.clif` filename extension.
17
18This reference uses the text format to describe IR semantics but glosses over
19the finer details of the lexical and syntactic structure of the format.
20
21## Overall structure
22
23Cranelift compiles functions independently. A `.clif` IR file may contain
24multiple functions, and the programmatic API can create multiple function
25handles at the same time, but the functions don't share any data or reference
26each other directly.
27
28This is a simple C function that computes the average of an array of floats:
29
30```c
31float average(const float *array, size_t count)
32{
33    double sum = 0;
34    for (size_t i = 0; i < count; i++)
35        sum += array[i];
36    return sum / count;
37}
38```
39
40Here is the same function compiled into Cranelift IR (with 64 bit pointers):
41
42```
43test verifier
44
45function %average(i64, i64) -> f32 system_v {
46    ss0 = explicit_slot 8         ; Stack slot for `sum`.
47
48block1(v0: i64, v1: i64):
49    v2 = f64const 0x0.0
50    stack_store v2, ss0
51    brif v1, block2, block5                  ; Handle count == 0.
52
53block2:
54    v3 = iconst.i64 0
55    jump block3(v3)
56
57block3(v4: i64):
58    v5 = imul_imm v4, 4
59    v6 = iadd v0, v5
60    v7 = load.f32 v6              ; array[i]
61    v8 = fpromote.f64 v7
62    v9 = stack_load.f64 ss0
63    v10 = fadd v8, v9
64    stack_store v10, ss0
65    v11 = iadd_imm v4, 1
66    v12 = icmp ult v11, v1
67    brif v12, block3(v11), block4 ; Loop backedge.
68
69block4:
70    v13 = stack_load.f64 ss0
71    v14 = fcvt_from_uint.f64 v1
72    v15 = fdiv v13, v14
73    v16 = fdemote.f32 v15
74    return v16
75
76block5:
77    v100 = f32const +NaN
78    return v100
79}
80```
81
82The first line of a function definition provides the function *name* and
83the [function signature] which declares the parameter and return types.
84Then follows the [function preamble] which declares a number of entities
85that can be referenced inside the function. In the example above, the preamble
86declares a single explicit stack slot, `ss0`.
87
88After the preamble follows the [function body] which consists of [basic block]s
89(BBs), the first of which is the [entry block]. Every BB ends with a
90[terminator instruction], so execution can never fall through to the next BB
91without an explicit branch.
92
93A `.clif` file consists of a sequence of independent function definitions:
94
95```
96function_list : { function }
97function      : "function" function_name signature "{" preamble function_body "}"
98preamble      : { preamble_decl }
99function_body : { basic_block }
100```
101
102### Static single assignment form
103
104The instructions in the function body use and produce *values* in SSA form. This
105means that every value is defined exactly once, and every use of a value must be
106dominated by the definition.
107
108Cranelift does not have phi instructions but uses [BB parameter]s
109instead. A BB can be defined with a list of typed parameters. Whenever control
110is transferred to the BB, argument values for the parameters must be provided.
111When entering a function, the incoming function parameters are passed as
112arguments to the entry BB's parameters.
113
114Instructions define zero, one, or more result values. All SSA values are either
115BB parameters or instruction results.
116
117In the example above, the loop induction variable `i` is represented
118as three SSA values: In `block2`, `v3` is the initial value. In the
119loop block `block3`, the BB parameter `v4` represents the value of the
120induction variable during each iteration. Finally, `v11` is computed
121as the induction variable value for the next iteration.
122
123The `cranelift_frontend` crate contains utilities for translating from programs
124containing multiple assignments to the same variables into SSA form for
125Cranelift [IR].
126
127Such variables can also be presented to Cranelift as [stack slot]s.
128Stack slots are accessed with the `stack_store` and `stack_load` instructions,
129and can have their address taken with `stack_addr`, which supports C-like
130programming languages where local variables can have their address taken.
131
132## Value types
133
134All SSA values have a type which determines the size and shape (for SIMD
135vectors) of the value. Many instructions are polymorphic -- they can operate on
136different types.
137
138### Integer types
139
140Integer values have a fixed size and can be interpreted as either signed or
141unsigned. Some instructions will interpret an operand as a signed or unsigned
142number, others don't care.
143
144- i8
145- i16
146- i32
147- i64
148- i128
149
150Of these types, i32 and i64 are the most heavily-tested because of their use by
151Wasmtime. There are no known bugs in i8, i16, and i128, but their use may not
152be supported by all instructions in all backends (that is, they may cause
153the compiler to crash during code generation with an error that an instruction
154is unsupported).
155
156The function `valid_for_target` within the [fuzzgen function generator][fungen]
157contains information about which instructions support which types.
158
159[fungen]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/fuzzgen/src/function_generator.rs
160
161### Floating point types
162
163The floating point types have the IEEE 754 semantics that are supported by most
164hardware, except that non-default rounding modes, unmasked exceptions, and
165exception flags are not currently supported.
166
167There is currently no support for higher-precision types like quad-precision,
168double-double, or extended-precision, nor for narrower-precision types like
169half-precision.
170
171NaNs are encoded following the IEEE 754-2008 recommendation, with quiet NaN
172being encoded with the MSB of the trailing significand set to 1, and signaling
173NaNs being indicated by the MSB of the trailing significand set to 0.
174
175Except for bitwise and memory instructions, NaNs returned from arithmetic
176instructions are encoded as follows:
177
178- If all NaN inputs to an instruction are quiet NaNs with all bits of the
179  trailing significand other than the MSB set to 0, the result is a quiet
180  NaN with a nondeterministic sign bit and all bits of the trailing
181  significand other than the MSB set to 0.
182- Otherwise the result is a quiet NaN with a nondeterministic sign bit
183  and all bits of the trailing significand other than the MSB set to
184  nondeterministic values.
185
186- f32
187- f64
188
189### SIMD vector types
190
191A SIMD vector type represents a vector of values from one of the scalar types
192(integer, and floating point). Each scalar value in a SIMD type is called a
193*lane*. The number of lanes must be a power of two in the range 2-256.
194
195i%Bx%N
196    A SIMD vector of integers. The lane type `iB` is one of the integer
197    types `i8` ... `i64`.
198
199    Some concrete integer vector types are `i32x4`, `i64x8`, and
200    `i16x4`.
201
202    The size of a SIMD integer vector in memory is :math:`N B\over 8` bytes.
203
204f32x%N
205    A SIMD vector of single precision floating point numbers.
206
207    Some concrete `f32` vector types are: `f32x2`, `f32x4`,
208    and `f32x8`.
209
210    The size of a `f32` vector in memory is :math:`4N` bytes.
211
212f64x%N
213    A SIMD vector of double precision floating point numbers.
214
215    Some concrete `f64` vector types are: `f64x2`, `f64x4`,
216    and `f64x8`.
217
218    The size of a `f64` vector in memory is :math:`8N` bytes.
219
220### Pseudo-types and type classes
221
222These are not concrete types, but convenient names used to refer to real types
223in this reference.
224
225iAddr
226    A Pointer-sized integer representing an address.
227
228    This is either `i32`, or `i64`, depending on whether the target
229    platform has 32-bit or 64-bit pointers.
230
231iB
232    Any of the scalar integer types `i8` -- `i64`.
233
234Int
235    Any scalar *or vector* integer type: `iB` or `iBxN`.
236
237fB
238    Either of the floating point scalar types: `f32` or `f64`.
239
240Float
241    Any scalar *or vector* floating point type: `fB` or `fBxN`.
242
243%Tx%N
244    Any SIMD vector type.
245
246Mem
247    Any type that can be stored in memory: `Int` or `Float`.
248
249Testable
250    `iN`
251
252### Immediate operand types
253
254These types are not part of the normal SSA type system. They are used to
255indicate the different kinds of immediate operands on an instruction.
256
257imm64
258    A 64-bit immediate integer. The value of this operand is interpreted as a
259    signed two's complement integer. Instruction encodings may limit the valid
260    range.
261
262    In the textual format, `imm64` immediates appear as decimal or
263    hexadecimal literals using the same syntax as C.
264
265offset32
266    A signed 32-bit immediate address offset.
267
268    In the textual format, `offset32` immediates always have an explicit
269    sign, and a 0 offset may be omitted.
270
271ieee32
272    A 32-bit immediate floating point number in the IEEE 754-2008 binary32
273    interchange format. All bit patterns are allowed.
274
275ieee64
276    A 64-bit immediate floating point number in the IEEE 754-2008 binary64
277    interchange format. All bit patterns are allowed.
278
279intcc
280    An integer condition code. See the `icmp` instruction for details.
281
282floatcc
283    A floating point condition code. See the `fcmp` instruction for details.
284
285The two IEEE floating point immediate types `ieee32` and `ieee64`
286are displayed as hexadecimal floating point literals in the textual [IR]
287format. Decimal floating point literals are not allowed because some computer
288systems can round differently when converting to binary. The hexadecimal
289floating point format is mostly the same as the one used by C99, but extended
290to represent all NaN bit patterns:
291
292Normal numbers
293    Compatible with C99: `-0x1.Tpe` where `T` are the trailing
294    significand bits encoded as hexadecimal, and `e` is the unbiased exponent
295    as a decimal number. `ieee32` has 23 trailing significand bits. They
296    are padded with an extra LSB to produce 6 hexadecimal digits. This is not
297    necessary for `ieee64` which has 52 trailing significand bits
298    forming 13 hexadecimal digits with no padding.
299
300Zeros
301    Positive and negative zero are displayed as `0.0` and `-0.0` respectively.
302
303Subnormal numbers
304    Compatible with C99: `-0x0.Tpemin` where `T` are the trailing
305    significand bits encoded as hexadecimal, and `emin` is the minimum exponent
306    as a decimal number.
307
308Infinities
309    Either `-Inf` or `Inf`.
310
311Quiet NaNs
312    Quiet NaNs have the MSB of the trailing significand set. If the remaining
313    bits of the trailing significand are all zero, the value is displayed as
314    `-NaN` or `NaN`. Otherwise, `-NaN:0xT` where `T` are the trailing
315    significand bits encoded as hexadecimal.
316
317Signaling NaNs
318    Displayed as `-sNaN:0xT`.
319
320
321## Control flow
322
323Branches transfer control to a new BB and provide values for the target BB's
324arguments, if it has any. Conditional branches terminate a BB, and transfer to
325the first BB if the condition is satisfied, and the second otherwise.
326
327The `br_table v, BB(args), [BB1(args)...BBn(args)]` looks up the index `v` in
328the inline jump table given as the third argument, and jumps to that BB. If `v`
329is out of bounds for the jump table, the default BB (second argument) is used
330instead.
331
332Traps stop the program because something went wrong. The exact behavior depends
333on the target instruction set architecture and operating system. There are
334explicit trap instructions defined below, but some instructions may also cause
335traps for certain input value. For example, `udiv` traps when the divisor
336is zero.
337
338
339## Function calls
340
341A function call needs a target function and a [function signature]. The
342target function may be determined dynamically at runtime, but the signature must
343be known when the function call is compiled. The function signature describes
344how to call the function, including parameters, return values, and the calling
345convention:
346
347```
348signature    : "(" [paramlist] ")" ["->" retlist] [call_conv]
349paramlist    : param { "," param }
350retlist      : paramlist
351param        : type [paramext] [paramspecial]
352paramext     : "uext" | "sext"
353paramspecial : "sarg" ( num ) | "sret" | "vmctx" | "stack_limit"
354callconv     : "fast" | "cold" | "system_v" | "windows_fastcall"
355             | "apple_aarch64" | "probestack" | "winch"
356```
357
358A function's calling convention determines exactly how arguments and return
359values are passed, and how stack frames are managed. Since all of these details
360depend on both the instruction set /// architecture and possibly the operating
361system, a function's calling convention is only fully determined by a
362`(TargetIsa, CallConv)` tuple.
363
364| Name      | Description |
365| ----------| ----------  |
366| sarg      | pointer to a struct argument of the given size |
367| sret      | pointer to a return value in memory |
368| vmctx     | VM context pointer, which may contain pointers to heaps etc. |
369| stack_limit | limit value for the size of the stack |
370
371| Name      | Description |
372| --------- | ----------- |
373| fast      |  not-ABI-stable convention for best performance |
374| cold      |  not-ABI-stable convention for infrequently executed code |
375| system_v  |  System V-style convention used on many platforms |
376| fastcall  |  Windows "fastcall" convention, also used for x64 and ARM |
377
378The "not-ABI-stable" conventions do not follow an external specification and
379may change between versions of Cranelift.
380
381The "fastcall" convention is not yet implemented.
382
383Parameters and return values have flags whose meaning is mostly target
384dependent. These flags support interfacing with code produced by other
385compilers.
386
387Functions that are called directly must be declared in the [function preamble]:
388
389FN = [colocated] NAME signature
390    Declare a function so it can be called directly.
391
392    If the colocated keyword is present, the symbol's definition will be
393    defined along with the current function, such that it can use more
394    efficient addressing.
395
396    :arg NAME: Name of the function, passed to the linker for resolution.
397    :arg signature: Function signature. See below.
398    :result FN: A function identifier that can be used with `call`.
399
400This simple example illustrates direct function calls and signatures:
401
402```
403test verifier
404
405function %gcd(i32 uext, i32 uext) -> i32 uext system_v {
406    fn0 = %divmod(i32 uext, i32 uext) -> i32 uext, i32 uext
407
408block1(v0: i32, v1: i32):
409    brif v1, block2, block3
410
411block2:
412    v2, v3 = call fn0(v0, v1)
413    return v2
414
415block3:
416    return v0
417}
418```
419
420Indirect function calls use a signature declared in the preamble.
421
422## Memory
423
424Cranelift provides fully general `load` and `store` instructions for accessing
425memory, as well as [extending loads and truncating stores](#extending-loads-and-truncating-stores).
426
427If the memory at the given address is not [addressable], the behavior of
428these instructions is undefined. If it is addressable but not
429[accessible], they [trap].
430
431There are also more restricted operations for accessing specific types of memory
432objects.
433
434Additionally, instructions are provided for handling multi-register addressing.
435
436### Memory operation flags
437
438Loads and stores can have flags that loosen their semantics in order to enable
439optimizations.
440
441| Flag     | Description |
442| -------- | ----------- |
443| notrap   | Memory is assumed to be [accessible]. |
444| aligned  | Trapping allowed for misaligned accesses. |
445| readonly | The data at the specified address will not modified between when this function is called and exited. |
446
447When the `accessible` flag is set, the behavior is undefined if the memory
448is not [accessible].
449
450Loads and stores are *misaligned* if the resultant address is not a multiple of
451the expected alignment. By default, misaligned loads and stores are allowed,
452but when the `aligned` flag is set, a misaligned memory access is allowed to
453[trap].
454
455### Explicit Stack Slots
456
457One set of restricted memory operations access the current function's stack
458frame. The stack frame is divided into fixed-size stack slots that are
459allocated in the [function preamble]. Stack slots are not typed, they
460simply represent a contiguous sequence of [accessible] bytes in the stack
461frame.
462
463SS = explicit_slot Bytes, Flags...
464    Allocate a stack slot in the preamble.
465
466    If no alignment is specified, Cranelift will pick an appropriate alignment
467    for the stack slot based on its size and access patterns.
468
469    :arg Bytes: Stack slot size on bytes.
470    :flag align(N): Request at least N bytes alignment.
471    :result SS: Stack slot index.
472
473The dedicated stack access instructions are easy for the compiler to reason
474about because stack slots and offsets are fixed at compile time. For example,
475the alignment of these stack memory accesses can be inferred from the offsets
476and stack slot alignments.
477
478It's also possible to obtain the address of a stack slot, which can be used
479in [unrestricted loads and stores](#memory).
480
481The `stack_addr` instruction can be used to macro-expand the stack access
482instructions before instruction selection:
483
484    v0 = stack_load.f64 ss3, 16
485    ; Expands to:
486    v1 = stack_addr ss3, 16
487    v0 = load.f64 v1
488
489When Cranelift code is running in a sandbox, it can also be necessary to include
490stack overflow checks in the prologue.
491
492### Global values
493
494A *global value* is an object whose value is not known at compile time. The
495value is computed at runtime by `global_value`, possibly using
496information provided by the linker via relocations. There are multiple
497kinds of global values using different methods for determining their value.
498Cranelift does not track the type of a global value, for they are just
499values stored in non-stack memory.
500
501When Cranelift is generating code for a virtual machine environment, globals can
502be used to access data structures in the VM's runtime. This requires functions
503to have access to a *VM context pointer* which is used as the base address.
504Typically, the VM context pointer is passed as a hidden function argument to
505Cranelift functions.
506
507Chains of global value expressions are possible, but cycles are not allowed.
508They will be caught by the IR verifier.
509
510GV = vmctx
511    Declare a global value of the address of the VM context struct.
512
513    This declares a global value which is the VM context pointer which may
514    be passed as a hidden argument to functions JIT-compiled for a VM.
515
516    Typically, the VM context is a `#[repr(C, packed)]` struct.
517
518    :result GV: Global value.
519
520A global value can also be derived by treating another global variable as a
521struct pointer and loading from one of its fields. This makes it possible to
522chase pointers into VM runtime data structures.
523
524GV = load.Type BaseGV [Offset]
525    Declare a global value pointed to by BaseGV plus Offset, with type Type.
526
527    It is assumed the BaseGV plus Offset resides in accessible memory with the
528    appropriate alignment for storing a value with type Type.
529
530    :arg BaseGV: Global value providing the base pointer.
531    :arg Offset: Offset added to the base before loading.
532    :result GV: Global value.
533
534GV = iadd_imm BaseGV, Offset
535    Declare a global value which has the value of BaseGV offset by Offset.
536
537    :arg BaseGV: Global value providing the base value.
538    :arg Offset: Offset added to the base value.
539
540GV = [colocated] symbol Name
541    Declare a symbolic address global value.
542
543    The value of GV is symbolic and will be assigned a relocation, so that
544    it can be resolved by a later linking phase.
545
546    If the colocated keyword is present, the symbol's definition will be
547    defined along with the current function, such that it can use more
548    efficient addressing.
549
550    :arg Name: External name.
551    :result GV: Global value.
552
553### Constant materialization
554
555A few instructions have variants that take immediate operands, but in general
556an instruction is required to load a constant into an SSA value: `iconst`,
557`f32const` and `f64const` serve this purpose.
558
559### Bitwise operations
560
561The bitwise operations and operate on any value type: Integers, and floating
562point numbers. When operating on integer or floating point types, the bitwise
563operations are working on the binary representation of the values.
564
565The shift and rotate operations only work on integer types (scalar and vector).
566The shift amount does not have to be the same type as the value being shifted.
567Only the low `B` bits of the shift amount is significant.
568
569When operating on an integer vector type, the shift amount is still a scalar
570type, and all the lanes are shifted the same amount. The shift amount is masked
571to the number of bits in a *lane*, not the full size of the vector type.
572
573The bit-counting instructions are scalar only.
574
575### Floating point operations
576
577These operations generally follow IEEE 754-2008 semantics.
578
579#### Sign bit manipulations
580
581The sign manipulating instructions work as bitwise operations, so they don't
582have special behavior for signaling NaN operands. The exponent and trailing
583significand bits are always preserved.
584
585#### Minimum and maximum
586
587These instructions return the larger or smaller of their operands. Note that
588unlike the IEEE 754-2008 `minNum` and `maxNum` operations, these instructions
589return NaN when either input is NaN.
590
591When comparing zeroes, these instructions behave as if :math:`-0.0 < 0.0`.
592
593#### Rounding
594
595These instructions round their argument to a nearby integral value, still
596represented as a floating point number.
597
598### Extending loads and truncating stores
599
600Most ISAs provide instructions that load an integer value smaller than a register
601and extends it to the width of the register. Similarly, store instructions that
602only write the low bits of an integer register are common.
603
604In addition to the normal `load` and `store` instructions, Cranelift
605provides extending loads and truncation stores for 8, 16, and 32-bit memory
606accesses.
607
608These instructions succeed, trap, or have undefined behavior, under the same
609conditions as [normal loads and stores](#memory).
610
611## ISA-specific instructions
612
613Target ISAs can define supplemental instructions that do not make sense to
614support generally.
615
616### x86
617
618Instructions that can only be used by the x86 target ISA.
619
620## Codegen implementation instructions
621
622Frontends don't need to emit the instructions in this section themselves;
623Cranelift will generate them automatically as needed.
624
625### Legalization operations
626
627These instructions are used as helpers when legalizing types and operations for
628the target ISA.
629
630### Special register operations
631
632The prologue and epilogue of a function needs to manipulate special registers like the stack
633pointer and the frame pointer. These instructions should not be used in regular code.
634
635### CPU flag operations
636
637These operations are for working with the "flags" registers of some CPU
638architectures.
639
640### Live range splitting
641
642Cranelift's register allocator assigns each SSA value to a register or a spill
643slot on the stack for its entire live range. Since the live range of an SSA
644value can be quite large, it is sometimes beneficial to split the live range
645into smaller parts.
646
647A live range is split by creating new SSA values that are copies or the
648original value or each other. The copies are created by inserting `copy`,
649`spill`, or `fill` instructions, depending on whether the values
650are assigned to registers or stack slots.
651
652This approach permits SSA form to be preserved throughout the register
653allocation pass and beyond.
654
655## Instruction groups
656
657All of the shared instructions are part of the `base` instruction
658group.
659
660Target ISAs may define further instructions in their own instruction groups.
661
662## Implementation limits
663
664Cranelift's intermediate representation imposes some limits on the size of
665functions and the number of entities allowed. If these limits are exceeded, the
666implementation will panic.
667
668Number of instructions in a function
669    At most :math:`2^{31} - 1`.
670
671Number of BBs in a function
672    At most :math:`2^{31} - 1`.
673
674    Every BB needs at least a terminator instruction anyway.
675
676Number of secondary values in a function
677    At most :math:`2^{31} - 1`.
678
679    Secondary values are any SSA values that are not the first result of an
680    instruction.
681
682Other entities declared in the preamble
683    At most :math:`2^{32} - 1`.
684
685    This covers things like stack slots, jump tables, external functions, and
686    function signatures, etc.
687
688Number of arguments to a BB
689    At most :math:`2^{16}`.
690
691Number of arguments to a function
692    At most :math:`2^{16}`.
693
694    This follows from the limit on arguments to the entry BB. Note that
695    Cranelift may add a handful of ABI register arguments as function signatures
696    are lowered. This is for representing things like the link register, the
697    incoming frame pointer, and callee-saved registers that are saved in the
698    prologue.
699
700Size of function call arguments on the stack
701    At most :math:`2^{32} - 1` bytes.
702
703    This is probably not possible to achieve given the limit on the number of
704    arguments, except by requiring extremely large offsets for stack arguments.
705
706## Glossary
707
708    addressable
709        Memory in which loads and stores have defined behavior. They either
710        succeed or [trap], depending on whether the memory is
711        [accessible].
712
713    accessible
714        [Addressable] memory in which loads and stores always succeed
715        without [trapping], except where specified otherwise (eg. with the
716        `aligned` flag). Heaps, globals, tables, and the stack may contain
717        accessible, merely addressable, and outright unaddressable regions.
718        There may also be additional regions of addressable and/or accessible
719        memory not explicitly declared.
720
721    basic block
722        A maximal sequence of instructions that can only be entered from the
723        top, and that contains no branch or terminator instructions except for
724        the last instruction.
725
726    entry block
727        The [BB] that is executed first in a function. Currently, a
728        Cranelift function must have exactly one entry block which must be the
729        first block in the function. The types of the entry block arguments must
730        match the types of arguments in the function signature.
731
732    BB parameter
733        A formal parameter for a BB is an SSA value that dominates everything
734        in the BB. For each parameter declared by a BB, a corresponding
735        argument value must be passed when branching to the BB. The function's
736        entry BB has parameters that correspond to the function's parameters.
737
738    BB argument
739        Similar to function arguments, BB arguments must be provided when
740        branching to a BB that declares formal parameters. When execution
741        begins at the top of a BB, the formal parameters have the values of
742        the arguments passed in the branch.
743
744    function signature
745        A function signature describes how to call a function. It consists of:
746
747        - The calling convention.
748        - The number of arguments and return values. (Functions can return
749          multiple values.)
750        - Type and flags of each argument.
751        - Type and flags of each return value.
752
753        Not all function attributes are part of the signature. For example, a
754        function that never returns could be marked as `noreturn`, but that
755        is not necessary to know when calling it, so it is just an attribute,
756        and not part of the signature.
757
758    function preamble
759        A list of declarations of entities that are used by the function body.
760        Some of the entities that can be declared in the preamble are:
761
762        - Stack slots.
763        - Functions that are called directly.
764        - Function signatures for indirect function calls.
765        - Function flags and attributes that are not part of the signature.
766
767    function body
768        The basic blocks which contain all the executable code in a function.
769        The function body follows the function preamble.
770
771    intermediate representation
772    IR
773        The language used to describe functions to Cranelift. This reference
774        describes the syntax and semantics of Cranelift IR. The IR has two
775        forms: Textual, and an in-memory data structure.
776
777    stack slot
778        A fixed size memory allocation in the current function's activation
779        frame. These include [explicit stack slot]s and
780        [spill stack slot]s.
781
782    explicit stack slot
783        A fixed size memory allocation in the current function's activation
784        frame. These differ from [spill stack slot]s in that they can
785        be created by frontends and they may have their addresses taken.
786
787    spill stack slot
788        A fixed size memory allocation in the current function's activation
789        frame. These differ from [explicit stack slot]s in that they are
790        only created during register allocation, and they may not have their
791        address taken.
792
793    terminator instruction
794        A control flow instruction that unconditionally directs the flow of
795        execution somewhere else. Execution never continues at the instruction
796        following a terminator instruction.
797
798        The basic terminator instructions are `br`, `return`, and
799        `trap`. Conditional branches and instructions that trap
800        conditionally are not terminator instructions.
801
802    trap
803    traps
804    trapping
805        Terminates execution of the current thread. The specific behavior after
806        a trap depends on the underlying OS. For example, a common behavior is
807        delivery of a signal, with the specific signal depending on the event
808        that triggered it.
809