菜单

LLVM IR 生成

相关源文件

本文档解释了 Swift 的 IRGen 子系统如何将 Swift 中间语言 (SIL) 转换为 LLVM 中间表示 (IR)。IRGen 是编译过程中连接 Swift 高级语义到 LLVM 低级表示的阶段,它使得最终的代码生成、优化和链接成为可能。有关从 AST 生成 SIL 的信息,请参阅 4.1

IRGen 概述

IRGen 通过将 Swift 的类型系统、函数和其他语言构造转换为 LLVM 的类型系统和指令来转换 SIL 为 LLVM IR。IRGen 阶段处理代码生成的许多关键方面,包括:

  • 类型布局和表示
  • 函数调用约定
  • 内存管理
  • 协议见证表
  • 类型元数据
  • 运行时支持

来源:[lib/IRGen/IRGenModule.h], [lib/IRGen/IRGenModule.cpp], [lib/IRGen/IRGenSIL.cpp]

关键组件

IRGenModule

IRGenModule 是 IR 生成子系统的核心类。它负责管理从 Swift 模块生成单个 LLVM 模块,处理全局声明、元数据生成以及协调类型布局。

来源:[lib/IRGen/IRGenModule.h:210-212], [lib/IRGen/IRGenModule.cpp:232-253]

IRGenFunction

IRGenFunction 负责为特定函数生成 LLVM IR。它包含 IR 构建器并管理函数级别的状态,如局部变量、控制流和错误处理。

来源:[lib/IRGen/IRGenFunction.h:69-93], [lib/IRGen/IRGenSIL.cpp:387-457]

类型系统

类型系统是 IRGen 的一个关键部分。它将 Swift 丰富的类型系统映射到 LLVM 更加受限的类型系统。

来源:[lib/IRGen/IRGenModule.h:163], [lib/IRGen/GenType.h]

SIL 到 IR 的转换过程

从 SIL 到 LLVM IR 的实际转换主要在 IRGenSIL.cpp 中完成,它会访问 SIL 指令并发出相应的 LLVM IR 指令。

来源:[lib/IRGen/IRGenSIL.cpp:458-462], [lib/IRGen/IRGenSIL.cpp:13-16]

关键 IRGen 过程

函数 IR 生成

在生成函数 IR 时,IRGen 会处理多个方面:

  1. 函数签名转换
  2. 参数翻译
  3. 间接结果
  4. 错误处理
  5. 协程和异步函数
  6. 泛型特化

来源:[lib/IRGen/GenCall.cpp:558-605], [lib/IRGen/IRGenSIL.cpp:458-462]

类型元数据生成

类型元数据对于 Swift 运行时管理类型至关重要。IRGen 生成各种元数据结构:

来源:[lib/IRGen/GenMeta.cpp:144-179], [lib/IRGen/IRGenModule.cpp:293-399]

协议和见证表

IRGen 为协议一致性生成见证表,以实现动态分派。

来源:[lib/IRGen/GenProto.cpp:95-105], [lib/IRGen/GenProto.cpp:435-458]

类型化 throws 和协程

Swift 的错误处理模型体现在 IR 生成中。可能抛出错误的函数在 IR 中需要特殊处理。

来源:[test/IRGen/typed_throws.swift:28-64], [lib/IRGen/GenCall.cpp:427-495]

对于协程和异步函数:

来源:[lib/IRGen/GenCall.cpp:71-83], [lib/IRGen/GenCall.cpp:100-163]

Swift 特性的 LLVM IR 生成

值表示

Swift 值在 LLVM IR 中的表示方式因其类型而异:

Swift 类型LLVM 表示备注
Int, FloatLLVM 原始类型直接表示
StructLLVM 结构体类型根据 ABI 进行字段布局
Pointer引用堆分配的对象
枚举(Enum)Tagged union使用判别符和可能的载荷
协议Existential container包含值缓冲区、类型元数据、见证表
功能函数指针 + 上下文捕获的上下文
可选枚举(Enum)针对优化的特殊情况

来源:[lib/IRGen/GenType.h], [lib/IRGen/IRGenSIL.cpp:153-196]

内存管理

IRGen 通过发出适当的 retain/release 调用来处理 Swift 的引用计数。

来源:[lib/IRGen/GenHeap.h], [lib/IRGen/IRGenSIL.cpp]

结论

IRGen 阶段是 Swift 高级语义与 LLVM 低级表示之间的关键桥梁。它负责将 Swift 丰富的类型系统、内存管理模型和语言特性转换为 LLVM IR 的复杂任务,使得 Swift 代码能够利用 LLVM 强大的优化和代码生成能力。

该系统是模块化的,为 IR 生成的不同方面配备了专门的组件,实现了关注点的清晰分离,同时保持了处理 Swift 不断变化的语言特性的灵活性。

来源:[lib/IRGen/IRGenModule.cpp], [lib/IRGen/IRGenSIL.cpp], [lib/IRGen/GenMeta.cpp], [lib/IRGen/GenProto.cpp]