菜单

SIL 生成

相关源文件

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

SILGenModule 是一个顶层类,负责协调整个 Swift 模块的 SIL 生成。它维护模块范围的状态,创建 SIL 函数,并协调全局声明的生成。

来源: lib/SILGen/SILGen.cpp58-104 lib/SILGen/SILGen.h58-161

SILGenFunction

SILGenFunction 负责函数级别的 SIL 生成。每个 Swift 函数或方法都有其自己的 SILGenFunction 实例来管理特定于函数的状态,例如:

  • 入口点和基本块
  • 局部变量和参数
  • 用于内存管理的清理栈
  • 用于循环和分支的控制流

来源: lib/SILGen/SILGenFunction.cpp53-122 lib/SILGen/SILGenFunction.h305-322

专门的 SIL 生成组件

几个专门的组件处理 Swift 的不同方面

  • SILGenExpr:降低表达式(函数调用、字面量等)
  • SILGenDecl:处理声明(变量、函数等)
  • SILGenConstructor:为初始化程序生成代码
  • SILGenDestructor:为析构函数生成代码
  • SILGenLValue:管理左值(可赋值)表达式
  • SILGenPoly:处理多态代码和泛型
  • SILGenPattern:处理模式匹配
  • SILGenThunk:创建方法重写和协议见证的 thunk

来源: lib/SILGen/SILGenExpr.cpp422-607 lib/SILGen/SILGenDecl.cpp44-54 lib/SILGen/SILGenLValue.cpp44-102 lib/SILGen/SILGenPoly.cpp84-133

SIL 生成过程

将 AST 节点转换为 SIL 的过程遵循递归模式

来源: lib/SILGen/SILGenFunction.cpp104-122 lib/SILGen/SILGenExpr.cpp403-607

模块级生成

SIL 生成从模块级别开始,SILGenModule 处理 Swift 模块中的顶层声明。对于每个函数,它会创建一个 SILFunction 对象,并委托给 SILGenFunction 来生成函数体。

来源: lib/SILGen/SILGen.cpp58-104

函数级生成

SILGenFunction 处理函数生成的复杂性

  1. 设置函数入口点
  2. 处理参数并创建 SIL 参数
  3. 初始化局部变量
  4. 为方法中的 self 设置特殊处理
  5. 通过清理栈管理内存清理
  6. 为语句和表达式生成 SIL 指令

来源: 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

ManagedValue 将 SIL 值与所有权信息配对。它表示可能需要清理操作(例如,引用类型的 release)的值,并帮助管理 Swift 的所有权模型。

来源: lib/SILGen/ManagedValue.h1-24

RValue

RValue 表示 Swift 中的“右侧”值——即可以计算但不能赋值给的值。它管理 ManagedValue 的集合,特别是对于元组等聚合值。

来源: lib/SILGen/RValue.cpp1-20

左值 (LValue)

LValue 表示 Swift 中的“左侧”值,即可以赋值的对象,例如变量和属性。它由一系列 LValueComponent 对象组成,用于模拟到存储的访问路径。

来源: lib/SILGen/LValue.h37-85 lib/SILGen/SILGenLValue.cpp44-102

初始化

Initialization 类表示一个可以存储值的目标。它抽象了不同类型的初始化上下文,例如变量、临时存储,甚至初始化元组。

来源: lib/SILGen/SILGenDecl.cpp51-52

CleanupStack (清理堆栈)

CleanupStack 管理内存清理和生命周期,确保资源在离开作用域时被正确释放。它对于实现 Swift 的确定性资源管理至关重要。

来源: lib/SILGen/SILGenFunction.h361-381

内存所有权模型

Swift 的内存模型结合了自动引用计数 (ARC) 和值语义。SIL 生成必须仔细实现此模型。

来源: lib/SILGen/SILGenExpr.cpp67-191 lib/SILGen/SILGenFunction.h113-172

值语义与引用语义

SIL 生成同时处理值类型(复制语义)和引用类型(带引用计数的标识语义)。

  • 对于值类型,SIL 生成会插入适当的复制操作。
  • 对于引用类型,它会插入 retainrelease 操作。

来源: 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 块

对于 try-catch 块,SIL 生成会创建特殊的控制流,带有错误传播路径,并为正常情况和错误情况设置专用基本块。

错误传播

可能抛出错误的函数在其 SIL 中具有特殊的错误处理逻辑。抛出的错误会沿着调用栈向上传播,并在此过程中执行清理代码。

来源: lib/SILGen/SILGenFunction.h387-391

结论

SIL 生成是 Swift 编译器管道中的关键阶段,它连接了 Swift 的高级语义和优化及代码生成所需的低级表示。通过构建 Swift 语义的精确表示,包括其所有权模型、类型系统和错误处理,SIL 生成使编译器能够执行复杂的 Swift 特定优化,同时保留语言语义。