32. Raw SIL
• May not have a fully-constructed SSA graph
• May contain dataflow errors
• Should not be used for native code generation or
distribution
33. Canonical SIL
• Dataflow errors must be eliminated
• Certain instructions must be canonicalized to simpler forms.
• Performance optimization and native code generation are
derived from this form
• A module can be distributed containing SIL in this (or later)
forms.
47. SIL Stage
sil_stage canonical
SIL files declare the processing stage of the included SIL with
one of the declarations
sil_stage raw or sil_stage canonical at top level.
48. Import
import Builtin
import Swift
import SwiftShims
SIL is reliant on Swift's type system and declarations. In a .sil
file, there are no implicit imports. The swift and/or Builtin
standard modules must be imported explicitly if used.
49. Legal SIL Types
• A loadable legal SIL type, $T
• The address of a legal SIL type, $*T
50. Linkage
sil hidden @_T06sample6numberSiyF : $@convention(thin) () -> Int
hidden definitions are unique and visible only within the
current Swift module. In LLVM IR, they will be emitted with
external linkage and hidden visibility.
51. Name Mangling
sil hidden @_T06sample6numberSiyF : $@convention(thin) () -> Int
The name @_T06sample6numberSiyF is the mangled name of
the number Swift function.
52. Calling Convention
How Swift functions are emitted in SIL
• @convention(swift)
• @convention(method)
• @convention(witness_method)
• @convention(c)
• @convention(objc_method)
53. Type Lowering
sil hidden @_T06sample6numberSiyF : $@convention(thin) () -> Int
A formal type is the type of a value in Swift, such as an
expression result.Type lowering is the process of turning a
formal type into its lowered type.
The lowered type of a declaration will usually be thin.
54. Basic Blocks
bb0:
In SIL, basic blocks take arguments, which are used as an
alternative to LLVM's phi nodes.
55. alloc_stack
%0 = alloc_stack $Int, let, name "x"
Allocates uninitialized memory that is sufficiently aligned on
the stack to contain a value of type Int.
56. integer_literal
%1 = integer_literal $Builtin.Int64, 1
Creates an integer literal value. The result will be of type
Builtin.Int64, which must be a builtin integer type. The literal
value is specified using Swift’s integer literal syntax.
57. struct
%2 = struct $Int (%1 : $Builtin.Int64)
Creates a value of a loadable struct type by aggregating
multiple loadable values.
58. store
store %2 to %0 : $*Int
Stores the value %2 to memory at address %0. The type of %0
is *Int and the type of %2 is Int.
59. dealloc_stack
dealloc_stack %0 : $*Int
Deallocates memory previously allocated by alloc_stack.
The allocated value in memory must be uninitialized or
destroyed prior to being deallocated.
60. return
return %2 : $Int
Exits the current function and returns control to the calling
function.
61. sample.sil
sil_stage canonical
import Builtin
import Swift
import SwiftShims
// main
...
// number()
sil hidden @_T06sample6numberSiyF : $@convention(thin) () -> Int {
bb0:
%0 = alloc_stack $Int, let, name "x" // users: %3, %4
%1 = integer_literal $Builtin.Int64, 1 // user: %2
%2 = struct $Int (%1 : $Builtin.Int64) // users: %5, %3
store %2 to %0 : $*Int // id: %3
dealloc_stack %0 : $*Int // id: %4
return %2 : $Int // id: %5
} // end sil function '_T06sample6numberSiyF'
// Int.init(_builtinIntegerLiteral:)
...