本页面提供了 Swift 编译器中使用的中间表示 (IRs) 的技术概述。这些 IRs 作为 Swift 源代码和机器代码之间的桥梁,在整个编译过程中实现各种优化和转换。
有关编译器整体架构的信息,请参阅 Swift 编译器概述。
Swift 编译器会经历多个阶段,前端和后端之间有两个主要的中间表示
来源:lib/IRGen/IRGenSIL.cpp1-15 lib/SILGen/SILGen.cpp1-19
SIL 是 Swift 主要的高级中间表示,专门设计用于表示类型检查后的 Swift 代码,直至平台特定的代码生成。
Swift 中间语言 serve several critical purposes
来源:lib/SILGen/SILGenFunction.h380-670 lib/SILGen/SILGen.cpp50-75
SIL 在编译过程中使用几种抽象来表示值
来源:lib/SILGen/SILGenExpr.cpp67-419 lib/SILGen/SILGenLValue.cpp45-65
SIL 通过 SILGenFunction 和 SILGenModule 类从 AST 生成,这些类会遍历 AST 并发出适当的 SIL 指令。
来源:lib/SILGen/SILGenFunction.cpp52-54 lib/SILGen/SILGenApply.cpp249-276
LLVM IR 是 Swift 编译器使用的第二个主要中间表示。它是一个更低级别的表示,通过 LLVM 基础架构将 SIL 连接到机器代码。
来源:lib/IRGen/IRGenModule.h129-200 lib/IRGen/IRGenModule.cpp233-250
从 SIL 到 LLVM IR 的转换由 IRGenModule 和 IRGenFunction 类处理。将 SIL 翻译成 LLVM IR 的关键类是 IRGenSILFunction。
来源:lib/IRGen/IRGenSIL.cpp120-155 lib/IRGen/IRGenSIL.cpp387-390
LoweredValue 类是 SIL 转换为 LLVM IR 的关键组件,表示一个 SIL 值在被降级到 LLVM IR 后的样子。
来源:lib/IRGen/IRGenSIL.cpp153-371
从 SIL 到 LLVM IR 的转换涉及几个复杂的步骤
Swift 类型必须转换为 LLVM 类型,这涉及到
来源:lib/IRGen/GenType.cpp lib/IRGen/IRGenModule.cpp233-250
SIL 函数被转换为 LLVM 函数,这涉及到
来源:lib/IRGen/GenFunc.cpp lib/IRGen/GenCall.cpp377-401
IRGenSILFunction 类使用访问者模式来遍历 SIL 指令并发出相应的 LLVM IR。
来源:lib/IRGen/IRGenSIL.cpp387-427
SIL 值使用 LoweredValue 抽象进行降级,它可以表示各种类型的值
来源:lib/IRGen/IRGenSIL.cpp469-615
Swift 的 IR 生成包含大量用于生成元数据和运行时支持的代码
类型元数据对于 Swift 的运行时功能(如反射、动态转换和泛型实例化)至关重要。
来源:lib/IRGen/GenMeta.cpp144-179
Swift 生成 witness 表来表示协议一致性
来源:lib/IRGen/GenProto.cpp95-170
Swift 使用协程来实现 async/await,这些协程同时在 SIL 和 LLVM IR 中表示
来源:lib/IRGen/GenCall.cpp100-168
Swift 编译器利用两种主要的中间表示——SIL 和 LLVM IR——来弥合 Swift 源代码和机器代码之间的差距。SIL 提供了一个 Swift 特定的表示,它捕获所有权语义并启用 Swift 特定的优化,而 LLVM IR 提供了一个利用 LLVM 成熟的优化和代码生成基础设施的途径。
这些表示能够支持从ARC内存管理到泛型特化再到协议见证分派等各种编译时和运行时特性。
这些表示之间的转换由IRGenSILFunction等专门组件处理,它们在更高级别的Swift抽象和更低级别的LLVM构造之间进行映射,在暴露优化机会的同时保持语义。