SIL 生成是 Swift 编译器管线中将抽象语法树(AST)转换为 Swift 中间语言(SIL)的过程。这种中间表示捕获了 Swift 的语言语义、类型系统和内存所有权模型,以便在最终代码生成之前进行 Swift 特定的优化。有关编译器管线后续阶段的信息,请参阅 LLVM IR 生成。
SIL 生成阶段处于编译过程的关键节点,在类型检查完成后,优化阶段开始之前。
来源: lib/SILGen/SILGen.cpp58-76
SIL 生成是由编译器中一组相互关联的组件实现的
来源: lib/SILGen/SILGen.h58-161 lib/SILGen/SILGenFunction.h305-322 lib/SILGen/SILGenExpr.cpp422-607
SILGenModule 是一个顶层类,负责协调整个 Swift 模块的 SIL 生成。它维护模块范围的状态,创建 SIL 函数,并协调全局声明的生成。
来源: lib/SILGen/SILGen.cpp58-104 lib/SILGen/SILGen.h58-161
SILGenFunction 负责函数级别的 SIL 生成。每个 Swift 函数或方法都有其自己的 SILGenFunction 实例来管理特定于函数的状态,例如:
来源: lib/SILGen/SILGenFunction.cpp53-122 lib/SILGen/SILGenFunction.h305-322
几个专门的组件处理 Swift 的不同方面
来源: lib/SILGen/SILGenExpr.cpp422-607 lib/SILGen/SILGenDecl.cpp44-54 lib/SILGen/SILGenLValue.cpp44-102 lib/SILGen/SILGenPoly.cpp84-133
将 AST 节点转换为 SIL 的过程遵循递归模式
来源: lib/SILGen/SILGenFunction.cpp104-122 lib/SILGen/SILGenExpr.cpp403-607
SIL 生成从模块级别开始,SILGenModule 处理 Swift 模块中的顶层声明。对于每个函数,它会创建一个 SILFunction 对象,并委托给 SILGenFunction 来生成函数体。
来源: lib/SILGen/SILGen.cpp58-104
SILGenFunction 处理函数生成的复杂性
self 设置特殊处理来源: lib/SILGen/SILGenFunction.cpp53-122 lib/SILGen/SILGenProlog.cpp1-154
表达式由 SILGenExpr 访问者类处理,该类根据表达式种类(调用、字面量、闭包等)进行分派并生成相应的 SIL 指令。
来源: lib/SILGen/SILGenExpr.cpp422-607
几个关键抽象促进了 SIL 的生成
来源: lib/SILGen/ManagedValue.h1-24 lib/SILGen/RValue.cpp1-20 lib/SILGen/LValue.h37-85
ManagedValue 将 SIL 值与所有权信息配对。它表示可能需要清理操作(例如,引用类型的 release)的值,并帮助管理 Swift 的所有权模型。
来源: lib/SILGen/ManagedValue.h1-24
RValue 表示 Swift 中的“右侧”值——即可以计算但不能赋值给的值。它管理 ManagedValue 的集合,特别是对于元组等聚合值。
LValue 表示 Swift 中的“左侧”值,即可以赋值的对象,例如变量和属性。它由一系列 LValueComponent 对象组成,用于模拟到存储的访问路径。
来源: lib/SILGen/LValue.h37-85 lib/SILGen/SILGenLValue.cpp44-102
Initialization 类表示一个可以存储值的目标。它抽象了不同类型的初始化上下文,例如变量、临时存储,甚至初始化元组。
来源: lib/SILGen/SILGenDecl.cpp51-52
CleanupStack 管理内存清理和生命周期,确保资源在离开作用域时被正确释放。它对于实现 Swift 的确定性资源管理至关重要。
来源: lib/SILGen/SILGenFunction.h361-381
Swift 的内存模型结合了自动引用计数 (ARC) 和值语义。SIL 生成必须仔细实现此模型。
来源: lib/SILGen/SILGenExpr.cpp67-191 lib/SILGen/SILGenFunction.h113-172
SIL 生成同时处理值类型(复制语义)和引用类型(带引用计数的标识语义)。
retain 和 release 操作。来源: lib/SILGen/SILGenExpr.cpp67-122
SIL 通过限定符显式表示所有权,例如
@owned:调用者将所有权转移给被调用者。@guaranteed:被调用者借用该值;调用者仍负责它。@inout:被调用者可以就地修改该值。SIL 生成必须根据 Swift 的语义正确应用这些限定符。
来源: lib/SILGen/SILGenExpr.cpp258-296 lib/SILGen/SILGenFunction.h113-172
SIL 使用抽象模型来处理 Swift 的泛型类型和协议系统。
来源: lib/SILGen/SILGenPoly.cpp84-133
对于泛型代码,SIL 生成会在已知具体类型时创建特化版本,或在完全泛型代码路径中使用类型元数据。
来源: lib/SILGen/SILGenPoly.cpp84-133
协议一致性通过见证表(witness tables)来表示,这些表将协议需求映射到具体的实现。SIL 生成创建这些表以及通常用于在不同类型抽象级别之间进行桥接的 thunk。
来源: lib/SILGen/SILGenType.cpp46-66
Swift 的错误处理模型通过 SIL 中的专用控制流机制实现。
来源: lib/SILGen/SILGenFunction.h387-391
对于 try-catch 块,SIL 生成会创建特殊的控制流,带有错误传播路径,并为正常情况和错误情况设置专用基本块。
可能抛出错误的函数在其 SIL 中具有特殊的错误处理逻辑。抛出的错误会沿着调用栈向上传播,并在此过程中执行清理代码。
来源: lib/SILGen/SILGenFunction.h387-391
SIL 生成是 Swift 编译器管道中的关键阶段,它连接了 Swift 的高级语义和优化及代码生成所需的低级表示。通过构建 Swift 语义的精确表示,包括其所有权模型、类型系统和错误处理,SIL 生成使编译器能够执行复杂的 Swift 特定优化,同时保留语言语义。