2025 年 3 月 4 日,Scott Pakin 提议写一篇关于如何为 Futhark 编译器添加新后端的博客文章,此时后端正在积极修改,这是个不错的想法。本文重点在于介绍添加新后端的核心内容及工作,而非教程式讲解具体内部 API。
架构概述:
- Futhark 编译器是用 Haskell 编写的单体程序,所有 passes 和后端都在同一个可执行文件中,理论上可使用不同语言编写后端,但目前未实现。
编译器由前端、中间端和后端三部分组成:
- 前端负责解析 Futhark 源语言、类型检查并转换为核心中间表示(IR)。
- 中间端对不同 IR 方言表示的程序进行渐进式细化、转换和优化。
- 后端将 IR 表示转换为低级表示,如 C 语言,可能通过多个步骤。
- 编译器通过前端生成中间表示,然后通过中间端管道转换为其他表示,最后传递给后端,不同编译模式下中间端和后端行为不同,编译器使用参数化表示来避免代码重复。
后端动作:
- 在 Futhark 编译器中,“后端”称为“动作”,是在中间端管道结果上运行的任意过程,包含动作名称、描述和处理程序。
- 例如
futhark c
的动作会进行 C 代码生成并执行相关操作,SequentialC.compileProg
负责实际的 C 代码生成,动作可以很灵活,甚至可以将最终 IR 转存到磁盘并运行其他程序进行代码生成。 - 要将管道与动作连接并生成可在命令行调用的内容,需要编写
main
定义,如futhark c
的定义,最后将其连接到子命令列表中。
命令式代码生成:
- 实际中 Futhark 的 C 后端和 Python 后端都使用共享基础设施避免重复工作。
- 编译器定义了一个命令式中间表示 Imp,它是一个可扩展语言,有各种方言,语义上类似于简化的 C,不是 SSA 形式,在 Imp 级别不进行优化。
- 从功能 IR 到 Imp 的翻译由 ImpGen 模块完成,该模块高度参数化,用于从任意 IR 方言转换到任意 Imp 方言。
- 获得 Imp 表示后,可将程序转换为 C、Python 或其他语言,为了维护三个 GPU 后端,还使用了 GPU 抽象层。
编写后端的建议:
- 若目标是高级并行语言,使用前端和到
SOACS
表示的中间端,可生成 fork-join 语言代码。 - 若目标是稍低层次的并行语言,可处理
GPU
表示的输出,保证无嵌套并行。 - 若目标是新的 GPU 后端,实现
gpu.h
抽象层,CPU 侧代码生成较简单,但生成 GPU 内核代码仍需大量工作。 - 若生成低级代码,使用包含内存信息的 IR 方言,生成类似 C 的代码使用现有 Imp 生成机制最容易。
- 无论如何,最好向 Futhark 开发者寻求建议和帮助,第三方添加新后端的相关文档尚未完善。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。