Rust 的增量式编译器架构

主要观点:传统编译器结构呈流水线形式,现代语言需求使其不再适用,Rust 八年来追求特殊设计以支持增量编译和低延迟响应,通过转向基于查询的模型来替代传统结构,利用构建系统的优势,在编译器中组织查询并使用 TyCtxt 结构,各查询间关系隐含且追踪依赖顺序,通过计算和存储哈希值优化性能,但也带来一些复杂问题。
关键信息

  • 传统编译器流水线包括解析、类型检查、优化和代码生成,现代语言需求使其需改变设计。
  • Rust 从 2016 年开始重写编译器以支持增量编译,部分编译器已采用基于查询的方法。
  • 利用 TyCtxt 组织查询,提供者需为纯函数,避免全局状态,查询结果需可复制。
  • Rust 查询与静态构建系统有结构差异,通过追踪查询间依赖关系和顺序进行增量编译。
  • 为解决内部 ID 变化问题,对保存到磁盘的结构赋予稳定 ID 形式,计算并存储哈希值优化性能,但带来额外开销。
    重要细节
  • 传统编译器各步骤需依次完成,虽有改进但架构限制增量编译。
  • Rust 中整个 crate 是单个翻译单元,cargo 处理变更的 crate 重新编译。
  • 基于查询的模型中,编译器通过查询获取程序不同属性,根据输入变化决定是否重新运行查询。
  • 初始运行编译器收集查询间依赖图,重新运行时检查该图确定需重新运行的查询。
  • 计算哈希值虽优化性能但带来显著开销,编译器会进行额外优化和调整。
  • Rust 增量编译已稳定成为开发构建的默认选项,发布构建出于谨慎仍避免增量编译,其他语言是否采用该设计尚待观察。
阅读 8
0 条评论