@@ -6,10 +6,21 @@ Abstract
6
6
7
7
TODO: enable high-level optimization, interoperability, persistence, embedded interpreter, second coming, etc.
8
8
9
- General features
10
- ----------------
11
-
12
- TODO: SSA, functional representation, all implicit Swift behavior is explicit in SIL, etc.
9
+ Structure
10
+ ---------
11
+
12
+ SIL is an SSA-form IR similar to LLVM assembly language. Values represent virtual registers and are
13
+ immutable once instantiated. Mutation is represented by loading and storing to allocated memory as
14
+ in LLVM. However, unlike LLVM, SIL represents branches using functional representation; rather than
15
+ use phi nodes to reconcile values in branches, basic blocks resemble functions that implicitly close
16
+ over their dominating blocks, and branch instructions look like function calls. Every SIL instruction
17
+ also carries a reference back into the originating Swift AST for diagnostic purposes. The first
18
+ basic block of a function takes the function's arguments as its own.
19
+
20
+ In Swift, memory management is almost always implicit, but in SIL, it is always explicit. Allocation,
21
+ deallocation, and reference counting have explicit instructions in SIL, and instructions such as tuple
22
+ construction and function calls in SIL never implicitly retain or release objects even if the
23
+ analogous high-level operations in Swift do.
13
24
14
25
Types
15
26
-----
@@ -32,26 +43,121 @@ SIL classifies types into two additional subgroups based on ABI stability:
32
43
contains an address-only type may be referred to by an address, but those addresses cannot be
33
44
directly loaded or stored.
34
45
35
- SIL adds some additional types of its own:
46
+ SIL adds some additional types of its own, which are not first-class Swift types but are needed
47
+ to :
36
48
37
49
* The *address of T * ``Address<T> ``, a pointer to memory containing a value of any reference or
38
50
value type ``T ``. This can be an internal pointer into a data structure. Addresses of loadable
39
- types can be loaded and stored to access values of those types. Addresses cannot be retained or
40
- released.
51
+ types can be loaded and stored to access values of those types. Addresses of address-only types
52
+ can only be used with the ``copy ``, ``destroy ``, and ``dealloc `` instructions, or as arguments to
53
+ functions. Addresses cannot be retained or released.
41
54
* The *object pointer * ``ObjectPointer `` is a generic pointer to a retainable block of memory, or
42
55
*box *. An object pointer behaves like a reference type, but its contents are not accessible; it
43
56
can only be retained, released, or passed around. Operations that allocate retainable memory
44
57
generally return both an object pointer for the box and an address pointing to the object or
45
58
objects inside the box.
59
+ * Unlike Swift, unbound generic function types such as ``<T> (T) -> T `` can be expressed in SIL.
60
+ Accessing a generic function with ``constant_ref `` will give a value of that type. The generic
61
+ variables can be bound with a ``specialize `` instruction to give a callable function value.
62
+
63
+ Functions
64
+ ---------
65
+ ::
66
+
67
+ func function_name [<T,U,V>] (T1, T2, ...) -> R {
68
+ entry(%a1:T1, %a2:T2, ...):
69
+ insn1
70
+ insn2
71
+ return
72
+ }
73
+
74
+ A SIL function definition gives the function's name, its generic parameters (if any), and the types
75
+ of its inputs and outputs. Implicit parameters for closures and curried functions in Swift are
76
+ translated into explicit arguments.
77
+
78
+ Basic blocks
79
+ ------------
80
+
81
+ The body of a function consists of one or more basic blocks. Each basic block is introduced with a
82
+ label and zero or more arguments and ends with a branch instruction.
46
83
47
84
Instructions
48
85
------------
49
86
87
+ TODO: formalize SIL notation
88
+
89
+ Literal values
90
+ ~~~~~~~~~~~~~~
91
+
92
+ constant_ref
93
+ ````````````
94
+ ::
95
+
96
+ %1 = constant_ref T identifier
97
+
98
+ Loads a reference to the global object of type ``T `` represented by the declaration ``identifier ``,
99
+ such as a function, method, constructor, or property declaration. If the definition is generic, the
100
+ result will be of a generic function type; the generic variables of such a result will need to be
101
+ bound with a ``specialize `` instruction before the object can be ``apply ``-ed.
102
+
103
+ zerovalue
104
+ `````````
105
+ ::
106
+
107
+ %1 = zerovalue T
108
+
109
+ Creates a "zero" value of type ``T ``. This value represents the uninitialized state of a value. This
110
+ may not be a semantically valid value of type ``T ``, but will at least give predictable results.
111
+
112
+ integer_literal
113
+ ```````````````
114
+ ::
115
+
116
+ %1:T = integer_literal T 123
117
+
118
+ Creates an integer literal value. The result will be of type ``T ``, which must be a builtin
119
+ integer type.
120
+
121
+ float_literal
122
+ `````````````
123
+ ::
124
+
125
+ %1:T = float_literal T 1.23
126
+
127
+ Creates a floating-point literal value. The result will be of type ``T ``, which must be a builtin
128
+ floating-point type.
129
+
130
+ char_literal
131
+ `````````````````
132
+ ::
133
+
134
+ %1:T = char_literal T 'x'
135
+
136
+ Creates a Unicode code point literal value. The result will be of type ``T ``, which must be of a
137
+ builtin integer type.
138
+
139
+ TODO: same as integer_literal?
140
+
141
+ string_literal
142
+ ``````````````
143
+ ::
144
+
145
+ %1:RawPointer = string_literal {ascii|utf8} "asdf"
146
+
147
+ Retrieves a pointer to a string literal in the string table. The result will be of the builtin
148
+ ``RawPointer `` type.
149
+
150
+ metatype
151
+ ````````
152
+ ::
153
+
154
+ %1:T.metatype = metatype T
155
+
156
+ Retrieves the metatype object for type ``T ``.
157
+
50
158
Memory Management
51
159
~~~~~~~~~~~~~~~~~
52
160
53
- TODO: formalize SIL source notation
54
-
55
161
alloc_var
56
162
`````````
57
163
::
@@ -182,11 +288,6 @@ except that ``copy`` must be used if ``T`` is an address-only type. The operands
182
288
be given the ``take `` and ``initialize `` attributes to indicate respectively whether the source may be
183
289
destroyed and whether the destination must be initialized.
184
290
185
- Literal values
186
- ~~~~~~~~~~~~~~
187
-
188
- TODO
189
-
190
291
Data manipulation
191
292
~~~~~~~~~~~~~~~~~
192
293
@@ -215,15 +316,18 @@ index_address
215
316
216
317
Returns the address of the ``%1 ``-th element relative to ``%0 ``.
217
318
218
- TODO: could it also index into tuples and structs like GEP?
319
+ TODO: could it also index into tuples and structs and into multilevel structures like GEP?
219
320
220
321
convert
221
322
```````
222
323
::
223
324
224
325
%1:U = convert %0:T -> U
225
326
226
- Performs an implicit conversion from ``T `` to ``U ``.
327
+ Performs an implicit conversion from ``T `` to ``U ``. This instruction is limited to conversions that
328
+ will not affect how the value will codegen.
329
+
330
+ TODO: what does that mean in practical terms?
227
331
228
332
Functions
229
333
~~~~~~~~~
@@ -244,7 +348,8 @@ specialize
244
348
245
349
%1:F1 = specialize %0:F0 -> F1
246
350
247
- Specializes a generic function of function type ``F0 ``
351
+ Specializes a generic function of generic function type ``F0 `` to generic or concrete function
352
+ type ``F1 ``, binding some or all of its generic type variables.
248
353
249
354
apply
250
355
`````
@@ -255,15 +360,57 @@ apply
255
360
Transfers control to function ``%0 ``, passing in the given arguments. The ``apply `` instruction does no retaining or
256
361
releasing of its arguments by itself; the calling convention's retain/release policy must be handled
257
362
by separate explicit ``retain `` and ``release `` instructions. The return value will likewise not be
258
- implicitly retained or released.
363
+ implicitly retained or released. ``%0 `` must be an object of a concrete function type; generic
364
+ functions must have all of their generic parameters bound with ``specialize `` instructions before
365
+ they can be applied.
259
366
260
- TODO: should have normal/unwind branch targets like ``invoke ``
367
+ TODO: should have normal/unwind branch targets like LLVM ``invoke ``
261
368
262
369
Branching
263
370
~~~~~~~~~
264
371
265
- TODO
372
+ Branching instructions terminate a basic block.
373
+
374
+ unreachable
375
+ ```````````
376
+ ::
377
+
378
+ unreachable
379
+
380
+ Instruction indicates that control flow must not reach the end of the current
381
+ basic block.
382
+
383
+ return
384
+ ``````
385
+ ::
386
+
387
+ return %0:T
388
+
389
+ Exits the current function and returns control to the calling function. The result of the ``apply ``
390
+ instruction that invoked the current function will be the operand of this ``return `` instruction.
391
+ ``return `` does not retain or release its operand or any other values.
392
+
393
+ branch
394
+ ``````
395
+ ::
396
+
397
+ branch label (%1:T1, %2:T2, ...)
398
+
399
+ Unconditionally transfers control from the current basic block to the block
400
+ labeled ``label ``, passing the given values as arguments to ``label ``.
401
+
402
+ cond_branch
403
+ ```````````
404
+ ::
405
+
406
+ cond_branch %0:Int1, true_label (%T1:T1, %T2:T2, ...),
407
+ false_label (%F1:F1, %F2:F2, ...)
408
+
409
+ Conditionally branches to ``true_label `` if ``%0 `` is equal to one or to ``false_label `` if ``%0 ``
410
+ is equal to zero, passing the corresponding set of values as arguments to the chosen block. ``%0 ``
411
+ must be of the builtin ``Int1 `` type.
266
412
413
+ TODO: throw
267
414
268
415
Examples
269
416
--------
0 commit comments