LLVM 编译器基础设施
站点地图
下载!
搜索 本站


实用 链接
发布 邮件

llvm-admin 团队
开放 LLVM 项目

LLVM 团队 编写

欢迎有志参加 2025 年 Google 编程之夏的学生!本文档是您寻找 LLVM、Clang 和其他相关子项目中有趣且重要项目的起点。此项目列表不仅为 Google 编程之夏而开发,而且是为了真正需要开发人员参与并对 LLVM 社区非常有益的开放项目而开发。

我们鼓励您浏览此列表,看看哪些项目让您兴奋并与您的技能组合良好匹配。我们也欢迎不在此列表中的提案。有关 GSoC 的更多信息和讨论,请访问 discourse 。如果您对特定项目有疑问,请在 discourse 中找到相关条目,查看之前的讨论并提问。如果没有这样的条目,或者您想提出一个想法,请创建一个新条目。来自社区的反馈是您的提案被考虑并有望被接受的必要条件。

LLVM 项目多年来一直参与 Google 编程之夏,并取得了一些非常成功的项目。我们希望今年也不例外,并期待收到您的提案。有关如何提交提案的信息,请访问 Google 编程之夏主 网站。

描述

使用调试信息中的变量位置信息来注释 LLDB 的反汇编器(和 `register read`)输出,其中包含源变量的位置和生命周期。富反汇编器输出应作为结构化数据公开,并通过 LLDB 的脚本 API 提供,以便在此基础上构建更多工具。在终端中,LLDB 应将注释呈现为文本。

预期成果

例如,我们可以增强以下函数的反汇编
frame #0: 0x0000000100000f80 a.out`main(argc=1, argv=0x00007ff7bfeff1d8) at demo.c:4:10 [opt]
  1   void puts(const char*);
  2   int main(int argc, char **argv) {
  3    for (int i = 0; i < argc; ++i)
→ 4      puts(argv[i]);
  5    return 0;
  6   }
(lldb) disassemble
a.out`main:
...
  0x100000f71 <+17>: movl  %edi, %r14d
  0x100000f74 <+20>: xorl  %r15d, %r15d
  0x100000f77 <+23>: nopw  (%rax,%rax)
→  0x100000f80 <+32>: movq  (%rbx,%r15,8), %rdi
  0x100000f84 <+36>: callq 0x100000f9e ; symbol stub for: puts
  0x100000f89 <+41>: incq  %r15
  0x100000f8c <+44>: cmpq  %r15, %r14
  0x100000f8f <+47>: jne 0x100000f80 ; <+32> at demo.c:4:10
  0x100000f91 <+49>: addq  $0x8, %rsp
  0x100000f95 <+53>: popq  %rbx
...

使用 LLDB 也有权访问的调试信息(观察源变量 i 如何从 [0x100000f77+slide) 开始位于 r15 中)

$ dwarfdump demo.dSYM --name  i
demo.dSYM/Contents/Resources/DWARF/demo: file format Mach-O 64-bit x86-64
0x00000076: DW_TAG_variable
 DW_AT_location (0x00000098:
 [0x0000000100000f60, 0x0000000100000f77): DW_OP_consts +0, DW_OP_stack_value
 [0x0000000100000f77, 0x0000000100000f91): DW_OP_reg15 R15)
 DW_AT_name ("i")
 DW_AT_decl_file ("/tmp/t.c")
 DW_AT_decl_line (3)
 DW_AT_type (0x000000b2 "int")
生成这样的输出,我们在其中注释变量何时处于活动状态以及其位置
(lldb) disassemble
a.out`main:
...                                                               ; i=0
  0x100000f74 <+20>: xorl  %r15d, %r15d                           ; i=r15
  0x100000f77 <+23>: nopw  (%rax,%rax)                            ; |
→  0x100000f80 <+32>: movq  (%rbx,%r15,8), %rdi                   ; |
  0x100000f84 <+36>: callq 0x100000f9e ; symbol stub for: puts    ; |
  0x100000f89 <+41>: incq  %r15                                   ; |
  0x100000f8c <+44>: cmpq  %r15, %r14                             ; |
  0x100000f8f <+47>: jne 0x100000f80 ; <+32> at t.c:4:10          ; |
  0x100000f91 <+49>: addq  $0x8, %rsp                             ; i=undef
  0x100000f95 <+53>: popq  %rbx

目标是为一部分明确的情况生成这样的输出,例如,常量或完全在寄存器中的变量。

已确认的导师及其联系方式

  • Adrian Prantl aprantl@apple.com (主要联系人)
  • Jonas Devlieghere jdevlieghere@apple.com

所需/期望的技能

必需

  • 良好理解 C++
  • 熟悉在终端上使用调试器
  • 需要熟悉上面示例中提到的所有概念
  • 需要良好理解至少一种机器代码汇编方言(x86_64 或 AArch64)。

期望

  • 编译器知识,包括数据流和控制流分析,是一个加分项。
  • 能够导航调试信息 (DWARF) 是一个加分项。

项目规模

中等 (~175 小时)

项目难度

困难

Discourse: URL

描述

Bfloat16 是一种最近开发的浮点格式,专为机器学习和 AI 定制,在最新的 C++23 标准 中,它被正式标准化为 std::bfloat16_t。它的支持可以在许多现代硬件中找到,从包括 Intel、AMD、Apple 和 Amazon 在内的所有主要供应商的 CPU,到 GPU(nVidia 和 AMD GPU)以及 Google TPU。在软件方面,所有主要的加速器库都支持它,例如 CUDA、ROCm、oneAPI、PyTorch 和 Tensorflow。该项目的目标是在 LLVM libc 库中实现 bfloat16 数学函数。

预期结果

  • 正确设置生成的头文件,以便类型和函数可以与各种编译器(+版本)和架构一起使用。
  • 实现支持 bfloat16 数据类型的通用基本数学运算,这些运算可在受支持的架构上工作:x86_64、arm (32 + 64)、risc-v (32 + 64) 和 GPU。
  • 尽可能使用编译器内置函数或特殊的硬件指令来实现特化,以提高其性能。
  • 如果时间允许,我们可以开始研究 bfloat16 的更高数学函数。

技能

基本 C & C++ 技能 + 对了解/学习更多关于浮点格式精妙之处的兴趣。

项目规模: 大型

难度: 简单/中等

已确认的导师: Tue Ly, Nicolas Celik,

Discourse: URL

描述

现代 GPU 能够与主机进行统一寻址。我们目前使用它通过 RPC 接口 提供 I/O 支持。但是,这需要在 CPU 上使用专用用户线程来处理服务器代码。我们希望探索使用 Linux io_uring 接口从 GPU 提供 I/O 的替代方案。

此接口是一个旨在加速 syscall 的环形缓冲区。但是,它提供了一种 轮询模式,允许内核刷新环形缓冲区,而无需用户启动系统调用。我们应该能够使用 AMDNVIDIA API 调用将 mmap() 内存注册到 GPU。此接口应该允许我们实现一个基本的读/写接口,该接口可以被认为与 CPU 上的 syscall 相同。然后可以使用它来实现完整的文件接口。

预期结果

  • 在 GPU 上运行的 pwritepread 的实现。
  • 通过将 snprintf 转发到 pwrite 来支持 printf
  • 如果时间允许,探索 GPU 文件 API。

技能

基本 C & C++ 技能 + 访问 GPU、Linux 内核知识、GPU 知识。

项目规模: 小型

难度: 困难

已确认的导师: Joseph Huber, Tian Shilei

Discourse: URL

描述

LLVM C 库提供了数学函数的实现。我们希望将这些函数与现有实现进行性能分析比较,例如 CUDA 的 libdevice、ROCm 的 device libs 和 OpenCL 的 libclc。去年,我们致力于一些接口来支持这些测试,现在需要对这些接口进行改进和完善,以用于有趣的函数。

此外,我们希望通过暴力测试来验证这些函数在 GPU 上运行时是否准确。目标是验证这些实现是正确的,并且至少符合 OpenCL 标准 中的误差范围。这将需要一组在 offload/ 项目中编写的单元测试,最好使用 @callumfare 正在开发的新 API。

预期结果

  • 最终性能结果类似于 旧结果,但具有更优化的函数和更高的精度。
  • 一个可以进行暴力测试以确认实现是否符合标准的测试套件。

技能

基本 C & C++ 技能 + 访问 GPU,一些数学知识

项目规模: 小型

难度: 简单/中等

已确认的导师: Joseph Huber, Tue Ly

Discourse: URL

描述: ClangIR (CIR) 项目旨在为 Clang 建立一个新的中间表示 (IR)。它构建在 MLIR 之上,为 Clang 中基于 C/C++ 的语言提供了一种方言,以及从 Clang AST 发射它以及降低到 LLVM-IR 方言的必要基础设施。ClangIR 上游化 目前正在进行中。

为了更频繁地向社区提供更新,如果我们能够通过衡量在启用 ClangIR 的管道中现有 Clang 的 CodeGen 测试的覆盖率来报告 ClangIR 的进度,那将非常棒。通过收集关于崩溃、通过或失败测试的信息,我们可以提出一个更容易报告和理解的指标,为寻找任务的新手提供入口点,并通过对现有问题进行分类来帮助项目。现有的 Clang CodeGen 测试位于 clang/test/CodeGen* 中,并且在 ClangIR 支持方面处于不同的状态

  • FileCheck 失败。LLVM IR 构建成功,但 FileCheck 无法匹配输出
    • LLVM IR 不同,因为 ClangIR 管道正在发射不同的 IR(例如,使用了不同的指令,缺少属性)。需要创建问题,并且需要修复 ClangIR。
    • LLVM IR 不同,因为 CHECK 行需要更灵活(LLVM-IR 方言输出不同,SSA 值名称,属性顺序等)。像 llvm-canon 这样的工具可能在这里很有用。
  • 测试崩溃/错误。ClangIR 不支持某些 C/C++ 构造,或者 LLVM 降低尚未实现。
  • 测试通过。耶!

为了检索上述信息,学生需要对 Clang 的测试基础设施(LIT 配置、脚本、测试、???)进行更改,以便更容易地在启用 ClangIR 的情况下重放相同的调用,与传统管道结果进行比较或从测试中检索特殊指令。

目前尚不清楚最佳方法是什么,但希望希望被认真对待的提交提案应提出关于如何实现这一目标的几种可能的想法,鼓励事先与社区其他成员进行讨论。还希望学生与 ClangIR 社区互动,提交 github 问题,调查和/或更改失败的 codegen 测试。

预期结果

  1. 构建基础设施以运行测试并收集结果。
  2. 以可以放在网页上的方式呈现结果。
  3. 为上面“FileCheck 失败”类别中的 50% 提交问题或更改检查行。目前唯一需要考虑的子目录是
        clang/test/CodeGen
        clang/test/CodeGenCXX
        clang/test/CodeGenOpenCL
        clang/test/CodeGenCUDA
        
  • 加分项:找到自动化/促进测试更改的方法,提交 PR 以修复 ClangIR 中的问题。

技能: 需要 Python、中级 C++ 编程技能以及熟悉基本的编译器设计概念。之前有 LLVM IR、MLIR、Clang 或 ClangIR 编程经验是一个很大的加分项,但愿意学习也是一种可能性。

项目规模: 大型

难度:中等

潜在导师: Bruno Cardoso Lopes Andy Kaylor

Discourse: URL

描述: ClangIR 是一种新的、基于 MLIR 的 C 和 C++ 代码中间表示。它是在 LLVM 孵化器项目中开发的,但现在正在进行将代码从孵化器迁移到主 LLVM 存储库的工作。在代码迁移过程中,必须对其进行更新,以符合 LLVM 编码标准和质量期望。该项目的目标是参与 ClangIR 上游化过程,并帮助改进代码和上游化过程。

ClangIR 项目旨在通过添加更紧密地模拟源结构的新抽象来解锁 C 和 C++ 代码的更好优化、分析和诊断的可能性,从而保留比标准 LLVM IR 中更多的细节。ClangIR 方言已经在使用 ClangIR 孵化器中提供的实现来解决实际问题,但我们需要将其移入主 LLVM 存储库,以便使此功能可供更广泛的受众使用。

该项目将是一个获得 MLIR 开发实践经验的机会,重点是日常软件工程规范。参与者将与其他 LLVM 贡献者并肩工作,以实现共同目标,并在此过程中深入了解 ClangIR 方言。

预期结果

  1. 将 ClangIR 对 C 和 C++ 语言特性的支持迁移到主 LLVM 存储库
  2. 在代码迁移过程中提高代码质量
  3. 提出改进迁移过程的方法

技能: 需要精通现代 C++ 编程并熟悉基本的编译器设计概念。之前有 LLVM IR、MLIR、Clang 或 ClangIR 编程经验是一个很大的加分项,但由于该项目的目标是获得此类经验,因此这不是先决条件。

项目规模: 中等到大型

难度:中等

潜在导师: Andy Kaylor Bruno Cardoso Lopes

Discourse: URL

描述: Clang 静态分析器 (CSA) 已经可以找到各种时间内存错误。这些检查通常具有关于某些 API 行为的硬编码知识。例如,cplusplus.InnerPointer 检查器知道 std::string::data 的语义。Clang 社区引入了一些生命周期注解,包括 [[clang::lifetimebound]][[clang::lifetime_capture_by(X)]],并对 Clang 的默认警告进行了 许多改进。不幸的是,编译器的警告仅进行语句局部分析。CSA 能够进行高级过程间分析。概括像 cplusplus.InnerPointer 这样的现有检查可以使分析器在带注解的代码中找到更多错误。一旦标准库 被注解,这可能会变得更具影响力。

预期结果

  1. 识别可以从 [[clang::lifetimebound]][[clang::lifetime_capture_by(X)]] 注解中受益的检查。
  2. 扩展这些检查以支持这些注解。
  3. 确保生成的错误报告质量高,诊断正确解释分析器如何考虑这些注解。
  4. 在真实世界的项目中验证结果。
  5. 可能警告有缺陷的注解(延伸目标)。

技能: 需要中级 C++ 编程技能和熟悉基本的编译器设计概念。之前有 Clang 或 CSA 编程经验是一个很大的加分项,但愿意学习也是一种可能性。

项目规模: 大型

难度:困难

潜在导师: Gabor Horvath Balazs Benics Daniel Domjan

Discourse: URL

描述

目前,没有简单的方法来获取使用 C++20 模块的源文件集合并从中构建可执行文件。这使得在不首先设置构建系统的情况下创建使用 C++20 模块的简单测试或小型程序变得困难。该项目的目标是扩展 Clang 驱动程序中极其简单的构建系统以处理这些情况。

这可以通过使用 Clang 现有的扫描 C++20 模块的支持来完成,以发现已传入的源文件之间的依赖关系,然后按该顺序构建它们,并在需要时传入正确的 PCM 文件。这也可以扩展为支持显式构建通过模块映射文件发现的 Clang 模块。

预期成果

调用 clang 类似于

clang -o program -std=c++20 main.cpp A.cppm B.cppm
应该成功编译,其中每个翻译单元仅导入在命令行或其他源文件中定义的模块,或标准库。这应该不会为未使用模块的情况增加开销。

已确认的导师及其联系方式

所需技能

中级 C++ 知识;熟悉 C++ 代码的构建方式。熟悉 C++20 模块是一个优势,但不是必需的。

项目规模

中等 (~175 小时)

项目难度

中等

Discourse: URL

描述

未定义行为消毒器 (UBSan) 是 Clang 中一种有用的编译模式,用于查找未定义行为(例如,有符号整数溢出)和有问题的 C/C++ 代码(例如,无符号整数溢出)的使用。UBSan 的默认版本使用仅在用户空间中工作的编译器运行时(例如,它在内核中或对于嵌入式应用程序不起作用),并且被认为不够安全,无法在生产环境中使用。为了处理这些其他环境,UBSan 提供了一种捕获模式,该模式发出陷阱指令,该指令立即停止应用程序,而不是调用 UBSan 运行时,后者通常诊断问题然后继续执行。

不幸的是,捕获 UBSan 存在一些缺陷,使其难以使用。特别是

  • Clang 静默忽略了-fsanitize-trap=undefined标志,当它在没有-fsanitize=undefined的情况下传递时。该项目将修复此问题,作为熟悉 Clang 代码库的“热身任务”。
  • 当使用附加的调试器命中 UBSan 陷阱时,不方便弄清楚 UBSan 陷阱的原因。对于 x86_64 和 arm64,一些信息被编码在指令中,但解码非常不方便。虽然可以教导 LLDB 查看指令并解码含义,但这很脆弱,因为它依赖于未文档化的编译器 ABI。相反,我们可以构建在__builtin_verbose_trap工作之上,将陷阱原因(“陷阱原因”)编码在调试信息中。如果时间允许,我们还可以研究发出更精确的陷阱原因

预期成果

  • -fsanitize-trap=undefined-fsanitize-trap=标志也传递。应该教导 Clang 警告这一点。标志单独传递时,编译器会静默忽略它。目前,Clang 要求
  • 教导 Clang 在 UBSan 陷阱指令上的调试信息中发出 UBSan 陷阱原因,类似于__builtin_verbose_trap的工作方式。
  • 确认 LLDB 能够识别 UBSan 陷阱原因并为此添加测试。
  • 如果时间允许,我们应该研究通过使用编译器中可用的信息来发出更精确的陷阱原因。我们可能希望实现类似于“Sema Diagnostic”的方法,其中可以在编译器内部轻松构建陷阱原因字符串。此任务更开放,并且可能在 UBSan 之外有用途(例如-fbounds-safety).

已确认的导师及其联系方式

所需技能

良好理解 C++

理想技能

  • 熟悉 UBSan
  • 熟悉 LLDB

项目规模

小型(~90 小时)。但如果时间允许,可以延长

项目难度

简单。这个项目对于 LLVM 的初学者来说是不错的。请注意,“发出更精确的陷阱原因”部分更开放,因此其难度完全取决于申请人选择的方向。

Discourse: URL

项目描述: Clang-Doc 是一个 C/C++ 文档生成工具,作为 Doxygen 的替代品而创建,并构建于 LibTooling 之上。这项工作始于 2018 年,并在 2019 年取得了重大进展,但其开发在很大程度上处于停滞状态,主要是由于资源匮乏,直到去年作为一个成功的 Google Summer of Code 项目重新启动开发。

该工具构建于 LibTooling 之上,并利用 Clang 解析器,该解析器支持解析文档注释中的 Doxygen 命令(此支持也用于 Clang 的实现中)

-Wdocumentation
它可以用于在编译期间验证文档注释的内容)。

不幸的是,Clang 的文档解析器并不完整,并且存在一些问题
  • 并非所有 Doxygen 命令都受支持,这限制了 Clang-Doc 的可用性。
  • 并非所有 C/C++ 构造目前都得到处理,最值得注意的是 C++20 的特性,例如概念。
  • Doxygen 1.8.0 版本中引入的文档注释中的 Markdown 支持缺失。

预期结果: 本项目的目标是实现 Clang 文档解析器中缺失的功能,以及在 Clang-Doc 中处理这些功能,以提高生成的文档的质量。最终目标是让 LLVM 项目开始使用 Clang-Doc 来生成其参考文档,但在我们做到这一点之前,我们需要确保所有必需的功能都已实现。

成功的提案不仅应侧重于解决现有的局限性,还应从其他文档工具(如 hdocstandardesesubdoccppdocgen)中汲取其他潜在改进的灵感。

在项目过程中,候选人将有机会获得有关 LLVM 和 Clang 内部机制(包括词法分析器和解析器)以及 C/C++ 语言的丰富经验。

技能: C++ 中级知识;对编译器和解析器感兴趣。 具有 Clang/LibTooling 的先前经验是加分项,但不是必需的。

项目规模: 中型或大型。

难度: 中等

已确认导师: Petr Hosek, Paul Kirth

Discourse 论坛: URL

项目描述: Clang 编译器是 LLVM 编译器基础设施的一部分,支持多种语言,如 C、C++、ObjC 和 ObjC++。LLVM 和 Clang 的设计使其能够作为库使用,并促成了一个完整的编译器辅助工具生态系统的创建。Clang 相对友好的代码库和 LLVM 中 JIT 基础设施的进步进一步推动了对处理 C++ 的不同方法的研究,模糊了编译时和运行时之间的界限。挑战包括增量编译以及将编译/链接时优化融入更动态的环境中。增量编译流水线通过构建不断增长的翻译单元来逐块处理代码。然后,代码被降级为 LLVM IR,并随后由 LLVM JIT 运行。这样的流水线允许创建高效的解释器。该解释器能够实现交互式探索,并使 C++ 语言更加用户友好。Clang-Repl 就是一个例子。

预期结果: 该项目旨在开发一种强大的机制,通过动态识别和加载适当的共享对象或静态库来解析缺失的符号。此外,它将探索根据执行配置文件调整符号的用例,从而实现可衡量的性能提升,优化即时编译和动态执行环境的效率。

技能: C++ 中级知识,理解 LLVM,特别是 LLVM JIT

项目规模:中型或大型。

难度: 中等

已确认导师: Vassil Vassilev

Discourse 论坛: URL

描述

Enzyme 需要关于类型内存布局的良好信息。LLVM-IR 是有意不透明的,例如 `&f32` 和 `&f64` 都具有 LLVM-IR 类型 `ptr`。Enzyme 通常能够通过使用分析来推断底层类型(例如 f32 与 f64),但该过程很慢,并且在某些情况下可能会失败。为了使 autodiff 更加健壮,我们应该将 MIR 或 THIR 类型信息降级到 LLVM-IR 元数据中。此分析是递归的,例如 `&[T]` 是一个胖指针,因此将在 LLVM-IR 中表示为 (ptr, int) 对。在这种情况下,算法还应递归分析 `T` 并为其生成元数据。

可以扩展 这里的 函数以从 rusts Mid-level IR (MIR) 生成元数据。解析器的原型已在 这里 实现,可用于提供灵感。可以在 测试文件夹中找到我们想要生成的元数据的各种 LLVM-IR 示例。查找 ` {[-1]:Pointer, [-1,0]:Float@float}` 风格的注释。

在线编译器 Explorer 分支可用于触发相关错误,从“无法推断 X 的类型”开始。

预期成果

参与者应查找并选择一些有趣的测试用例,在这些用例中,Enzyme 要么由于类型信息不足而无法区分示例,要么花费了不合理的长的时间(例如,比不使用 autodiff 编译代码慢 20 倍以上)。在第二种情况下,应使用性能分析器来验证 Enzyme 是否由于类型分析而导致编译时间过长。然后,参与者应编写(或稍后扩展)类型解析器以生成正确的元数据,以便 Enzyme 可以处理新的测试用例。LIT 测试用例应添加到 rust 编译器中,以避免进一步的回归。

目前未正确处理的代码示例可以在项目提案阶段进行讨论。

已确认的导师及其联系方式

所需技能

Rust 和 C++ 中级知识;熟悉性能分析器或 LLVM 元数据是加分项,但不是必需的。

项目规模

中等 (~175 小时)

项目难度

中等

Discourse 论坛: URL

描述: 目前,每个想要支持调用 C 代码 (FFI) 的基于 LLVM 的前端都需要重新实现大量的复杂调用 ABI 处理。本项目的目标是引入一个 LLVM ABI 库,该库可以在不同的前端(包括 Clang)之间重用。有关动机和设计概要的更多详细信息,请参见 相应的 RFC

该项目的初始阶段将是实现一个原型,该原型至少可以处理 x86_64 System V ABI。这将涉及实现 ABI 类型系统,将 Clang 类型映射到 ABI 类型,以及将 Clang 的 X86 ABIInfo 实现的至少一部分移动到新的 ABI 库。这是为了证明总体可行性,找出设计问题并分析编译时间的影响。

假设原型的结果是积极的,下一步将是通过将其拆分为较小的 PR 来向上游提交实现。最后,可以扩展实现以涵盖其他目标,最终完全删除 Clang 的 ABI 处理代码。

预期结果: 最低结果是 x86_64 ABI 的原型。最大结果是完全向上游提交对所有目标的支持。预期结果介于两者之间。

技能: C++ 中级。 对 LLVM 有一定的熟悉度是加分项,但不是必需的。

项目规模: 大型

难度: 困难

已确认导师: Nikita Popov

Discourse 论坛: URL

描述: 由于缺乏表示原始内存的方式,LLVM IR 无法正确表示 memcpy、memcmp 等的实现。本项目旨在向 LLVM IR 添加一个新的“byte”类型来表示原始内存。

除了添加新类型之外,该项目还涉及更改 clang 以将 chars 降级为新的 b8 类型而不是 i8,修复内存内部函数的错误降级,并跟踪性能回归。

已经有一个针对旧版本 LLVM 的 byte 类型的 原型 实现。更多信息请参见 这里

预期结果: 最低结果是将现有原型移植到当前 LLVM,修复所有已知的错误优化,为 Alive2 添加 byte 类型支持,以及性能分析。

技能: C++ 中级,熟悉 LLVM,性能分析。

项目规模: 大型

难度: 困难

已确认导师: Nuno Lopes

Discourse 论坛: URL

描述: LLVM 通过 remarks、性能分析或运行时调试注释(例如,LIBOMPTARGET_INFO=-1)提供不同的信息。但是,随着项目规模的扩大,用户越来越难以剖析这些信息。例如,在构建大型项目时,很难收集所有这些数据、对其进行可视化并从中学习。

目前,某些此类信息(例如,编译 remarks)可以导出为 JSON 格式。我们希望创建一个工具来可视化、聚合和总结这些信息。为了帮助加速器开发,我们将从 offload 项目开始作为主要候选项目。

类似的工具,例如 opt-viewer,可以用作参考和起点。

预期成果: 预期的成果是一个工具(例如,以编译器包装器(如 ccache)的形式),它将允许以 JSON 格式转储所有编译器生成的信息,并将其组织在项目结构中。

该工具应生成基于 HTML 的报告,以帮助可视化 remarks。我们设想一个小型客户端-服务器应用程序,使用 Python 来生成本地服务器作为可视化的前端。服务器将公开不同的报告并执行早期分析和聚合。

此外,该工具的设计应使其在未来能够对 remarks 进行分析,从而为开发人员提供通用指南(例如,显示最常见的 remark,使用 LLM 模型来解释操作等)。客户端(HTML 查看器)将显示聚合数据、内联 remarks、性能分析信息等。我们不期望该项目在 GSoC 结束时拥有所有功能,而是作为未来增长的占位符。

特别是,本项目的成果应包括

  • 与导师一起,帮助设计编译器包装器、数据存储层和客户端/服务器基础设施。这包括服务器 API。此任务的成果是一份设计文档(类似于 RFC)。
  • 创建一个编译器包装器,该包装器将以 JSON 格式将不同的信息转储到数据存储层(例如,文件夹)。
  • 创建一个简单的服务器层,该层向前端公开后端 API。Python 是执行此操作的正确方法,但我们欢迎其他与 LLVM 项目一致的建议。我们希望避免依赖外部项目(例如,Flask),以避免向 LLVM 项目添加更多依赖项。
  • 创建一个简单的客户端可视化工具,该工具在未来可以扩展以显示更多报告。

导师: @shiltian, @jdoerfert, @josemonsalve2

所需/期望的技能

  • 对 LLVM 编译器有基本的了解,能够从编译器生成编译器 remarks、性能分析数据和其他信息。
  • 精通 Python 和 C++。
  • 全栈 Web 开发。

项目规模: 大型

难度: 简单

Discourse 链接: [GSoC][Offload]LLVM 编译器 Remarks 可视化工具 Offload 提案

Google Summer of Code 2024 对 LLVM 项目来说又是成功的一年。有关已接受和已完成项目的列表,请查看 Google Summer of Code 网站

欢迎有希望参加 Google Summer of Code 2024 的学生!本文档是您寻找 LLVM、Clang 和其他相关子项目的有趣且重要项目的起点。此项目列表不仅为 Google Summer of Code 而开发,也是真正需要开发人员参与且对 LLVM 社区非常有益的开放项目。

我们鼓励您浏览此列表,看看哪些项目让您兴奋并与您的技能组合良好匹配。我们也欢迎不在此列表中的提案。有关 GSoC 的更多信息和讨论,请访问 discourse 。如果您对特定项目有疑问,请在 discourse 中找到相关条目,查看之前的讨论并提问。如果没有这样的条目,或者您想提出一个想法,请创建一个新条目。来自社区的反馈是您的提案被考虑并有望被接受的必要条件。

LLVM 项目已参与 Google Summer of Code 多年,并取得了一些非常成功的项目。我们希望今年也不例外,并期待收到您的提案。有关如何提交提案的信息,请访问 Google Summer of Code 主要 网站。

项目描述: LLVM 的许多单元测试都是从较大的测试中自动缩减而来的。上一代缩减工具到处使用 undef 和 poison 作为占位符,并引入了未定义行为 (UB)。具有 UB 的测试是不受欢迎的,因为 1) 它们很脆弱,因为将来编译器可能会开始更积极地优化并破坏测试,以及 2) 它破坏了翻译验证工具,例如 Alive2(因为将始终为 UB 的函数翻译成任何内容都是正确的)。
主要步骤包括

  1. 用非 UB 模式替换已知的模式,例如 undef/poison 上的分支、具有无效指针的内存访问等。
  2. 使用 Alive2 检测更多模式(通过搜索始终为 UB 的测试)。
  3. 报告 Alive2 在删除 UB 时发现的任何 LLVM 错误。

预期结果: 大部分 LLVM 的单元测试将不包含 UB。

技能: 需要具有脚本编写(Python 或 PHP)经验。 鼓励具有正则表达式的经验。

项目规模: 中型或大型。

难度: 中等

已确认导师: Nuno Lopes

Discourse 论坛: URL

项目描述: LLVM 中描述 SPIR-V 指令集的现有文件是手动创建的,并且并非总是完整或最新的。每当需要向 SPIR-V 后端添加新指令时,都必须修改该文件。此外,由于它不是以系统的方式创建的,因此 SPIR-V 规范中指令的描述与 TableGen 文件中指令的声明之间通常存在细微的差异。由于 SPIR-V 后端开发人员在开发新功能时经常使用规范作为参考,因此在规范和 TableGen 记录之间建立一致的映射将简化开发。本项目建议创建一个脚本,该脚本能够根据 KhronosGroup/SPIRV-Headers 存储库中提供的 JSON 语法,生成完整的描述 SPIR-V 指令集的 TableGen 文件,并更新 SPIR-V 后端代码以使用新的定义。将 JSON 语法转换为 TableGen 的具体方法由申请人自行决定,但是,应将其检入 LLVM 存储库,并附带详细记录的说明以复制转换过程,以便未来的维护人员能够在语法更改时重新生成文件。请注意,语法本身应保留在树外,位于其现有的单独存储库中。

预期结果

  • TableGen 中 SPIR-V 指令集的定义将替换为自动生成的定义。
  • 编写一个脚本和文档,以支持根据 SPIR-V 指令集的 JSON 语法,根据需要重新生成定义。
  • 更新 SPIR-V 后端中 SPIR-V 指令集的使用,以使用新的自动生成的定义。

技能: 具有脚本编写经验和 C++ 中级知识。 具有 LLVM/TableGen 的先前经验是加分项,但不是必需的。

项目规模: 中型 (175 小时)

已确认导师: Natalie Chouinard, Nathan Gauër

Discourse 论坛: URL

项目描述: LLVM bitstream 文件格式用于序列化中间编译器工件,例如 LLVM IR 或 Clang 模块。在某些情况下,多个 bitstream 文件存储相同的信息,这种重复会导致存储需求增加。

本项目旨在将 LLVM CAS 库集成到 LLVM bitstream 文件格式中。如果我们从 bitstream 文件中提取频繁重复的部分到单独的 CAS 对象中,我们可以用对规范 CAS 对象的小引用替换所有副本,从而节省存储空间。

本项目的主要动机用例是依赖项扫描器,该扫描器为“隐式发现、显式构建”的 Clang 模块提供支持。在实际应用中,即使在块级别进行粗略的去重也可以将扫描模块缓存的大小减半。

预期结果: 有一种方法可以配置 LLVM bitstream 写入器/读取器以使用 CAS 作为后备存储。

技能: C++ 中级知识,对数据序列化有一定的熟悉度,自我激励。

项目规模: 中型或大型

已确认导师: Jan Svoboda, Steven Wu

Discourse 论坛: URL

项目描述: 三向比较 根据值是小于、等于还是大于,返回 -1、0 或 1。它们在 C++ 中通过太空船运算符 (operator<=>) 暴露,在 Rust 中通过 PartialOrd 和 Ord traits 暴露。目前,在某些情况下,此类比较会产生次优的代码生成和优化结果。

本项目的目标是通过实现新的三向比较内部函数来解决这些优化问题,如 [RFC] 添加三向比较内部函数 中所述。实现步骤大致如下

  1. 将内部函数添加到 LLVM IR。
  2. 在 SelectionDAG 和 GlobalISel 中实现合法化/扩展支持。
  3. 在 ConstantFolding、InstSimplify、InstCombine、CorrelatedValuePropagation、IndVarSimplify、ConstraintElimination、IPSCCP 和其他相关转换中实现优化支持。
  4. 通过 InstCombine 规范化或在 clang/rustc 中直接发射来使用内部函数。
添加新的目标无关的内部函数是熟悉 LLVM 的广泛领域的好方法!

预期结果: 后端和最重要的优化传递中对内部函数的支持。理想情况下,从前端开始完全集成。

技能: C++ 中级知识

项目规模: 中型或大型

难度: 中等

已确认导师: Nikita Popov, Dhruv Chawla

Discourse 论坛: URL

项目描述: llvm.org 网站是关于 LLVM 项目信息的中心枢纽,涵盖项目详细信息、当前事件和相关资源。随着时间的推移,该网站已自然发展,促使需要重新设计以增强其现代性、结构和易于维护性。

本项目的目标是创建一个现代且连贯的静态网站,以反映 LLVM.org 的精髓。此重新设计旨在改进导航、分类、内容可发现性、移动设备支持、可访问性和整体可用性。鉴于该网站在社区中的关键作用,将努力与社区成员互动,就拟议的更改寻求共识。

预期结果: 一个现代、外观连贯的网站,可以吸引新的潜在用户,并通过更好的导航、分类、内容可发现性和整体可用性来增强现有社区的能力。由于该网站是关键的基础设施,并且大多数社区成员都会对此项目发表意见,因此该项目应尝试与社区互动,就正在采取的步骤建立社区共识。建议的方法

  • 对现有网站进行全面的内容审核。
  • 选择适当的技术,最好是 Hugo 或 Jekyll 等静态站点生成器。
  • 倡导数据和可视化分离,利用 YAML 和 Markdown 等格式来促进内容管理,而无需直接进行 HTML 编码。
  • 展示新网站的三个设计模型,促进公开讨论,并为感兴趣的各方提供替代方案留出时间。
  • 实施选定的设计,并纳入来自社区的宝贵反馈。
  • 与内容创建者协作,根据需要集成或更新内容。
成功的候选人应承诺定期参加每周会议,进行演示,并根据要求撰写博客文章。此外,他们应展示出有耐心和理解力地驾驭社区流程的能力。

技能: 具有静态站点生成器的 Web 开发领域知识。 html、css、bootstrap 和 markdown 知识。 有耐心和自我激励。

难度: 困难

项目规模: 大型

已确认导师: Tanya Lattner, Vassil Vassilev

Discourse 论坛: URL

项目描述: Clang 编译器是 LLVM 编译器基础设施的一部分,支持多种语言,如 C、C++、ObjC 和 ObjC++。LLVM 和 Clang 的设计使其能够作为库使用,并促成了一个完整的编译器辅助工具生态系统的创建。Clang 相对友好的代码库和 LLVM 中 JIT 基础设施的进步进一步推动了对处理 C++ 的不同方法的研究,模糊了编译时和运行时之间的界限。挑战包括增量编译以及将编译/链接时优化融入更动态的环境中。

增量编译流水线通过构建不断增长的翻译单元来逐块处理代码。然后,代码被降级为 LLVM IR,并随后由 LLVM JIT 运行。这样的流水线允许创建高效的解释器。该解释器能够实现交互式探索,并使 C++ 语言更加用户友好。Clang-Repl 就是一个例子。

Clang-Repl 在同一进程中使用 Orcv2 JIT 基础设施。该设计高效且易于实现,但存在两个明显的缺点。首先,它不能用于没有足够资源来托管整个基础设施的设备中,例如 arduino due(有关更多详细信息,请参见此 talk)。其次,用户代码中的崩溃意味着整个进程崩溃,从而降低了整体可靠性和易用性。

本项目旨在将 Clang-Repl 迁移到进程外执行模型,以解决这两个问题。

预期结果: 实现 Clang-Repl 的语句的进程外执行; 证明 Clang-Repl 可以支持某些 ez-clang 用例; 研究在崩溃时重启/继续会话的方法; 作为一个延伸目标,设计一种通用的崩溃恢复可靠性方法;

技能: C++ 中级知识,理解 LLVM,特别是 LLVM JIT

项目规模:中型或大型。

难度: 中等

已确认导师: Vassil Vassilev,

Discourse 论坛: URL

项目描述: Clang 编译器是 LLVM 编译器基础设施的一部分,支持多种语言,如 C、C++、ObjC 和 ObjC++。LLVM 和 Clang 的设计允许使用插件 [1] 扩展编译器。插件使得在编译期间运行额外的用户定义操作成为可能。插件在 unix 和 darwin 上受支持,但在 windows 上不受支持,这归因于 windows 平台的一些特殊性。

本项目将使参与者接触到 LLVM 代码库的广泛横截面。它涉及探索 API 表面,将接口分类为公共接口或私有接口,并将该信息注释到 API 声明中。它还将使参与者了解不同平台的详细信息和差异,因为这项工作是跨平台的(Windows、Linux、Darwin、BSD 等)。由此产生的更改将改进 Linux 和 Windows 上的 LLVM,同时在 Windows 上启用新功能。

预期结果: 本项目旨在使 clang -fplugin=windows/plugin.dll 工作。实现方法应扩展工作原型 [3] 并扩展注释工具 [4]。成功的候选人应准备好参加每周会议,进行演示并根据要求准备博客文章。

进一步阅读
[1] https://clang.llvm.net.cn/docs/ClangPlugins.html
[2] https://discourse.llvm.org/t/clang-plugins-on-windows
[3] https://github.com/llvm/llvm-project/pull/67502
[4] https://github.com/compnerd/ids

技能: C++ 中级知识,具有 Windows 及其编译和链接模型的经验。

项目规模:中型或大型。

难度: 中等

已确认导师: Vassil Vassilev, Saleem Abdulrasool

Discourse 论坛: URL

项目描述: Clang,像任何 C++ 编译器一样,线性地解析字符序列。然后,线性字符序列在降级为机器代码之前被转换为标记和 AST。在许多情况下,最终用户代码仅使用来自整个翻译单元的一小部分 C++ 实体,但用户仍然要为编译所有冗余内容付出代价。

本项目建议在使用时而不是急切地处理繁重的编译 C++ 实体。Clang 的 CodeGen 已经采用了这种方法,它允许 Clang 仅为正在使用的内容生成代码。按需编译有望显着减少编译峰值内存,并提高稀疏使用其内容的翻译单元的编译时间。此外,这将对交互式 C++ 产生重大影响,其中头文件包含本质上变为无操作,并且实体将仅按需解析。

Cling 解释器实现了一种非常幼稚但高效的跨翻译单元惰性编译优化,该优化在能源物理学领域数百个库中扩展。

// A.h
#include <string>
#include <vector>
template <class T, class U = int> struct AStruct {
  void doIt() { /*...*/ }
  const char* data;
  // ...
};

template<class T, class U = AStruct<T>>
inline void freeFunction() { /* ... */ }
inline void doit(unsigned N = 1) { /* ... */ }

// Main.cpp
#include "A.h"
int main() {
  doit();
  return 0;
}
    


这个病态的示例扩展到 37253 行代码进行处理。Cling 构建了一个索引(它称之为自动加载映射),其中仅包含这些 C++ 实体的转发声明。它们的大小为 3000 行代码。索引看起来像
// A.h.index
namespace std{inline namespace __1{template <class _Tp, class _Allocator> class __attribute__((annotate("$clingAutoload$vector")))  __attribute__((annotate("$clingAutoload$A.h")))  __vector_base;
  }}
...
template <class T, class U = int> struct __attribute__((annotate("$clingAutoload$A.h"))) AStruct;
    


在需要实体的完整类型时,Cling 会包含相关的头文件以获取它。有一些简单的解决方法可以处理默认参数和默认模板参数,因为它们现在出现在转发声明和定义中。您可以在 [1] 中阅读更多内容。

尽管该实现不能称为参考实现,但它表明 Clang 的 Parser 和 Preprocessor 是相对无状态的,可以用于处理本质上不是线性的字符序列。特别是命名空间范围的定义相对容易处理,并且当我们惰性解析某些内容时,返回到命名空间范围并不十分困难。对于其他上下文(例如局部类),我们将丢失一些重要信息,例如局部实体的名称查找表。但是,这些情况可能不是很令人感兴趣,因为惰性解析粒度可能仅对顶级实体值得。

这样的实现可以帮助解决标准中已存在的问题,例如 CWG2335,在该问题下,类的延迟部分会在首次需要时立即解析,如果第一次使用发生在类结束之前。这应该为向上游提交返回到封闭范围并解析某些内容所需的所有操作提供良好的动机。

实现方法:在解析期间看到标记定义后,我们可以创建一个转发声明,记录标记序列并将其标记为惰性定义。稍后在完全类型请求时,我们可以重新定位解析器以解析定义主体。我们已经以类似的方式跳过了一些模板特化 [2, 3]。

另一种方法是每个惰性解析的实体记录其标记流,并更改存储在 LateParsedDeclarations 上的 Toks,以可选地引用外部存储的标记序列的子序列,而不是存储其自己的序列(或者可能更改 CachedTokens 以使其可以透明地执行此操作)。挑战之一是,我们当前修改缓存的标记列表以附加“eof”标记,但应该可以以不同的方式处理它。

在某些情况下,类定义会以几种方式影响其周围的上下文,您需要在此处小心

1) 出现在类内部的 `struct X` 可以将名称 `X` 引入到封闭上下文中。

2) `static inline` 声明可以引入具有非恒定初始化器的全局变量,这些变量可能具有任意副作用。

对于第 (2) 点,存在一个更普遍的问题:解析任何表达式都可能触发类模板的模板实例化,该类模板具有带有具有副作用的初始化器的静态数据成员。与上述两种情况不同,我不认为我们可以通过对标记流进行一些简单的分析来正确检测和处理此类情况;需要实际的语义分析来检测此类情况。但是,如果它们仅发生在本身未使用的代码中,那么 Clang 具有一种不保证此类实例化实际发生的语言模式可能并不可怕。

替代和更高效的实现可能是使查找表基于范围,但我们甚至没有原型证明这可能是一种可行的方法。

预期结果

  • 非模板函数的按需编译的设计和实现
  • 支持非模板结构体和类
  • 在相关代码库上运行性能基准测试并准备报告
  • 准备社区 RFC 文档
  • [延伸目标] 支持模板
成功的候选人应承诺定期参加每周会议,进行演示,并根据要求撰写博客文章。此外,他们应展示出有耐心和理解力地驾驭社区流程的能力。

进一步阅读
[1] https://github.com/root-project/root/blob/master/README/README.CXXMODULES.md#header-parsing-in-root
[2] https://github.com/llvm/llvm-project/commit/b9fa99649bc99
[3] https://github.com/llvm/llvm-project/commit/0f192e89405ce

技能: C++ 知识,更深入地了解 Clang 的工作原理,Clang AST 和 Preprocessor 的知识。

项目规模:大型

难度: 困难

已确认导师: Vassil Vassilev, Matheus Izvekov

Discourse 论坛: URL

项目描述: Clang-Doc 是一个 C/C++ 文档生成工具,作为 Doxygen 的替代品而创建,并构建于 LibTooling 之上。这项工作始于 2018 年,并在 2019 年取得了重大进展,但此后的开发一直处于休眠状态,主要是由于资源匮乏。

该工具目前可以生成 Markdown 和 HTML 格式的文档,但该工具存在一些结构性问题,难以使用,生成的文档存在可用性问题,并且缺少几个关键功能

  • 并非所有 C/C++ 构造当前都由 Markdown 和 HTML 发射器处理,这限制了该工具的可用性。
  • 生成的 HTML 输出无法随代码库的大小进行扩展,这使得它对于较大的 C/C++ 项目不可用。
  • 该实现并非始终使用最有效或最合适的数据结构,这会导致正确性和性能问题。
  • 存在大量重复的样板代码,可以使用模板和助手进行改进。

预期结果: 本项目的目标是解决现有的缺点,并将 Clang-Doc 的可用性提高到可以用于为 LLVM 等大型项目生成文档的程度。理想的结果是 LLVM 项目将使用 Clang-Doc 来生成其 参考文档

成功的提案不仅应侧重于解决现有的局限性,还应从其他类似工具(如 hdocstandardesesubdoccppdocgen)中汲取其他潜在改进的灵感。

技能: 具有 Web 技术(HTML、CSS、JS)的经验和 C++ 中级知识。 具有 Clang/LibTooling 的先前经验是加分项,但不是必需的。

项目规模: 中型或大型。

难度: 中等

已确认导师: Petr Hosek, Paul Kirth

讨论区: URL

描述

使用调试信息中的变量位置信息来注释 LLDB 的反汇编器(和 `register read`)输出,其中包含源变量的位置和生命周期。富反汇编器输出应作为结构化数据公开,并通过 LLDB 的脚本 API 提供,以便在此基础上构建更多工具。在终端中,LLDB 应将注释呈现为文本。

预期成果

例如,我们可以增强以下函数的反汇编
frame #0: 0x0000000100000f80 a.out`main(argc=1, argv=0x00007ff7bfeff1d8) at demo.c:4:10 [opt]
  1   void puts(const char*);
  2   int main(int argc, char **argv) {
  3    for (int i = 0; i < argc; ++i)
→ 4      puts(argv[i]);
  5    return 0;
  6   }
(lldb) disassemble
a.out`main:
...
  0x100000f71 <+17>: movl  %edi, %r14d
  0x100000f74 <+20>: xorl  %r15d, %r15d
  0x100000f77 <+23>: nopw  (%rax,%rax)
→  0x100000f80 <+32>: movq  (%rbx,%r15,8), %rdi
  0x100000f84 <+36>: callq 0x100000f9e ; symbol stub for: puts
  0x100000f89 <+41>: incq  %r15
  0x100000f8c <+44>: cmpq  %r15, %r14
  0x100000f8f <+47>: jne 0x100000f80 ; <+32> at demo.c:4:10
  0x100000f91 <+49>: addq  $0x8, %rsp
  0x100000f95 <+53>: popq  %rbx
...

使用 LLDB 也有权访问的调试信息(观察源变量 i 如何从 [0x100000f77+slide) 开始位于 r15 中)

$ dwarfdump demo.dSYM --name  i
demo.dSYM/Contents/Resources/DWARF/demo: file format Mach-O 64-bit x86-64
0x00000076: DW_TAG_variable
 DW_AT_location (0x00000098:
 [0x0000000100000f60, 0x0000000100000f77): DW_OP_consts +0, DW_OP_stack_value
 [0x0000000100000f77, 0x0000000100000f91): DW_OP_reg15 R15)
 DW_AT_name ("i")
 DW_AT_decl_file ("/tmp/t.c")
 DW_AT_decl_line (3)
 DW_AT_type (0x000000b2 "int")
生成这样的输出,我们在其中注释变量何时处于活动状态以及其位置
(lldb) disassemble
a.out`main:
...                                                               ; i=0
  0x100000f74 <+20>: xorl  %r15d, %r15d                           ; i=r15
  0x100000f77 <+23>: nopw  (%rax,%rax)                            ; |
→  0x100000f80 <+32>: movq  (%rbx,%r15,8), %rdi                   ; |
  0x100000f84 <+36>: callq 0x100000f9e ; symbol stub for: puts    ; |
  0x100000f89 <+41>: incq  %r15                                   ; |
  0x100000f8c <+44>: cmpq  %r15, %r14                             ; |
  0x100000f8f <+47>: jne 0x100000f80 ; <+32> at t.c:4:10          ; |
  0x100000f91 <+49>: addq  $0x8, %rsp                             ; i=undef
  0x100000f95 <+53>: popq  %rbx

目标是为一部分明确的情况生成这样的输出,例如,常量或完全在寄存器中的变量。

已确认的导师及其联系方式

  • Adrian Prantl aprantl@apple.com (主要联系人)
  • Jonas Devlieghere jdevlieghere@apple.com

所需/期望的技能

必需

  • 良好理解 C++
  • 熟悉在终端上使用调试器
  • 需要熟悉上面示例中提到的所有概念
  • 需要良好理解至少一种机器代码汇编方言(x86_64 或 AArch64)。

期望

  • 编译器知识,包括数据流和控制流分析,是一个加分项。
  • 能够导航调试信息 (DWARF) 是一个加分项。

项目规模。

中等 (~175 小时)

如果可能,请给出简单、中等或困难的评级

困难

Discourse: URL

描述

LLVM-reduce 和类似的工具执行 delta 调试,但如果存在许多隐式约束,并且违规容易导致类似于要隔离的原因的错误,则它们不太有用。此项目是关于开发一个 GPU 感知版本,特别是针对执行时间错误,它可以与 LLVM/OpenMP GPU 记录和重放或简单的 GPU 加载器脚本结合使用,以更有效和高效地最小化 GPU 测试用例。

预期成果

一个在不丢失原始错误的情况下减少 GPU 错误的工具。可选地,其他属性可能是缩减的重点,而不仅仅是错误。

已确认的导师及其联系方式

  • Parasyris,Konstantinos parasyris1@llnl.gov
  • Johannes Doerfert jdoerfert@llnl.gov

所需/期望的技能

必需

  • 良好理解 C++
  • 熟悉 GPU 和 LLVM-IR

期望

  • 编译器知识,包括数据流和控制流分析,是一个加分项。
  • 具有调试和错误缩减技术(llvm-reduce)的经验将有所帮助

项目规模。

中等

如果可能,请给出简单、中等或困难的评级

中等

讨论区: URL

描述

现代 C++ 将并行算法定义为标准库的一部分,例如 `std::transform_reduce(std::execution::par_unseq, vec.begin(), vec.end(), 0, std::plus, …)`。在这个项目中,我们希望扩展这些算法的实现,该实现使用 OpenMP,包括 GPU 卸载(如果合理)。虽然一些算法可能适合通过纯(包装器)运行时解决方案进行 GPU 卸载,但我们知道其他算法,特别是那些具有用户提供的 functor 的算法,还需要静态程序分析,并可能需要转换以进行额外的数据管理。该项目的目标是探索不同的算法以及我们在主机以及加速器设备(特别是 GPU)上自动通过 OpenMP 执行它们的选项。

预期成果

改进 libcxx 中卸载的原型支持。与其他卸载方法进行评估,并记录缺失部分和缺点。

已确认的导师及其联系方式

  • Johannes Doerfert jdoerfert@llnl.gov
  • Tom Scogland scogland1@llnl.gov
  • Tom Deakin tom.deakin@bristol.ac.uk

所需/期望的技能

必需

  • 良好理解 C++ 和 C++ 标准算法
  • 熟悉 GPU 和 (OpenMP) 卸载

期望

  • 具有 libcxx(开发)经验。
  • 具有调试和分析 GPU 代码的经验。

项目规模。

大型

如果可能,请给出简单、中等或困难的评级

中等

讨论区: URL

描述

LLVM 有很多阈值和标志来避免“代价高昂的情况”。但是,尚不清楚这些阈值是否有用,它们的值是否合理,以及它们真正的影响是什么。由于有很多阈值,我们无法进行简单的穷举搜索。在一些原型工作中,我们引入了一个 C++ 类,它可以替换硬编码值并提供对阈值的控制,例如,您可以通过命令行标志将递归限制从硬编码的“6”增加到不同的数字。在这个项目中,我们希望探索阈值,何时会达到阈值,达到阈值意味着什么,我们应该如何选择它们的值,以及我们是否需要不同的“配置文件”。

预期成果

关于 LLVM 代码库内部各种阈值影响的统计证据,包括编译时间变化、对转换的影响以及性能测量。

已确认的导师及其联系方式

  • Jan Hueckelheim jhueckelheim@anl.gov
  • Johannes Doerfert jdoerfert@llnl.gov
  • William Moses wmoses@mit.edu

所需/期望的技能

必需

  • 分析技能和统计推理知识

期望

  • 良好理解 LLVM 代码库和优化流程

项目规模。

中等

如果可能,请给出简单、中等或困难的评级

简单

讨论区: URL

描述

我们已经开始着手开发针对 GPU 的 libc 库。这将允许用户在 GPU 上执行时调用诸如 malloc 或 memcpy 之类的函数。但是,重要的是这些实现必须是功能性的和高性能的。该项目的目标是对 GPU 上某些 libc 函数的实现进行基准测试。工作将包括编写基准测试来测试当前的实现,以及编写更优化的实现。

预期成果

libc 函数的深入性能分析。GPU 到 CPU 远程过程调用的开销。更优化的“libc”函数实现。

已确认的导师及其联系方式

  • Joseph Huber joseph.huber@amd.com
  • Johannes Doerfert jdoerfert@llnl.gov

所需/期望的技能

必需

  • 分析技能和对 GPU 架构的理解

期望

  • 具有 libc 实用程序的经验

项目规模。

小型

如果可能,请给出简单、中等或困难的评级

简单

讨论区: URL

描述

GPU First 是一种方法和框架,可以使任何现有的主机代码在 GPU 上执行整个程序,而无需用户进行任何修改。该项目的目标有两个方面:1) 移植 主机代码 以处理到新插件的 RPC,并使用 GPU LibC 项目中引入的主机 RPC 框架重写它。2) 探索单个 GPU 甚至多个 GPU 上多个线程块之间的 MPI 支持。

预期成果

更高效的 GPU First 框架,可以支持 NVIDIA 和 AMD GPU。可选地,向上游提交框架。

已确认的导师及其联系方式

  • Shilei Tian i@tianshilei.me
  • Johannes Doerfert jdoerfert@llnl.gov
  • Joseph Huber joseph.huber@amd.com

所需/期望的技能

必需

  • 良好理解 C++ 和 GPU 架构
  • 熟悉 GPU 和 LLVM IR

期望

  • 良好理解 LLVM 代码库和 OpenMP 目标卸载

项目规模。

中等

如果可能,请给出简单、中等或困难的评级

中等

讨论区: URL

项目描述: 诸如 SYCLOpenMPOpenACC 等异构编程模型帮助开发人员将计算密集型内核卸载到 GPU 和其他加速器。MLIR 有望为下一代异构编程模型编译器解锁新的高级优化和更好的代码生成。然而,一个健壮的 MLIR 发射 C/C++ 前端的可用性是这些努力的先决条件。

ClangIR (CIR) 项目旨在为 Clang 建立一个新的中间表示 (IR)。它构建在 MLIR 之上,为 Clang 中基于 C/C++ 的语言提供了一种方言,以及从 Clang AST 发射它所需的基础设施,以及到 LLVM-IR 方言的降低路径。在过去的一年中,ClangIR 已经发展成为一个成熟的孵化器项目,最近关于将其上游提交到 LLVM monorepo 的 RFC 获得了积极的评论和社区支持。

这个 GSoC 项目的总体目标是识别和实现 ClangIR 中缺失的功能,以便能够将 OpenCL C 语言 中的 GPU 内核编译为用于 SPIR-V 目标的 LLVM-IR。OpenCL 到 SPIR-V 流程是这个项目的绝佳环境,因为 a) Clang 中 已经支持 它,并且 b) OpenCL 基于工作项和工作组的编程模型仍然很好地捕捉了现代 GPU 架构。贡献者将扩展 AST 访问器、方言和 LLVM-IR 降低,以添加对例如多个地址空间、向量和自定义浮点类型以及 spir_kernelspir_func 调用约定 的支持。

这项工作的一个良好起点是 Polybench-GPU 基准测试套件。它包含常见算法的独立的中小型 OpenCL 实现。我们预计只有设备代码(*.cl 文件)将通过 ClangIR 编译。Clang 中现有的 OpenCL 支持可用于创建带有参考 LLVM-IR 输出的 lit 测试,以指导开发。可选地,Polybench 中的内置结果验证和时间测量也可用于评估生成的代码的正确性和质量。

预期结果: Polybench-GPU 的 2DCONVGEMMCORR OpenCL 内核可以使用 ClangIR 编译为用于 SPIR-V 的 LLVM-IR。

技能: 需要中级 C++ 编程技能和对基本编译器设计概念的熟悉。具有 LLVM IR、MLIR、Clang 或 GPU 编程的先验经验是一个很大的优势,但学习意愿也是一种可能性。

项目规模: 大型

难度: 中等

已确认导师: Julian OppermannVictor LomüllerBruno Cardoso Lopes

讨论区: URL

描述

半精度是一种 IEEE 754 浮点格式,最近已被广泛使用,尤其是在机器学习和 AI 中。它已在最新的 C23 标准中标准化为 _Float16,使其支持程度与 float 或 double 数据类型相同。该项目的目标是在 LLVM libc 库中实现 C23 半精度数学函数。

预期结果

  • 正确设置生成的头文件,以便类型和函数可以与各种编译器(+版本)和架构一起使用。
  • 实现支持半精度数据类型的通用基本数学运算,这些运算可以在受支持的架构上工作:x86_64、arm (32 + 64)、risc-v (32 + 64) 和 GPU。
  • 尽可能使用编译器内置函数或特殊的硬件指令来实现特化,以提高其性能。
  • 如果时间允许,我们可以开始研究更高精度的半精度数学函数。

技能

需要中级 C++ 编程技能和对基本编译器设计概念的熟悉。具有 LLVM IR、MLIR、Clang 或 GPU 编程的先验经验是一个很大的优势,但学习意愿也是一种可能性。

项目规模: 大型

难度: 简单/中等

已确认导师: Tue LyJoseph Huber

讨论区: URL

Google Summer of Code 2023 对 LLVM 项目来说非常成功。有关已接受和已完成项目的列表,请查看 Google Summer of Code 网站

项目描述: 在即时编译器中,我们通常选择较低的优化级别,以最大限度地减少编译时间并缩短启动时间和延迟,但是某些函数(我们称之为热函数)被非常频繁地使用,对于这些函数,更值得进行更重的优化。通常,热函数只能在运行时识别(不同的输入将导致不同的函数成为热函数),因此重新优化项目的目标是构建基础设施以 (1) 在运行时检测热函数,以及 (2) 以更高的优化级别第二次编译它们,因此得名“重新优化”。

对于这个问题的两个部分,有很多可能的方法。例如,可以通过采样、使用现有的分析基础设施或通过实施自定义检测来识别热函数。重新优化可以应用于整个函数,或者可以使用 outlining 来启用函数部分的优化。从 JIT 代码重新进入 JIT 基础设施可以在现有的惰性编译之上实现,或者通过自定义路径实现。

无论采用何种设计,目标是基础设施应该是通用的,以便可以被其他 LLVM API 客户端使用,并且应该支持进程外 JIT 编译(因此一些解决方案将在 ORC 运行时中实现)。

预期结果

  • 改进间接引用的工效学 - 理想情况下,所有形式的间接引用(用于重新优化、惰性编译和过程链接表)都应该能够在运行时共享单个存根(和/或二进制重写元数据)。
  • 在整理后的间接引用之上实现基本重新优化。
  • (延伸目标)垃圾回收不再需要的未优化代码,一旦优化的版本可用。

期望技能: 中级 C++;理解 LLVM,特别是 LLVM JIT。

项目规模: 大型。

难度: 中等

已确认导师: Vassil VassilevLang Hames

讨论区: URL

项目描述: JITLink 是 LLVM 新的 JIT 链接器 API——将编译器输出(可重定位目标文件)转换为内存中可执行字节的低级 API。为此,JITLink 的通用链接器算法需要专门化以支持目标对象格式(COFF、ELF、MachO)和架构(arm、arm64、i386、x86-64)。LLVM 已经为 MachO/arm64、MachO/x86-64、ELF/x86-64、ELF/aarch64 和 COFF/x86-64 提供了成熟的 JITLink 实现,而 ELF/riscv、ELF/aarch32 和 COFF/i386 的实现仍然相对较新。
您可以处理全新的架构,如 PowerPC 或 eBPF,或完成最近添加的 JITLink 实现之一。在这两种情况下,您都可能会重用其中一种目标对象格式的现有通用代码。您还将处理重定位解析,填充 PLT 和 GOT,并为您选择的目标连接 ORC 运行时。

预期结果: 为尚未支持或不完整的格式/架构(如 PowerPC、AArch32 或 eBPF)编写 JITLink 专门化。

期望技能: 中级 C++;理解 LLVM,特别是 LLVM JIT;熟悉您选择的格式/架构,以及基本的链接器概念(例如,节、符号和重定位)。

项目规模: 大型。

难度:中等

已确认导师: Vassil VassilevLang Hames

Stefan Gränitz

讨论区: URL

项目描述: 虽然编译器的主要工作是生成快速代码(良好的运行时性能),但优化不花费太多时间(良好的编译时性能)也很重要。该项目的目标是在不损害优化质量的情况下提高编译时间。
该项目的一般方法是

  1. 选择要优化的工作负载。例如,这可以是 CTMark 中的文件,在特定的构建配置中编译(例如 -O0 -g-O3 -flto=thin)。
  2. 收集分析信息。这可能涉及编译器选项,如 -ftime-report-ftime-trace 以获得高级概述,以及 perf recordvalgrind --tool=callgrind 以获得详细的分析。
  3. 识别异常缓慢的地方。这在很大程度上取决于工作负载。
  4. 尝试优化已识别的热点,理想情况下不影响生成的代码。编译时间跟踪器 可用于快速评估对 CTMark 的影响。
作为免责声明,应该指出的是,在病态情况之外,编译往往没有一个方便的热点,其中 90% 的时间都在花费,相反,它分布在许多遍中。因此,个别改进也往往对整体编译时间只有很小的影响。期望进行 10 次每次 0.2% 的改进,而不是一次 2% 的改进。

预期结果: 在某些单个文件上实现显著改进(多个百分点),并在整体几何平均编译时间上实现小幅改进。

期望技能: 中级 C++。熟悉分析工具(特别是如果您不在 Linux 上,在这种情况下我将无法提供帮助)。

项目规模: 中型或大型。

难度: 中等

已确认导师: Nikita Popov

讨论区: URL

项目描述: Rust 编程语言 使用 LLVM 进行代码生成,并严重依赖 LLVM 的优化能力。但是,在许多情况下,LLVM 无法优化 rustc 发出的典型代码模式。这些问题使用 I-slow 和/或 A-LLVM 标签报告。
解决这些问题的常用方法是

  1. Godbolt 上检查 --emit=llvm-ir 输出。
  2. 创建一个 LLVM IR 测试用例,该测试用例在通过 opt -O3 运行时未优化。
  3. 识别最小的缺失转换,并使用 alive2 证明其正确性。
  4. 识别哪些 LLVM pass 或 passes 可以执行转换。
  5. 添加必要的测试覆盖率并实现转换。
  6. (很久以后:检查在 Rust 中下一次主要的 LLVM 版本升级后,问题是否真的得到解决。)
该项目的目标是解决一些不太困难的优化失败。这意味着在某些情况下,该过程将在步骤 3 或 4 之后停止,而不会继续进行实现,因为不清楚如何解决该问题,或者这将需要大量的工作。在这种情况下,对问题的分析仍然很有价值。

预期结果: 修复许多简单到中等的 Rust 优化失败。即使没有实施修复,也对某些失败进行初步分析。

期望技能: 用于实现的中级 C++。一些 LLVM 知识(至少能够理解 LLVM IR)用于分析。基本的 Rust 知识(足以阅读,但不能编写 Rust)。

项目规模: 中型或大型。

难度: 中等

已确认导师: Nikita Popov

讨论区: URL

项目描述: Clang 编译器是 LLVM 编译器基础设施的一部分,支持多种语言,如 C、C++、ObjC 和 ObjC++。LLVM 和 Clang 的设计使其能够作为库使用,并促成了一个完整的编译器辅助工具生态系统的创建。Clang 相对友好的代码库和 LLVM 中 JIT 基础设施的进步进一步推动了对处理 C++ 的不同方法的研究,模糊了编译时和运行时之间的界限。挑战包括增量编译以及将编译/链接时优化融入更动态的环境中。

增量编译管道通过构建不断增长的翻译单元来逐块处理代码。然后将代码降低到 LLVM IR 中,并随后由 LLVM JIT 运行。这样的管道允许创建高效的解释器。该解释器支持交互式探索,并使 C++ 语言更用户友好。交互式 C++ 解释器 Cling 使用增量编译模式,最初开发它是为了在 C++ 环境中实现交互式高能物理分析。

我们的团队 努力通过一个新的工具 clang-repl 将 Cling 的部分内容合并并可能重新设计到 Clang 主线中。该项目旨在设计和实现在用户在 clang-repl 的提示符下键入 C++ 时的健壮的自动完成功能。例如

      [clang-repl] class MyLongClassName {};
      [clang-repl] My<tab>
      // list of suggestions.
    

预期结果: 预计有几个任务

  • 研究当前在 clang 中的自动完成方法,例如 clang -code-completion-at=file:col1:col2。
  • 使用 clang 的 libInterpreter 中的部分翻译单元基础设施实现自动完成支持的版本。
  • 调查语义自动完成的要求,该要求考虑了代码的确切语法位置和语义。例如
              [clang-repl] struct S {S* operator+(S&) { return nullptr;}};
              [clang-repl] S a, b;
              [clang-repl] v = a + <tab> // shows b as the only acceptable choice here.
            
  • 在相关会议和研讨会上展示这项工作。
  • 项目规模:大型。

    难度: 中等

    已确认导师: Vassil Vassilev

    讨论区: URL

项目描述: Clang 当前在每个 clang 实例中独立处理模块,使用文件系统同步哪个实例构建给定的模块。由于为模块重用和文件系统争用而做的权衡,这在健全性和性能方面存在许多问题。

Clang 还有另一种构建模块的方式,显式构建的模块,目前需要构建系统更改才能采用。在这里,构建系统确定需要哪些模块,例如通过使用 clang-scan-deps,并确保在运行需要它们的 clang 编译任务之前构建这些模块。

为了允许采用这种构建模块的新方法,而无需进行重大的构建系统工作,我们需要一个模块构建守护程序。通过对命令行进行小的更改,clang 将连接到此守护程序并请求它需要的模块。然后,模块构建守护程序要么返回现有的有效模块,要么构建然后返回它。

存在一个现有的开源依赖扫描守护程序,它位于 llvm-project 分支中。这仅处理文件依赖项,但具有 IPC 机制。此 IPC 系统可以用作模块构建守护程序的基础,但确实需要扩展以在 Windows 上工作。

预期结果: 可以使用模块构建守护程序通过显式构建的模块来构建使用 Clang 模块和现有构建系统(如 Make 或 CMake)的普通项目。

期望技能: 中级 C++ 编程技能;熟悉编译器;熟悉 Clang 是一项优势,但不是必需的。

项目规模: 175 小时或 350 小时,具体取决于 IPC 的重用

难度: 中等

已确认导师: Michael SpencerJan Svoboda

讨论区: URL

项目描述: Swift-DocC 是 Swift OSS 项目的规范文档编译器。但是 Swift-DocC 并非 Swift 特有的,它使用 SymbolKit 的语言无关的基于 JSON 的符号图格式来了解代码中可用的符号,这样,只要有符号图生成器,任何语言都可以被 Swift-DocC 支持。

Clang 支持 C 和 Objective-C 的符号图生成,如 [RFC] clang support for API information generation in JSON 中所述。今天,对 Objective-C 类别的支持尚不完整,一方面,如果类别扩展了当前模块中的类型,则假定类别成员属于扩展类型本身。另一方面,如果扩展类型属于另一个模块,则忽略该类别。尽管如此,在 Objective-C 中扩展属于其他模块的类型作为模块公共 API 的一部分是很常见的。该项目的目标是扩展符号图格式以适应 Objective-C 类别,并实现对通过 clang 和 libclang 生成此信息的支持。

预期结果: 在 clang 的符号图生成器和 libclang 中添加必要的支持,以描述在其他模块中定义的符号类别。这可能涉及对 SymbolKit 的添加,需要与该社区讨论。

期望技能: 中级 C++ 编程技能;熟悉 clang 和 Objective-C 是一项优势,但不是必需的。

项目规模: 中等

难度: 中等

已确认导师: Daniel GrumbergZixu WangJuergen Ributzka

讨论区: URL

项目描述: Swift-DocC 是 Swift OSS 项目的规范文档编译器。但是 Swift-DocC 并非 Swift 特有的,它使用 SymbolKit 的语言无关的基于 JSON 的符号图格式来了解代码中可用的符号,这样,只要有符号图生成器,任何语言都可以被 Swift-DocC 支持。

Clang 支持 C 和 Objective-C 的符号图生成,如 [RFC] clang support for API information generation in JSON 中所述。

当前,发出的符号图格式不支持各种 C++ 构造,例如模板和异常,并且符号图生成器不完全理解 C++。该项目旨在在符号图格式中引入对各种 C++ 构造的支持,并实现对在 clang 中生成此数据的支持。

预期结果: 在 clang 的符号图生成器和 libclang 中添加必要的支持,以描述在其他模块中定义的符号类别。这将涉及对 SymbolKit 的添加,需要与该社区讨论。

期望技能: 中级 C++ 编程技能;熟悉 clang 和 Objective-C 是一项优势,但不是必需的。

项目规模: 大型

难度: 中等/困难

已确认导师: Daniel GrumbergZixu WangJuergen Ributzka

讨论区: URL

项目描述: Swift-DocC 是 Swift OSS 项目的规范文档编译器。但是 Swift-DocC 并非 Swift 特有的,它使用 SymbolKit 的语言无关的基于 JSON 的符号图格式来了解代码中可用的符号,这样,只要有符号图生成器,任何语言都可以被 Swift-DocC 支持。

Clang 支持 C 和 Objective-C 的符号图生成,如 [RFC] clang support for API information generation in JSON 中所述。

当前,用户可以使用 clang 通过 clang -extract-api 命令行界面生成符号图文件,或者使用 libclang 界面为特定符号生成符号图。该项目将需要添加第三种模式,该模式将在常规编译作业的副作用中生成符号图输出。这可以使符号图格式成为 clang Index 或 clangd 的轻量级替代方案,用于代码智能服务。

预期结果: 在常规编译(或模块构建)期间启用生成符号图文件;提供一个工具来合并符号图文件,其方式与静态链接器链接单个目标文件的方式相同;扩展 clang Index 以支持符号图文件包含的所有信息。

期望技能: 中级 C++ 编程技能;熟悉 clang 和 Objective-C 是一项优势,但不是必需的。

项目规模: 中等

难度: 中等/困难

已确认导师: Daniel GrumbergZixu WangJuergen Ributzka

讨论区: URL

项目描述: clang 发出的诊断信息最终是其与开发人员的接口。虽然诊断信息通常很好,但仍有一些粗糙的边缘需要消除。有些情况可以通过在编译器中特殊处理来改进。

正如人们从 Clang 的问题跟踪器中看到的那样,针对 clang 的诊断信息打开了 许多问题

该项目不旨在实现一个大的功能,而是侧重于对 Clang 诊断信息进行较小的、增量的改进。

可能要解决的示例问题

预期成果:至少三个已修复的较小诊断问题,或一个已实施的较大诊断改进。

已确认导师:Timm Bäder

理想技能

  • 中级 C++ 知识。
  • 最好具有 Clang 代码库的经验,因为提到的问题可能在代码库的各个部分都有其根本原因。
  • 最好是已经可以工作的本地 LLVM 构建

项目类型: 中等/200 小时

讨论区 URL

项目描述: Clang 编译器是 LLVM 编译器基础设施的一部分,支持各种语言,如 C、C++、ObjC 和 ObjC++。LLVM 和 Clang 的设计使它们可以用作库,并导致创建了整个编译器辅助工具生态系统。Clang 相对友好的代码库和 LLVM 中 JIT 基础设施的进步进一步促进了对处理 C++ 的不同方法的研究,模糊了编译时间和运行时间之间的界限。挑战包括增量编译和将编译/链接时间优化融入更动态的环境。

增量编译管道通过构建不断增长的翻译单元来逐块处理代码。然后将代码降低到 LLVM IR 中,并随后由 LLVM JIT 运行。这样的管道允许创建高效的解释器。该解释器支持交互式探索,并使 C++ 语言更用户友好。交互式 C++ 解释器 Cling 使用增量编译模式,最初开发它是为了在 C++ 环境中实现交互式高能物理分析。

我们投入精力通过一个新的工具 clang-repl 将 Cling 的部分内容合并并可能重新设计到 Clang 主线中。该项目旨在实施教程,演示该项目的功能,并研究在 xeus-clang-repl 原型中采用 clang-repl,从而允许在 Jupyter 中编写 C++。

预期结果: 预计有几个任务

  • 编写几个教程,演示 clang-repl 的当前功能。
  • 调查将 clang-repl 添加为 xeus-cling 后端的先决条件。
  • 改进 clang-repl 的 xeus 内核协议。
  • 准备一篇关于 clang-repl 以及可能的 Jupyter 的博客文章。在相关会议和研讨会上展示这项工作。
  • 已确认导师: Vassil Vassilev David Lange

    期望技能: 中级 C++;理解 Clang,特别是 Clang API

    项目类型: 中等

    讨论区 URL

项目描述: Clang 编译器是 LLVM 编译器基础设施的一部分,支持各种语言,如 C、C++、ObjC 和 ObjC++。LLVM 和 Clang 的设计使它们可以用作库,并导致创建了整个编译器辅助工具生态系统。Clang 相对友好的代码库和 LLVM 中 JIT 基础设施的进步进一步促进了对处理 C++ 的不同方法的研究,模糊了编译时间和运行时间之间的界限。挑战包括增量编译和将编译/链接时间优化融入更动态的环境。

增量编译管道通过构建不断增长的翻译单元来逐块处理代码。然后将代码降低到 LLVM IR 中,并随后由 LLVM JIT 运行。这样的管道允许创建高效的解释器。该解释器支持交互式探索,并使 Jupyter 中通过 xeus 内核协议使用的交互式 C++ 语言更用户友好。协议的较新版本允许可能的浏览器内执行,从而为 clang-repl 和 Jupyter 提供更多可能性。

我们投入精力通过一个新的工具 clang-repl 将 Cling 的部分内容合并并可能重新设计到 Clang 主线中。该项目旨在在 clang-repl 中添加 WebAssembly 支持,并在 xeus-clang-repl 中采用它以帮助基于 Jupyter 的 C++。

预期结果: 预计有几个任务

  • 调查以类似于新的 交互式 CUDA 支持 的方式生成 WebAssembly 的可行性。
  • 在 clang-repl 中启用生成 WebAssembly。
  • 在 xeus-clang-repl 中采用该功能。
  • 准备一篇关于 clang-repl 以及可能的 Jupyter 的博客文章。在相关会议和研讨会上展示这项工作。
  • 已确认导师: Vassil Vassilev Alexander Penev

    期望技能: 良好 C++;理解 Clang 和 Clang API 以及 LLVM JIT

    项目类型: 大型

    讨论区 URL

项目描述 GNU 工具链被广泛用于构建嵌入式目标。Clang/LLVM 社区在改进 Clang 工具链以支持嵌入式目标方面具有一定的势头。使用 Clang 工具链作为替代方案可以帮助我们提高代码质量,查找和修复安全漏洞,改善开发人员体验,并利用 Clang/LLVM 社区在支持嵌入式设备方面的新想法和势头。

可以对 LLD 进行改进的非详尽列表:

  • --print-memory-usage 支持

    GCC 中的“--print-memory-usage”提供了链接器文件中定义的每个内存区域中使用的内存的细分。嵌入式开发人员使用此标志来了解对内存的影响。通常,嵌入式系统定义具有不同空间约束的多个内存区域。在 Clang 工具链中支持这一点将有助于希望在其项目中使用 Clang 工具链的项目。

  • 链接图

    当前,LLD 链接器的链接图输出不如 BFD 链接器输出丰富。在链接图输出上实现功能对等将非常有助于分析 LLD 链接器创建的二进制文件。此外,以不同格式(当前 LLD 输出、BFD 和 JSON)输出链接图可以帮助构建自动化工具,以调查链接器生成的工件。

  • --print-gc-sections 改进

    启用“--print-gc-sections”标志后,LLD 会打印在链接过程中丢弃的节。此信息当前不包括符号和节组之间的映射,这对于调试很有用。在链接过程中保留此信息将需要修改内部链接器数据结构。

项目规模: 中等或大型

难度: 中等/困难

技能: C++

预期结果:

  • 实现“--print-memory-usage”标志。
  • 支持新的链接图输出格式 1. BFD 和 2. JSON。
  • 改进的“--print-gc-sections”输出以包含有关幸存符号的信息。

已确认导师: 普拉布·拉贾塞卡兰 彼得·霍塞克

讨论区: URL

描述: MLIR 的 Presburger 库 FPL (https://grosser.science/FPL) 为多面体编译和分析提供数学抽象。该库提供的主要抽象是由仿射不等式约束系统定义的整数元组集合。该库支持对此类集合的标准集合运算。结果将是由另一个约束系统定义的集合,可能具有更多约束。当按顺序执行许多集合运算时,约束系统可能会变得非常大,从而对性能产生负面影响。有几种潜在的方法可以简化约束系统;然而,这涉及执行额外的计算。因此,花费更多时间进行更积极的简化可能会使每个单独的操作变慢,但与此同时,由于约束系统大小的爆炸式增长,不充分的简化可能会使操作序列变慢。该项目的目标是找到两者之间的正确平衡。

该项目的目标

  • 了解库在运行时和输出大小方面的性能。
  • 通过找到最佳输出大小和性能权衡来优化库。

预期成果:

  • 对库的主要操作的性能和输出约束复杂度进行基准测试。
  • 实施简化启发式方法。
  • 更好地理解哪些简化启发式方法可以充分提高整体性能,从而值得额外的计算成本。

理想技能:中级 C++,基准测试经验

项目规模:大型

难度:中等

已确认导师昆瓦尔·格罗弗

讨论区URL

描述:该项目旨在为 MLIR 开发一种交互式查询语言,使开发人员能够动态查询 MLIR IR。该工具将提供 REPL(或命令行)界面,使用户能够查询 MLIR 代码的各种属性,例如“isConstant”和“resultOf”。拟议的工具旨在类似于 clang-query,它允许开发人员使用具有自动完成和其他功能的 TUI 匹配 C++ 代码中的 AST 表达式。

该项目的目标

  • 了解 MLIR IR 表示形式以及用户进行的常见探索。
  • 实施 REPL 以执行 MLIR IR 上的查询。

预期成果:

  • 可用于交互式探索 IR 的独立工具。
  • 实施该工具可使用的常用匹配器。
  • (扩展)启用将查询匹配的 IR 部分提取到独立的 IR 代码片段中。

理想技能:中级 C++,编写/调试窥孔优化的经验

项目规模:中型或大型。

难度:中等

已确认导师雅克·皮纳尔

讨论区URL

项目描述 我们正在实际部署中使用机器引导的编译器优化(“MLGO”)进行寄存器分配驱逐和内联以实现尺寸优化。ML 模型已通过强化学习算法进行训练。扩展到更多性能领域目前受到我们性能估计模型预测质量差的阻碍。改进这些模型对于强化学习训练算法的有效性至关重要,因此对于系统地将 MLGO 应用于更多优化至关重要。

项目规模: 175 或 350 小时。

难度: 中等

技能: C/C++,一些编译器经验,一些 Python。ML 经验是加分项。

预期成果:通过包含额外的运行时/分析信息(例如额外的 PMU 数据、LLC 未命中概率或分支误预测)来更好地建模执行环境。这涉及 (1) 构建一个涵盖额外运行时信息的数据收集管道,(2) 修改 ML 模型以允许处理此数据,以及 (3) 修改模型的训练和推理过程以使用此数据。

如今,这些模型几乎纯粹是静态分析;它们查看指令,但它们对执行环境和代码的运行时行为做出一刀切的假设。该项目的目标是从静态分析转向更动态的模型,以更好地表示代码的实际执行方式。

导师 Ondrej Sykora, Mircea Trofin, Aiden Grossman

讨论区 URL

项目描述: Clang 静态分析器附带了污点分析的实验性实现,这是一种面向安全的分析技术,旨在警告用户关于攻击者控制的(“污点”)数据流入敏感函数的情况,如果攻击者能够伪造正确的输入,这些函数可能会表现出意外和危险的行为。程序员可以通过正确“清理”污点数据来解决此类警告,以消除这些危险输入。可以使用这种方法捕获的一个常见问题是 SQL 注入。一个更简单的例子,可以说与 Clang 用户更相关,是由于攻击者控制的数字用作循环边界而在堆栈或堆数组上迭代或作为参数传递给低级缓冲区操作函数(例如memcpy().

作为静态符号执行引擎,静态分析器通过简单地维护在符号模拟期间从已知污点源获得的“符号”(命名的未知数值)列表来实现污点分析。然后,这些符号被视为可能采用任意具体值,而不是采用未知可能值子集的一般情况。例如,除以未经检查的未知值不一定保证除零警告,因为通常不知道该值是否可以为零。但是,除以未经检查的污点值会立即保证除零警告,因为攻击者可以自由地传递零作为输入。因此,静态分析器的污点基础设施由几个部分组成:有一种机制用于跟踪符号程序状态中的污点符号,有一种方法可以定义新的污点源,并且一些路径敏感检查被教导消耗污点信息以发出额外的警告(如除零检查器),充当污点“接收器”并定义特定于检查器的“清理”条件。

整个设施都被标记为实验性的:它基本上是一个概念验证实现。它很可能可以做得非常好,但它需要通过在真实世界的源代码上运行来进行一些质量控制,并且在我们可以声明它稳定之前,需要解决许多错误,尤其是在个别检查中。此外,最吸引人的检查——基于污点循环边界或大小参数的缓冲区溢出检测——从未实现。还有一个相关的检查,用于使用污点索引进行数组访问——这再次是实验性的;让我们看看我们是否也可以宣布这个稳定!

预期结果: 默认情况下为静态分析器的所有用户启用了许多与污点相关的检查,或者作为选择加入提供给关心安全性的用户。它们被证实对真实世界的代码具有低误报率。希望缓冲区溢出检查是其中之一。

理想技能: 中级 C++,能够理解 LLVM 代码。我们还将在一些纯 C 代码上运行我们的分析。编译器或安全方面的背景知识是受欢迎的,但不是绝对必要的。

项目规模: 中型或大型。

难度: 中等

已确认导师: Artem Dergachev, Gábor Horváth, Ziqing Luo

讨论区: URL

项目描述 这项工作延续了 GSoC 2020 和 2021 的工作。开发人员通常使用标准优化流程(如 -O2 和 -O3)来优化他们的代码。手动制作的启发式方法用于确定要选择哪些优化pass以及如何排序这些pass的执行。然而,此过程并非针对特定程序或程序类型量身定制,因为它旨在对任何输入执行“相当好”。我们希望改进现有的启发式方法,或用基于机器学习的模型替换启发式方法,以便 LLVM 编译器可以为每个程序提供更优越的pass顺序。最后一个里程碑启用了特征提取,并开始研究训练策略以选择更合适的pass流程。

项目规模: 175 或 350 小时。

难度: 中等

技能: C/C++,一些编译器经验。ML 经验是加分项。

预期成果:预训练模型,选择最经济的优化流程,且性能无损失;在 LLVM 中挂钩模型;(重新)训练工具;通过搜索或学习提出新的优化序列。

导师 Tarindu Jayatilaka, Mircea Trofin, Johannes Doerfert

讨论区 URL

项目描述
Clang 支持基于源代码的覆盖率,该覆盖率显示已执行的测试覆盖了哪些代码行 [1]。它使用 llvm-profdata [2] 和 llvm-cov [3] 工具来生成覆盖率报告。llvm-cov 当前生成单个顶级索引 HTML 文件。例如,LLVM 仓库的单个顶级目录代码覆盖率报告 [4] 发布在覆盖率机器人上。顶级索引会导致大型项目(如 Fuchsia [5])中的渲染可伸缩性问题。该项目的目标是在生成的覆盖率 html 报告中生成分层目录结构,以匹配目录结构并解决可伸缩性问题。Chromium 使用其自己的后处理工具来显示每个目录的分层结构,以显示覆盖率结果 [6]。类似地,Lcov 是 Gcov 的图形前端 [7],它提供一级目录结构以显示覆盖率结果 [8]
[1] 基于源代码的代码覆盖率
[2] llvm-profdata
[3] llvm-cov
[4] LLVM 覆盖率报告
[5] Fuchsia
[6] Chromium 的覆盖率摘要
[7] Gcov
[8] Lcov 覆盖率报告
[9] Issue #54711:支持 HTML 覆盖率报告的每个目录的索引文件

预期结果: 在生成的覆盖率 html 报告中实现分层目录结构的支持,并在 LLVM 仓库代码覆盖率报告中显示此功能的使用情况。

项目规模: 中等或大型

难度: 中等

已确认导师: 古尔芬·萨夫伦·耶尼切里 彼得·霍塞克

讨论区: URL

项目描述 开发人员经常使用编译器生成的备注和分析报告来优化他们的代码。虽然编译器通常擅长在生成的消息中包含源代码位置(即行号和列号),但如果这些生成的消息还包括相应的源代码级表达式,则会很有用。LLVM 实现中使用的方法是使用一小组内在函数来定义 LLVM 程序对象和源代码级表达式之间的映射。该项目的目标是使用这些内在函数中包含的信息来生成与 LLVM 值相对应的源表达式,或者在现有信息不足的情况下提出和实施解决方案以获得相同的结果。优化程序中的内存访问对于应用程序性能非常重要。我们特别打算使用编译器分析消息,这些消息报告与 LLVM 加载/存储指令相对应的源代码级内存访问,这些指令会抑制编译器优化。例如,我们可以使用此信息来报告抑制向量化的内存访问依赖关系。

项目规模: 中等

难度: 中等

技能: 中级 C++,熟悉 LLVM 核心或愿意学习它。

预期结果: 提供一个接口,该接口接受 LLVM 值并返回与等效源代码级表达式相对应的字符串。我们特别感兴趣的是使用此接口将加载/存储指令中使用的地址映射到等效的源代码级内存引用。

已确认导师: Satish Guggilla (satish.guggilla@intel.com) Karthik Senthil (karthik.senthil@intel.com)

讨论区: URL

项目描述
Clang 代码生成通过使用 AST 访问者发出 LLVM IR 来工作。在 ClangIR 项目中,我们也从 AST 访问者(CIRGen)发出 ClangIR (CIR),然后降低到 (a) 直接降低到 LLVM IR,或者 (b) 降低到 MLIR 内置方言。降低到 LLVM 仍然非常不成熟,并且缺少许多指令、属性和元数据支持。ClangIR 将极大地受益于在性能和构建时间方面与 Clang AST → LLVM IR 代码生成质量的某种程度的对等性。这是逐步桥接正确性和性能测试,为未来在 C/C++ 之上的更高级别优化提供基线的关键。一个好的起点是构建和运行简单的基准测试,测量生成的代码和构建时间性能。LLVM 的 llvm-test-suite 包含脚本和机制,可以轻松检查正确性并收集与性能相关的数据,其 SingleSource 集合提供了一组更简单的程序来构建。简而言之,在从事此项目时,学生将弥合 CIR → LLVM 降低的差距,并有时修复任何缺乏的 Clang AST → CIR 支持。这项工作将逐步在 SingleSource 基准测试之上完成,同时测量编译器构建时间和编译程序的性能。

技能: 中级 C++ 编程技能;熟悉编译器、LLVM IR、MLIR 或 Clang 是一个很大的优势,但学习的意愿也是一种可能性。

预期结果:从 lvm-test-suite 的 SingleSource 子目录构建和运行程序,收集并呈现针对常规(上游)clang 代码生成的结果(性能和构建时间)。

项目规模: 大型

难度: 中等

已确认导师: 布鲁诺·卡多索·洛佩斯 内森·兰扎

讨论区: URL

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何降低到 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。对越来越多的 LLVM 版本 (7-main)、AD 模式(反向、正向、正向向量、反向向量、雅可比)和库(BLAS、OpenMP、MPI、CUDA、ROCm 等)的支持导致代码库稳步增长。为了限制复杂性并帮助新的贡献者,我们希望使用 LLVM Tablegen 表达我们核心逻辑的更多部分。申请人可以自由决定如何最好地将 Enzyme 中的程序转换抽象映射到 Tablegen。

预期结果: 1. 扩展 Enzyme 中的 tablegen 规则生成系统,以涵盖 AdjointGenerator 之外的新组件
2. 将几个现有规则移动到新的自动生成系统(例如 LLVM 指令、LLVM 内在函数、MPI 调用等)

已确认导师: 曼努埃尔·德雷瓦尔德 威廉·摩西

理想技能: 良好的 C++、微积分和 LLVM 和/或 Clang 和/或 MLIR 内部知识。具有 Tablegen、Enzyme 或自动微分的经验会很好,但也可以在项目中学习。

项目规模: 大型

难度: 中等

讨论区 URL

项目描述 LLVM 中大多数日常测试都是由 Lit 执行的回归测试,结构化为源代码或 IR 以传递给某些二进制文件,而不是直接调用要测试的代码的测试代码。这有很多优点,但很难预测在用特定测试输入调用编译器时执行哪个代码路径,特别是对于涉及错误处理的边缘情况。该项目的目标是帮助开发人员为他们的补丁创建良好的测试覆盖率,并使审查人员能够验证他们是否已这样做。为了实现这一目标,我们希望引入一个工具,该工具可以将补丁作为输入,为受影响的源文件添加覆盖率检测,运行 Lit 测试,并记录哪些测试用例导致每个计数器被执行。对于每个计数器,我们可以报告执行该计数器的测试用例数量,但也许更重要的是,我们还可以报告执行该计数器的测试用例数量,这些测试用例也以某种方式被补丁更改,因为修改后的行导致相同的测试结果没有得到适当的测试,除非它旨在进行非功能性更改。这可以在三个独立的部分中实现

  1. 向 llvm-lit 添加一个选项以发出必要的测试覆盖率数据,每个测试用例划分(涉及为每个 RUN 将唯一值设置为 LLVM_PROFILE_FILE
  2. 用于处理生成的覆盖率数据和相关 git 补丁的新工具,并以用户友好的方式呈现结果
  3. 添加一种以非侵入方式(无需更改构建配置)启用构建的覆盖率检测的方法。通过正常构建项目,触摸补丁更改的文件,并使用 CCC_OVERRIDE_OPTIONS 设置为 添加覆盖率 重新构建,我们可以降低生成和处理与补丁无关的行的覆盖率的开销。
步骤 2 和 3 中的工具可以完全独立于实际的测试运行器,从而降低了除 Lit 之外的其他测试工具实现相同功能的门槛。如果时间允许,在 CI 中添加此步骤也将对审查人员有所帮助。

项目规模: 小型或中型

难度: 简单

技能: Python 用于 Lit,数据处理和 diff 处理。无需编译器经验。

预期结果: 为社区实施一个新工具。开发人员在开发过程中获得帮助以查找未覆盖的边缘情况,同时避免为了检查代码是否实际执行而散布偏执的断言或日志。审查人员可以更轻松地检查每个测试测试了补丁的哪些部分。

已确认导师: 亨里克·奥尔松

讨论区: URL

Google Summer of Code 2022 对 LLVM 项目非常成功。有关已接受和已完成项目的列表,请查看 Google Summer of Code 网站

项目描述: 编写一个基于共享内存的 JITLinkMemoryManager。
LLVM 的 JIT 使用 JITLinkMemoryManager 接口来分配工作内存(JIT 在其中修复编译器生成的可重定位对象)和目标内存(JIT 编译的代码将驻留在目标内存中)。JITLinkMemoryManager 实例还负责将修复后的代码从工作内存传输到目标内存。LLVM 具有现有的跨进程分配器,该分配器使用远程过程调用 (RPC) 来分配字节并将字节复制到目标进程,但是更具吸引力的解决方案(当 JIT 和目标进程共享相同的物理内存时)是使用共享内存页以避免进程之间的复制。

预期结果

    实施基于共享内存的 JITLinkMemoryManager
  • 编写用于共享内存分配的通用 LLVM API。
  • 编写一个 JITLinkMemoryManager,它使用这些通用 API 来分配共享工作和目标内存。
  • 对该方法进行广泛的性能研究。

已确认导师: Vassil VassilevLang Hames

理想技能: 中级 C++;特别了解 LLVM 和 LLVM JIT;了解虚拟内存管理 API。

项目类型: 大型

讨论区 URL

项目描述: LLVM 的 BuildingAJIT 教程系列教读者使用 LLVM 的 ORC API 从头开始构建自己的 JIT 类,但是教程章节尚未跟上最近的 API 改进。使现有教程章节与时俱进,编写关于惰性编译的新章节(章节代码已可用)或从头开始编写新章节。

预期结果

  • 更新第 1-3 章的章节文本——简单,但提供了一个熟悉 API 的机会。
  • 为第 4 章编写章节文本——章节代码已可用,但尚无章节文本。
  • 从头开始编写新章节——例如,如何编写进程外 JIT,或如何使用 ObjectLinkingLayer::Plugin API 直接操作 JIT 编译的指令流。

已确认导师: Vassil VassilevLang Hames

理想技能: 中级 C++;特别了解 LLVM 和 LLVM JIT;熟悉 RST (reStructured Text);技术写作技能。

项目类型: 中等

讨论区 URL

项目描述: JITLink 是 LLVM 的新 JIT 链接器 API——将编译器输出(可重定位对象文件)转换为内存中可执行字节的低级 API。为此,需要专门化 JITLink 的通用链接器算法以支持目标对象格式(COFF、ELF、MachO)和架构(arm、arm64、i386、x86-64)。LLVM 已经为 MachO/arm64 和 MachO/x86-64 提供了成熟的 JITLink 实现,以及一个相对较新的 ELF/x86-64 实现。为你感兴趣的缺失目标编写 JITLink 实现。如果你选择使用 ELF 或 MachO 格式实现对新架构的支持,那么你将能够重用这些格式的现有通用代码。如果你想使用 COFF 格式实现对新目标的支持,那么你需要编写通用 COFF 支持代码和你选择的架构的架构支持代码。

预期结果: 为尚未支持的格式/架构编写 JITLink 专门化。

已确认导师: 瓦西尔·瓦西列夫, 斯特凡·格雷尼茨, 朗·哈姆斯

期望技能: 中级 C++;理解 LLVM,特别是 LLVM JIT;熟悉您选择的格式/架构,以及基本的链接器概念(例如,节、符号和重定位)。

项目类型: 大型

讨论区 URL

项目描述: 每个开发人员,在某个时候(通常在等待他们的程序编译时),都会问“为什么这么慢?”。这个项目旨在寻找这个问题的答案。LLVM 内部以及 CLANG 扩展内部存在一个计时基础设施,用于记录编译器内部的事件。然而,它的利用是不一致和不足的。可以通过在 LLVM 和 CLANG 中添加更多检测来改进这一点,但必须小心。过多的检测,或检测错误的东西,可能会令人困惑和不知所措,因此使其与信息不足一样无用。诀窍是找到正确的检测位置并控制检测。寻找这些关键点将带你完成整个编译过程,从预处理到最终代码生成,以及所有中间阶段。当你检测代码时,你将查看数据,因为你会不断改进它,这将进一步指导你的搜索。你将开发新的方法来控制和过滤信息,以便更好地了解编译器花费时间的位置。你将寻找和开发示例测试输入,以说明可以改进编译器的地方,这将反过来帮助指导你的检测和搜索。你将考虑和开发控制检测的方法,以便更好地理解和详细检查编译阶段。通过这一切,你将了解编译器如何工作,从前端处理到 LLVM 优化流程,再到代码生成。你将看到并理解编译和优化 C/C++ 程序所需的大局,特别是 CLANG、LLVM 和 LLC 如何完成这些任务。你的导师拥有约 25 年的编译器开发经验和约 8 年的 LLVM 本身经验,可以帮助你完成你的探索。

预期结果

  • 有针对性地扩展现有计时基础设施的使用
  • 识别用于改进编译时间的适当测试输入
  • 识别编译时间热点
  • 控制计时基础设施的新的和改进的方法

已确认导师: Jamie Schmeiser, Whitney Tsang

理想技能: C++ 编程技能;CLANG/LLVM 知识是加分项但不是必需的;自我激励;好奇心;学习的渴望

项目类型:175 或 350 小时

难度评级:简单 - 中等

讨论区 URL

项目描述 这项工作延续了 GSoC 2020 和 2021 的工作。开发人员通常使用标准优化流程(如 -O2 和 -O3)来优化他们的代码。手动制作的启发式方法用于确定要选择哪些优化pass以及如何排序这些pass的执行。然而,此过程并非针对特定应用程序或应用程序类型量身定制,因为它旨在对任何输入执行“相当好”。我们希望改进现有的启发式方法,或用基于机器学习的模型替换启发式方法,以便 LLVM 编译器可以为每个应用程序提供更优越的pass顺序。最后一个里程碑启用了特征提取,并开始研究训练策略以选择更合适的pass流程。

项目规模: 175 或 350 小时。

难度: 中等

技能: C/C++,一些编译器经验。ML 经验是加分项。

预期成果:预训练模型,选择最经济的优化流程,且性能无损失;在 LLVM 中挂钩模型;(重新)训练工具。

导师 Tarindu Jayatilaka, Mircea Trofin, Johannes Doerfert

讨论区 URL

项目描述 该项目是去年 项目 的延续。在 2021 年,该项目实现了其第一个里程碑——将正确性决策与策略决策分开。这为用机器学习策略替换后者开辟了可能性。粗略的里程碑:1) 选择一组初始特征,并使用现有的 ML 引导优化 (MLGO) 基础设施生成训练日志;2) 定义可在编译时计算的奖励信号,以指导强化学习训练循环;3) 迭代训练并改进奖励/特征集

项目规模: 175 或 350 小时,理想情况下 350 小时

难度: 中等/困难

技能: C/C++,一些编译器经验。ML 经验是加分项。

预期成果:循环展开的策略(“顾问”)接口,以当前启发式方法作为默认实现;设置用于强化学习训练的特征提取;设置奖励指标;设置训练算法,并迭代策略训练

导师 Johannes Doerfert, Mircea Trofin

讨论区 URL

项目描述 LLVM 的内联器是一个自下而上、强连通组件级别的pass。这限制了评估调用站点的顺序,这会影响内联的有效性。由于 GSoC2021 工作 的成果,我们现在有了一个功能齐全的模块内联器。我们希望调用站点优先级方案、成功内联后运行函数pass的有效性/频率、与 ML 内联顾问的相互作用,仅举几个探索领域。

项目规模: 175 或 350 小时,理想情况下 350 小时,里程碑允许 175 小时的范围

难度: 中等/困难

技能: C/C++,一些编译器经验。

预期成果:替代遍历顺序的提案和评估;评估“聚类”内联决策(一次内联多个调用站点);评估内联后函数优化pass的有效性/频率

导师 Kazu Hirata, Liqiang Tao, Mircea Trofin

讨论区 URL

项目描述: C 和 C++ 程序通常由各种对象文件组成,这些对象文件由单独编译的源文件生成,然后链接在一起。当编译一个源文件时,通常无法获得可以从其他源文件中包含的逻辑派生的知识。链接时优化(也称为 LTO)是一种使用来自多个源文件的信息进行优化的方法。

在 LLVM 中,LTO 是通过使用 LLVM bitcode 对象作为“编译”步骤的输出并将这些对象馈送到链接步骤来实现的。LLVM 的 LTO 与链接器协同工作。链接器由用户调用,当链接器遇到 LLVM bitcode 文件时,链接器反过来驱动 LLVM 的 LTO,从 LTO 获取有关 bitcode 对象定义或引用的符号的信息。有关对象中定义或引用的符号的信息对于链接器执行符号解析是必要的,并且链接器通常能够从常规(非 bitcode)对象文件中提取此类信息。

LLVM 的 LTO 实现关于链接器 GC(链接器垃圾回收)的隐含后果可以得到改进,特别是对于具有对象和节的延迟包含的激进形式的链接器 GC。特别是,LTO 模块引用但未定义的符号对于链接器而言在模块级别是整体的。同时,常规(非 LTO)对象引用但未定义的符号对于 LTO 而言是整体的。总之,这意味着将 LTO 模块包含到整个过程中可能会导致,在链接器的初始符号解析中,该模块中的所有未定义符号都被视为已引用;反过来,额外的工件(例如,存档成员)可能会被添加到解析中,这进一步导致可能解析为 LTO 模块中定义的符号的引用,以及过早地得出结论,即需要这些符号的定义。这至少意味着可能会为最终将被垃圾回收的函数完成不必要的代码生成(浪费电力和时间)。

我们承认,理想的实现可能涉及链接器和 LTO 代码生成之间类似“协程”的交互,其中信息来回流动;然而,这样的努力对链接器和 LLVM 都具有侵入性。

我们相信通过

  • 让链接器通过 LTO 的 API 注册符号引用“节点”,这些节点建模符号与其链接器选择的定义(包含在对象文件节中)中反过来引用的符号之间的关系,以及
  • 在 LTO 处理中使用该信息,

LTO 处理将能够有效地识别一组更准确的 LTO 符号,这些符号在 LTO 单元外部可见。链接器仅需识别导出的符号和入口点(例如可执行文件的入口点以及参与初始化和最终化的函数)。

让 LLVM opt/codegen 理解来自“外部世界”的依赖关系影响,严格来说比另一个方向更好:非 LTO 代码中重定位引用的符号几乎在编译时就已固定(而 LTO 代码中的某些引用可能会随着优化而消失)。

预期结果

  1. 修改 LLD 使用的 C++ LTO 接口,以实现一个接口来记录符号引用依赖关系数据(包含对 sections 和 comdats 的感知)。这可能还包括一种临时添加 LTO 对象的方法,模拟链接器仅在需要时才添加对象的行为。
  2. 修改 LTO 以在访问 IR 中内部化传递之前的定义时,使用常规对象中定义的新符号引用信息,以发现(传递)符号引用,并将如此引用的符号记录为对常规对象可见。这可能还包括将临时添加的 LTO 对象“后期”合并到合并后的 LTO 模块中。
  3. 修改 LLD(对于 ELF)以修改初始解析,使用新接口来替换设置 VisibleToRegularObj,但入口点函数(包括 C++ 动态初始化和最终化)除外。

已确认导师: Sean Fertile, Hubert Tong, Wael Yehia

期望技能: 中级 C++;基本的链接器概念(例如,符号、sections 和重定位)

项目规模: 350 小时

难度: 中等/困难

Discourse URL

项目描述 LLVM 中 undef 值的存在阻碍了多项优化,即使在不使用它的程序中也是如此。因此,我们一直在尝试将 undef 的所有用途转移到 poison,以便我们最终可以从 LLVM 中删除 undef。
本项目专注于未初始化的内存:目前 LLVM 的语义是从未初始化的内存加载值会产生 undef 值。这阻止了,例如,SROA/mem2reg 优化条件加载,因为 phi(undef, %x) 不能用 x 替换,因为 %x 可能是 poison。
本项目包括为未初始化制定一致的语义(基于现有提案)、LLVM 的升级计划,并在 LLVM 和 clang 中实施更改。在 clang 中,更改应特定于位域。
有关更多信息,请参阅以下讨论和/或联系导师。
进一步阅读:LLVM 内存模型简介

项目规模: 350 小时

难度: 中等/困难

技能: 中级 C++

预期成果:

  • 内存操作的语义,消除了对 undef 值的需求
  • LLVM 和前端的升级计划
  • 在 LLVM 中实施提议的语义
  • 为旧的 LLVM IR 文件实施自动升级路径
  • 在 clang 中实施修复以使用新的 IR 功能
  • 基准测试以检查回归和/或性能改进

导师: Nuno Lopes

项目描述

目前,LLVM 内部的所有库都公开导出其所有符号。当静态链接到它们时,链接器将删除未使用的符号,这不是问题。

但是,当库构建为共享库时,导出的符号数量非常庞大,并且原本应该是内部的符号会泄漏到共享 libLLVM.so 的公共 ABI 中。

在这个项目中,我们希望将库符号的默认可见性更改为“隐藏”,向 LLVM 添加一个注释宏,并使用该宏逐步将整个库朝着这个方向发展。这将最终使在 Windows 上构建共享 libLLVM.so 成为可能。

在实践中,这意味着向各个库添加 -fvisibility=hidden,并使用 LLVM 导出注释注释导出的符号。

我们希望这项工作尽可能不干扰其他开发人员的工作流程,因此从一个小型内部库开始会很有益,例如 LLVM 目标或 IR pass 之一。

如需进一步阅读,有一个 Discourse 帖子讨论了此提案背后的想法:在 Windows 上支持 LLVM_BUILD_LLVM_DYLIB,以及链接的 Phabricator 审查,其中包含实现该功能的补丁:⚙ D109192 [WIP/DNM] 支持:引入公共 API 注释支持。这项工作尚未提交,但可以用作此提案的起点。

项目规模: 中等

难度: 简单

技能: 构建系统、CMake、LLVM

预期成果:

  • 已实施导出宏并提交到 LLVM
  • 至少一个内部目标已移植到新的导出方案

导师: Timm Bäder, Tom Stellard

项目描述: 当实例化模板时,模板参数在代入模板模式之前会被规范化。当随后访问实例化的成员时,Clang 不会保留类型糖。

    std::vector<std::string> vs;
    int n = vs.front(); // bad diagnostic: [...] aka 'std::basic_string<char>' [...]

    template<typename T> struct Id { typedef T type; };
    Id<size_t>::type // just 'unsigned long', 'size_t' sugar has been lost
    
当对类模板特化执行成员访问时,Clang 应该根据访问的特化的类型糖“重新加糖”类型。vs.front() 的类型应该是 std::string,而不是 std::basic_string<char, [...]>。

建议的设计方法:添加一个新的类型节点来表示模板参数糖,并在每次访问类模板特化的成员时隐式创建此节点的实例。当对此节点执行单步脱糖时,通过将加糖的模板参数传播到内部类型节点(特别是,用相应的糖替换 Subst*Parm 节点)来延迟创建脱糖表示。当出于诊断目的打印类型时,使用带注释的类型糖来打印最初编写的类型。

为了获得良好的结果,模板参数推导还需要能够推导出类型糖(并调和两次推导出具有不同糖的相同类型的情况)。

预期结果: 即使在访问模板特化的成员时,诊断也保留类型糖。T<unsigned long> 和 T<size_t> 仍然是相同的类型和相同的模板实例化,但 T<unsigned long>::type 单步脱糖为 'unsigned long',而 T<size_t>::type 单步脱糖为 'size_t'。

已确认导师: Vassil Vassilev, Richard Smith

期望技能: 良好的 clang API 知识、clang 的 AST、中级 C++ 知识。

项目类型: 大型

Discourse URL

项目描述: 尽管 clang AST 在幕后完成了所有工作,但静态分析器自动支持许多新的 C++ 功能,但 C++17 “结构化绑定”语法

    auto [x, y] = ...;
需要在静态分析器端进行一些额外的工作。分析器的转换函数需要了解新的 AST 节点 BindingDeclDecompositionDecl,以便在标准描述的 三种解释 中正确工作。

对结构化绑定的不完整支持是现代 C++ 代码中未初始化变量检查器中误报的常见来源,例如 #42387

Clang CFG 也可能需要更新。CFG 中的此类更改可能会提高 clang 警告的质量(在静态分析器之外)。

预期结果: 静态分析器正确地建模结构化绑定和分解声明。特别是,绑定变量不再在静态分析器的未初始化变量检查器中显示为未初始化。

已确认导师: Artem Dergachev, Rashmi Mudduluru, Gábor Horváth, Kristóf Umann

期望技能: 中级 C++ 知识。熟悉 Clang AST 和/或一些静态分析背景。

项目规模: 350 小时

难度: 中等/困难

Discourse URL

描述: Clang 诊断,它向程序员发出警告和错误,是编译器的关键功能。出色的诊断可以对编译器的用户体验产生重大影响,并提高他们的生产力。

GCC 最近的改进 [1] [2] 表明在改进诊断(以及一般的用户交互)方面还有很大的提升空间。调查并确定 clang 在此主题上的所有可能改进,并开始重新设计我们的下一代诊断,这将是一个非常有影响力的项目。

此外,我们还将对 LLVM Github Issue 页面上标记为 clang-diagnostics 的问题做出结论,如果需要修复,我们将准备补丁,否则直接关闭它们。

预期成果:诊断将得到改进

  • 改进诊断美观性
  • 涵盖缺失的诊断
  • 降低误报率
  • 重写诊断

已确认导师: Aaron Ballman, Erich Keane, Shivam Gupta

期望技能: C++ 编码经验

项目类型: 大型/350 小时

Discourse URL

项目描述: 虽然标准的启用 Polly 的 -O1/-O2/-O3 优化 pass 管道在新 Pass 管理器 (NPM) 上运行良好,但 Polly 的某些部分仍然仅适用于旧的 pass 管理器。这包括一些 pass,例如 -polly-export-jscop/-polly-export-jscop、回归测试、Polly-ACC、命令行选项(例如 -polly-show)、PassInstrumentation 机制(例如 -print-after-all 使用的机制)。LLVM(和 Clang)已将 NPM 作为默认设置,并且对旧 pass 管理器的支持已弃用,正在慢慢退化,并且功能正在被删除。也就是说,Polly 的所有功能最终都应该与 NPM 一起工作,并为完全删除旧 pass 管理器做好准备。有关两个 pass 管理器的更多详细信息,请参见 此处

预期结果: 目标是使 Polly 在仅使用 NPM 的情况下更易于使用。里程碑,不一定都要在这个 GSoC 中实现,是
1. 使 Polly 的所有功能在 NPM 中可用(或决定弃用/删除它)
2. 更好地集成到 NPM 中(例如支持 PassInstrumentation);如果 NPM 证明不足,则仅使用单体函数 pass。
3. 在回归测试中替换旧的 pass 管理器。
4. 为 LLVM 中完全删除旧的 pass 管理器做好准备。

已确认导师: Michael Kruse

期望技能: 理解新 pass 管理器使用的 C++ 模板模式 (CRTP, Mixins 等)。熟悉 LLVM 如何 链接 (静态、BUILD_SHARED_LIBS 和 SHLIB/DYLIB) 及其 插件加载机制 (静态, -load 和 -load-pass-plugin)。理想情况下,已经使用过 LLVM 的新 pass 管理器。

项目规模: 中等

难度: 中等/困难

Discourse URL

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何降低到 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。对越来越多的 LLVM 版本 (7-main)、AD 模式(反向、正向、正向向量、反向向量、雅可比)和库(BLAS、OpenMP、MPI、CUDA、ROCm、...)的支持导致代码库稳步增长。为了限制复杂性并帮助新的贡献者,我们希望使用 LLVM Tablegen 来表达我们的核心逻辑。申请人可以自由决定如何最好地将 Enzyme 中的程序转换抽象映射到 Tablegen。

预期结果: 1. Enzyme 中一个可工作的 tablegen 规则生成系统
2. 将几个现有规则移动到新的自动生成系统(例如,LLVM 指令、LLVM 内联函数、BLAS 调用、MPI 调用、...)

已确认导师: William Moses, Valentin Churavy

理想技能: 良好的 C++、微积分和 LLVM 和/或 Clang 和/或 MLIR 内部知识。具有 Tablegen、Enzyme 或自动微分的经验会很好,但也可以在项目中学习。

项目规模: 大型

难度: 中等

Discourse URL

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何降低到 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。Enzyme 已经实现了正向和反向模式自动微分。Enzyme 还实现了向量正向模式自动微分,这允许 Enzyme 在单个调用中批量处理多个对象的导数计算。这个项目的目标也是扩展此功能,以便执行向量反向模式。通过这样做,可以同时执行多次反向模式自动微分扫描,从而减少内存、时间,并在其他方面通常可以进一步优化。

预期结果: 向量化版本的反向模式自动微分

已确认导师: William Moses, Tim Gymnich

期望技能: 良好的 C++ 知识和一些 LLVM API 经验。Enzyme 或自动微分的经验会更好,但也可以在项目中学习。

项目规模: 中等

难度: 中等

Discourse URL

项目描述: Enzyme 是 LLVM 的编译器插件,它对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何降低到 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。
Enzyme 通过使用可以加载到 Clang、LLVM (opt)、链接器 (lld)、库 (HIPRtc)、直接加载 (Julia) 以及其他 (Flang、Rust 等) 中的 LLVM 插件集成到前端。
虽然在内部使用了新 pass 管理器的各种机制,但 Enzyme 目前在使用新 pass 管理器时不会自动注册其转换 pass。这为 LLVM 13 或更高版本的用户带来了问题,在这些版本中,默认情况下运行新的 pass 管理器,并且可能不理解为什么他们的代码未被微分而出现链接器错误(目前他们必须添加一个标志来指定旧的 pass 管理器)。
这个项目的目标是使 Enzyme 能够被 LLVM 中的新 pass 管理器调用,并总体上创建一致的用户体验。

预期结果: 1. Enzyme 可以被新 pass 管理器调用
2. [可选] 使 Enzyme 更易于使用的其他语法糖。

已确认导师: William Moses, Valentin Churavy

期望技能: 良好的 C++ 和 LLVM 知识。Enzyme 的经验会更好,但也可以在项目中学习。

项目规模: 小型

难度: 中等

Discourse URL

欢迎有兴趣的 2021 年 Google Summer of Code 学生!本文档是您查找 LLVM、Clang 和其他相关子项目的有趣且重要项目的起点。此项目列表不仅为 Google Summer of Code 开发,而且是真正需要开发人员参与并且对 LLVM 社区非常有益的开放项目。

我们鼓励您浏览此列表,看看哪些项目让您兴奋并且与您的技能组合非常匹配。我们也欢迎不在此列表中的提案。您必须通过我们的开发者邮件列表 (llvm-dev@lists.llvm.org 或特定的子项目邮件列表) 向 LLVM 社区提出您的想法。来自社区的反馈是您的提案被考虑并有望被接受的要求。

LLVM 项目已经参与 Google Summer of Code 多年,并取得了一些非常成功的项目。我们希望今年也不例外,并期待听到您的提案。有关如何提交提案的信息,请访问 Google Summer of Code 主要 网站。

项目描述: LLVM lit 测试套件由数千个独立的小型测试组成。由于测试数量众多,即使在高配置计算机上,运行完整的套件也可能需要很长时间。构建已经可以在同一网络上的多台计算机上分发,使用诸如 distcc 或 icecream 之类的软件,因此在单台机器上运行测试成为潜在的瓶颈。加速测试运行的一种方法可能是将测试执行也分布到多台计算机上。Lit 提供了一种测试分片机制,允许多台计算机并行运行同一测试套件的部分,但这目前假设可以访问单个公共文件系统,这在所有情况下都可能是不可能的,并且需要了解当前可以在哪些机器上运行该套件。这个项目的目标是更新现有的 lit harness(或在其周围编写一个包装器),以允许以这种方式分发测试,其想法是开发人员可以编写他们自己的 harness 和他们选择的分发系统之间的接口。这个 harness 可能需要能够识别测试依赖项,例如输入文件和可执行文件,将测试发送到分发系统(可能分批发送),并以类似于 lit 已经做的方式接收、整理和报告结果给用户。

预期结果: 上述易于使用的 harness。一些证据表明,给定一个分布式系统,如果用户正在使用该 harness,他们可以期望看到测试套件执行速度加快。

已确认导师: James Henderson

期望技能: 良好的 Python 知识。熟悉 LLVM lit 测试。对分布式系统的一些了解也会有帮助。

项目描述: 这是一个简短的描述,如果听起来有趣,请联系 Johannes (IRC 上的 jdoerfert) 和 Mircea Trofin。我们成功地为内联器决策引入了一个 ML 框架,现在我们想要扩大范围。在这个项目中,我们将研究循环转换启发式,例如展开因子。作为一个激励性的例子,我们可以看一个小行程计数的 dgemm,我们对其优化得非常糟糕。使用 nounroll pragmas,我们做得更好,但仍然远不及 gcc。该项目是开放式的,我们可以同时研究各种 pass/启发式方法。

准备资源: LLVM 代码库中的 ML 内联器框架以及 论文。LLVM 转换 pass(基于启发式方法),例如,循环展开。

预期结果: 通过学习的预测器获得可衡量的更好性能,可能是一组从 ML 模型导出的“经典”启发式方法。

已确认导师: Johannes Doerfert, Mircea Trofin

期望技能: 中级 ML 知识、C++、自我激励。

项目描述: 这是一个简短的描述,如果听起来有趣,请联系 Johannes (IRC 上的 jdoerfert)。Fuzzing 通常会揭示无数的错误。CSmith(和其他工具)展示了如何使用类似 C 的语言做到这一点,并且我们过去已经成功地使用了 LLVM-IR fuzzing。在这个项目中,我们将把 fuzzing 应用于正在开发的新 pass,例如 Attributor pass。我们想要查找和修复崩溃,以及其他错误,包括编译时性能问题。

准备资源: LLVM fuzzer 基础设施。我们可能想要 fuzz 的 LLVM pass,例如 Attributor pass。先前的 IR-Fuzzing 工作 (https://www.youtube.com/watch?v=UBbQ_s6hNgg)

预期结果: 崩溃,也可能是一种捕获非崩溃错误的方法,包括性能问题。

已确认导师: Johannes Doerfert

期望技能: 中级 C++ 知识、自我激励。

项目描述: 这是一个简短的描述,如果听起来有趣,请联系 Johannes (IRC 上的 jdoerfert)。llvm.assume是一个保留知识的强大机制。自从它诞生以来,它已经被多次改进,但仍有主要的扩展待完成,我们希望在这个项目中解决这些扩展。不完整的议题列表包括

  • 基于范围的假设,RFC 中的设计理念 3)。
  • 概述任意假设/断言代码,RFC 中的设计理念 2)。
  • 无副作用假设,请参阅 此评论
  • 更多知识保留用法
  • 减少对优化的干扰

准备资源: llvm.assumption 用法、假设缓存、“enable-knowledge-retention”选项、RFC此评论

预期结果: 新的 llvm.assume 用例,通过知识保留提高性能,基于断言的优化。

已确认导师: Johannes Doerfert

期望技能: 中级 C++ 知识、自我激励。

项目描述: LLVM 的 IR 存在根本性的、长期存在的问题。许多问题与未定义行为有关。其他问题只是由于规范不足以及不同的人的不同解释而引起的。Alive2 是一个自动检测 LLVM 优化中的错误的工具。使用 Alive2,我们在 仪表板 上跟踪单元测试暴露的错误。

预期结果: 1) 报告并修复 Alive2 检测到的错误。2) 选择一个基本的 IR 问题,并在修复它方面取得进展,包括为 语义 提出修复方案,通过在 LLVM 单元测试和中等规模程序上运行 Alive2 来测试语义修复,测试语义修复的性能并修复性能回归。

已确认导师: Nuno Lopes, Juneyoung Lee

期望技能: 中级 C++;愿意学习 LLVM IR 语义;阅读论文的经验(优先)。

项目描述: LoopNest pass 的想法是最近添加的,并且没有现有的 pass 利用它。在拥有 LoopNest pass 之前,如果您想编写一个作用于循环嵌套的 pass,您必须从函数 pass 或循环 pass 中选择一个。如果您选择将其编写为函数 pass,那么您将失去将循环动态添加回管道的能力。如果您决定将其编写为循环 pass,那么当给定循环不是最外层循环时,您将浪费编译时间来遍历到您的 pass 并立即返回。在这个项目中,我们希望为旨在用于循环嵌套的 pass 利用最近引入的 LoopNest pass,并具有与 LoopPass 相同的能力来动态地将循环添加到管道中。此外,在必要时改进当前 LoopNestPass 的实现。

预期结果(可能性): 为一些现有的转换/分析利用 LoopNest Pass。

已确认导师: Whitney Tsang, Ettore Tiotto

期望技能: 中级 C++ 知识、自我激励。

项目描述: 这是一个简短的描述,如果听起来有趣,请联系 Johannes (IRC 上的 jdoerfert)。OpenMP GPU 内核通常被降低为本机二进制文件(例如,cubin),并嵌入到主机对象中。在运行时,OpenMP“插件”将与设备驱动程序(例如,CUDA)连接,以加载和运行此类嵌入式二进制映像。在这个项目中,我们希望开发一个新的插件,该插件接受 LLVM-IR 代码,使用仅在运行时才已知的内核参数优化 IR,然后生成 GPU 二进制文件,供其他插件使用。与 远程卸载插件 类似,我们可以对用户透明地执行此操作。除了插件中的 JIT 基础设施设置之外,我们还需要将 IR 嵌入到主机对象中。

准备资源:OpenMP 目标卸载基础设施,LLVM JIT 基础设施。

预期结果: 一个具有 JIT 功能的卸载插件,当内核特化启用优化时,它可以实现卓越的性能。

已确认导师: Johannes Doerfert

期望技能: 中级 C++ 知识、JIT 编译、自我激励。

项目描述: Clacc 和 Flacc 是将 OpenACC 支持引入 Clang 和 Flang 的项目。为此,OpenACC 运行时支持正在 LLVM 的 OpenMP 运行时之上开发。但是,LLVM 的 OpenMP 运行时发出的诊断是用 OpenMP 概念表达的,因此这些诊断并不总是对 OpenACC 用户有意义。这个项目应该分两步解决这个问题

  1. 开发一种机制,选择由于 OpenACC 相关调用运行时而发出的 OpenACC 版本的诊断。这种机制应该足够通用,可以用于 OpenMP 和 OpenACC 之外的编程语言。一种可能的方法是扩展 OpenMP 运行时的某些组件中已经存在的国际化机制。
  2. 为现有的 OpenMP 诊断提供 OpenACC 翻译。此步骤需要了解 Clacc 和 Flacc 中实现的 OpenACC 和 OpenMP 之间的关系。
许多将依赖于此项目的 OpenACC 支持组件尚未向上游提交,并且正在开发中。对这些工作的高级理解对此项目很有帮助,导师可以提供。尽管如此,此项目现在可以在上游 LLVM 的 OpenMP 运行时中独立于这些工作完成。

预期结果: 上游 LLVM 的 OpenMP 运行时的一个版本,可以根据需要发出 OpenACC 诊断。

已确认导师: Valentin Clement, Joel E. Denny

期望技能: 中级 C++;OpenACC 或 OpenMP 的经验

项目描述: Polly 使用来自 整数集库 (isl) 的算法,该库是用 C 编写的库。它使用引用计数进行内存管理。在 C++ 中使用 RAII 可以更容易地获得正确的引用计数,因此我们为 isl 创建了一个 C++ 绑定:isl-noexceptions.h。从那时起,isl 也获得了两个官方的 C++ 绑定,cpp.hcpp-checked.h。我们希望用上游绑定替换 Polly 维护的 C++ 绑定。不幸的是,这不是一个就地替换。差异包括错误检查方式、方法名称、哪些函数被视为运算符/构造函数重载以及导出的函数集。这将需要更改 Polly 对 C++ 绑定的使用,并提交补丁到 isl 以导出 Polly 所需的其他功能。

预期结果: 减少 Polly 维护的 isl-noexceptions.h 绑定与 isl 支持的两个 C++ 绑定之一之间的差异。由于 isl-noexceptions.h 导出的函数和类比上游绑定更多,因此完全替换可能遥不可及,但即使减少差异也会降低 Polly 的 isl-noexceptions.h 的维护成本。

已确认导师: Michael Kruse

期望技能: 深入了解 C++,特别是 RAII 和移动语义。对 API 设计感兴趣。理想情况下,您已经编写了一些库的头文件。isl 库的经验会更好,但也可以在项目中学习。

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何降低到 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。Enzyme 通过将链式法则应用于要微分的原始函数调用的每个函数中的每个指令来实现这一点。虽然功能强大,但这对于可能具有更快导数计算代数性质的高级矩阵运算来说不一定是最佳的。Enzyme 还具有为给定函数指定自定义梯度的机制。如果自定义导数可用,Enzyme 将使用它,而不是回退到实现自己的导数。许多程序使用 BLAS 库来有效地计算矩阵和张量运算。这个项目将通过为其运算指定自定义导数规则,实现 BLAS 和类似库(例如 Eigen)的高性能自动微分。

预期结果: 通过为矩阵和张量运算编写自定义导数规则,实现 BLAS 和 Eigen 代码的有效微分。

已确认导师: William Moses, Johannes Doerfert

期望技能: 良好的 C++、微积分和线性代数知识。BLAS、Eigen 或 Enzyme 的经验会更好,但也可以在项目中学习。

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何可以降级为 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。虽然这适用于任何发出 LLVM IR 的前端,但可能希望 Enzyme 和前端之间有更紧密的集成,以便传递更多信息并创建更好的用户体验。Swift 通过在前端指定自定义导数规则来提供自动微分。Enzyme 可以直接与 Swift 集成,对最终的 LLVM 进行微分,但这会失去所有关于自定义导数的附加信息。此外,天真地调用 Enzyme 将不具备类型检查、精细的 AD 特定调试信息或 Swift 为 AD 用户提供的各种其他优秀工具。本项目旨在整合 Enzyme 和 Swift 前端,为希望使用 Enzyme 实现高性能自动微分的 Swift 程序员提供良好的用户体验,并允许 Enzyme 利用 Swift 中已有的特定于导数的元数据。

预期成果: 在 Swift 中创建用于调用 Enzyme 的自定义类型检查语言结构。用于传递 Swift 的微分特定元数据以供 Enzyme 使用的机制。

已确认导师: William Moses, Vassil Vassilev

期望技能: 良好的 C++ 和 Swift 知识。有 Enzyme 或自动微分经验会更好,但也可以在项目中学习。

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何可以降级为 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。在许多领域中,需要对定点值(例如整数)而不是浮点值进行计算。这避免了某些截断错误,这些错误对于给定的应用可能至关重要。此外,特定的硬件可能在定点值而非浮点值上更有效。本项目旨在扩展 Enzyme,使其不仅支持浮点基值的微分,还支持定点基值的微分。

预期成果: 实现 LLVM 定点内在函数的伴随,必要的类型分析规则,并集成到前端以进行端到端测试。

已确认导师: William Moses

期望技能: 良好的 C++、微积分和 LLVM 内部原理知识。有 Enzyme 或自动微分经验会更好,但也可以在项目中学习。

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 对任何可以降级为 LLVM 的语言的现有代码执行各种算法,例如 ML 中的反向传播或科学模拟。虽然这适用于任何发出 LLVM IR 的前端,但可能希望 Enzyme 和前端之间有更紧密的集成,以便传递更多信息并创建更好的用户体验。本项目旨在整合 Enzyme 和 Rust 前端,为希望使用 Enzyme 实现高性能自动微分的 Rust 程序员提供良好的用户体验。这也可能涉及将 LLVM 插件支持/自定义代码生成集成到 rustc 中。

预期成果: 在 Rust 中创建用于调用 Enzyme 的自定义类型检查语言结构。用于将 Rust 的类型信息(表示为调试 LLVM 调试信息)直接解析到类型分析中的机制。

已确认导师: William Moses

期望技能: 良好的 C++ 和 Rust 知识。有 Enzyme 或自动微分经验会更好,但也可以在项目中学习。

项目描述

  • 绘制在转移函数中花费的时间图表——包括(但不限于!)检查器回调。
  • 添加 llvm 统计信息和计时器,以便在无需外部分析器的情况下快速获得精确而简洁的转储。关于状态分裂的统计信息可能特别有趣!
  • 测量分析特定堆栈帧所花费的时间。例如,我们在内联中花费了多少时间std::string方法?如果我们为这些方法添加自定义模型,则可以节省这段时间。

已确认导师: Artem Dergachev

项目描述: CSA 有一个小型内部约束求解器,它非常简单,但速度超快。目标是为一些符号运算符支持基于范围的逻辑,同时保持线性。此外,可以专门为测试约束求解器设计一个单元测试框架(目前它的测试方式相当笨拙)。这个项目有几个有趣的特性。它可以被分割成小块,并且每个小块都有一个重要的解决方案。它可能会把你带入求解器的世界(最好用一些重量级的求解器如 z3 来检查你的想法)。并且由于现有的求解器很简单,因此有无数可能的扩展可以尝试。

已确认导师: Valeriy Savchenko

项目描述

  • 设计并集成一个新的诊断抽象(类似于 clang::Diagnostic),以结构化的方式报告错误、警告和注释。
  • 允许我们区分错误(意外错误)和调试器根本不知道的事情(预期错误)。智能地只打印一次全局错误。具有冗余的能力并拥有额外的元数据(源位置、DWARF 单元、对象文件等,具体取决于错误的类型及其来源)。
  • 应该与现有类兼容并紧密集成,例如 Status 和 CommandReturnObject。

已确认导师: Jonas Devlieghere 和 Raphael Isemann

LLVM 参与 2020 年 Google 编程之夏非常成功,并促成了许多有趣的 LLVM 贡献项目。有关已接受和已完成项目的列表,请查看 Google 编程之夏 网站。

项目描述: 这是一个简短的描述,如果听起来有趣,请联系 Johannes (IRC 上的 jdoerfert)。在 GSoC'19 期间,我们构建了 Attributor 框架,以提高 LLVM 的过程间能力。这本身就很有用,尤其是在内联不可能或不可取的情况下。在这个 GSoC 项目中,我们将研究 Attributor 中尚未提供的功能,以及将 Attributor 与现有的过程内和过程间优化连接起来的潜力。在这个项目中,有很多自由来确定实际任务,但我们也会提供一个小型和中型任务池,可以从中选择。

准备资源: 来自 2019 年 LLVM 开发者会议的 Attributor YouTube 视频以及同次会议的 IPO 小组录音。Attributor 框架以及 LLVM 中其他现有的过程间分析和优化。

预期成果: 可衡量的更好的 IPO,在内联不是一种选择或不可取的情况下尤其明显。

已确认导师: Johannes Doerfert

期望技能: 中级 C++ 知识,自我激励。

项目描述: 这是一个简短的描述,如果听起来有趣,请联系 Johannes (IRC 上的 jdoerfert)。通过 OpenMPOpt pass (正在审查中) ,我们开始教 LLVM 优化管道关于 OpenMP 并行性,该并行性被编码为 OpenMP 运行时调用。在这个 GSoC 项目中,我们将研究 OpenMPOpt pass 中尚未提供的功能,以及将现有的过程内和过程间优化连接起来的潜力,例如 Attributor。在这个项目中,有很多自由来确定实际任务,但我们也会提供一个小型和中型任务池,可以从中选择。

准备资源: 来自 2018 年 LLVM 开发者会议的 YouTube 视频 “优化间接寻址,无悔地使用抽象”。J. Doerfert 和 H. Finkel 的论文 “OpenMP 编译器优化” 和 “并行程序编译器优化”(这些幻灯片可能更有用)。

预期成果: 可衡量的更好的并行程序性能或程序分析结果,重点是 OpenMP。

已确认导师: Johannes Doerfert

期望技能: 中级 C++ 知识,自我激励。

项目描述: 生成调试信息是编译器通常执行的基本任务之一。很明显,生成的可执行代码不应依赖于调试信息的存在。

不幸的是,在 LLVM 中已知存在代码生成因是否启用调试信息 (`-g`) 而异的情况。这类错误可能导致糟糕的调试体验,从意外的执行行为到程序在调试模式下运行良好但在没有调试信息的情况下崩溃。

该问题可能并非单一原因造成,而是在不同架构上的不同 pass 期间触发的。其中一个原因是编译器后端在帧降低和其他后续 pass 期间插入了调用帧信息 (CFI)。CFI 指令的存在似乎会改变指令调度,从而导致生成的代码不同。

准备资源

  • PR37728 是一个元错误,它收集了几个与不同代码生成相关的issue。
  • PR37240 是一个讨论上述 CFI 问题的错误。
  • 以下 RFC 讨论了一些可能的缓解策略,并提供了有关 CFI 问题的一些背景信息。

预期结果

  • 基于现有脚本编写一些工具,以自动生成不同代码生成的示例。这旨在作为一项入门任务,以了解现有的 LLVM 工具,学习阅读 LLVM 的内部输出等。
  • 选择一个或多个(取决于难度)导致代码生成差异的错误,并尝试提供补丁来修复它们。我们对提到的 CFI 问题特别感兴趣,但处理其他一些相关错误也完全可以。

已确认导师: Paul Robinson 和 David Tellenbach

期望技能: 中级 C++ 知识,对通用计算机体系结构的一些熟悉,对 x86 或 Arm/AArch64 指令集的一些熟悉。

项目描述: MergeSimilarFunctions pass 不仅能够合并相同的函数,还能够合并指令略有不同的函数,以减小代码大小。它通过在合并的函数中插入控制流和一个额外的参数来解决这些差异。这项工作在 LLVM Dev Meeting in 2013 上进行了展示,更详细的描述发表在 LCTES 2014 的一篇论文中。该代码当时已发布给社区。同时,该 pass 在过去的几年中一直在 QuIC 生产中使用,并在内部得到了积极维护。为了扩大 MergeSimilarFunctions 的影响,它已被移植到 ThinLTO,并且补丁已向上游提交(请参阅下面提到的 5 个补丁堆栈)。但是,社区建议我们用 MergeSimilarFunctions 的思想改进现有的 MergeFunctions pass,而不是替换 LLVM 上游中现有的 MergeFunctions pass。然后再利用 ThinLTO。ThinLTO 中使用的 MergeSimilarFunction 在各种工作负载中都实现了令人印象深刻的代码大小缩减,并且这项工作在 LLVM-dev 2018 上进行了展示。LLVM 项目将极大地受益于这种代码大小优化,因为大多数嵌入式系统(想想智能手机)应用程序都受到代码大小的限制。

准备资源

预期结果

  • Improve MergeFunctions to have feature parity with MergeSimilarFunctions.
  • Enable MergeFunctions to ThinLTO.

已确认导师:Aditya Kumar (hiraditya on IRC and phabricator), JF Bastien (jfb on phabricator)

期望技能: 编译器设计课程,SSA 表示,中级 C++ 知识,熟悉 LLVM Core。

项目描述: LLVM 提供了一个名为 yaml2obj 的工具,该工具将 YAML 文档转换为对象文件,用于各种不同的文件格式,例如 ELF、COFF 和 Mach-O,以及执行相反操作的 obj2yaml。该工具通常用于测试 LLVM 的各个部分,因为 YAML 通常比原始汇编更容易用于描述对象文件,并且比预构建的二进制文件更易于维护。DWARF 是 LLVM 常用的调试文件格式。LLVM 的 DWARF 发射的许多测试都是用汇编编写的,但用 YAML 编写会更好。但是,yaml2obj 不正确地支持 DWARF 部分的发射。本项目旨在向 yaml2obj 添加功能,以简化 DWARF 测试的测试输入的编写,特别是对于 ELF 对象。

准备资源: 阅读 DWARF 文件格式将很有用,特别是 http://dwarfstd.org/Download.php 提供的标准。此外,熟悉 ELF 文件格式的基础知识(此处描述为 https://www.sco.com/developers/gabi/latest/contents.html)可能会有所帮助。

预期成果: 能够使用 yaml2obj 为对象文件生成 DWARF 部分。特别重要的是确保输入 YAML 比等效的汇编更容易理解。

已确认导师: James Henderson

期望技能: 中级 C++ 知识。

项目描述: LLVM 中的热冷分离是一种 IR 级别的函数拆分转换。热冷分离的目标是提高代码的内存局部性,并有助于减少启动工作集。拆分 pass 通过识别冷块并将它们移动到单独的函数中来实现这一点。由于它是在 IR 级别实现的,因此所有后端目标都从中受益。这是一种相对较新的优化,最近在 LLVM Dev Meeting in 2019 上进行了展示,幻灯片 在此处 因为大部分好处来自概述小块,例如 __assert_rtn。本项目的目标是通过静态分析(例如,异常处理代码、优化人格函数)来识别潜在的块。使用成本模型来确保概述减少调用者的代码大小,并在适当的时候使用尾调用来节省指令。

准备资源

预期结果

  • 改进热冷分离,以通过静态分析或配置文件信息从程序中检测和概述冷块。使用适当的成本模型来衡量 HCS 的好处。如果编译时开销变为二次方,则提出一个成本模型来检测何时触发二次方行为,并根据编译器标志退出。

已确认导师:Aditya Kumar (hiraditya on IRC and phabricator)

期望技能: 编译器设计课程,SSA 表示,中级 C++ 知识,熟悉 LLVM Core。

项目描述: 为给定应用程序选择优化 pass 非常重要,但由于编译器转换空间(包括 pass 排序)的巨大规模,这是一个非平凡的问题。虽然现有的启发式方法可以为某些应用程序提供高性能代码,但它们不能轻易地使广泛的应用程序代码受益。本项目的目标是学习 LLVM 转换 pass 和代码结构之间的相互作用,然后改进现有的启发式方法(或用基于机器学习的模型替换启发式方法),以便 LLVM 编译器可以为每个应用程序提供定制的 pass 的最佳顺序。

Expected results (possibilities)

  • Insights about (implicit) dependences between existing passes.
  • New pass pipelines (think -O3a, -O3b, ...) selectable by the user that tend to perform substantially better on certain kinds of programs.
  • An improved LLVM pass heuristic or new machine learning-based models that can select the best order for LLVM transformation passes based on code structures.

准备资源

已确认导师:EJ Park, Giorgis Georgakoudis, Johannes Doerfert

期望技能: C++、Python,有 LLVM 和基于学习的预测经验者优先。

项目描述: 当前用于编译器优化的机器学习模型基于隔离的每个函数分析为函数选择最佳优化策略。在这种方法中,构建的模型不知道与其周围其他函数(调用者或被调用者)的任何关系,这可能有助于为每个函数确定最佳优化策略。在这个项目中,我们希望探索 SCC(强连通分量)调用图,以在构建基于机器学习的模型中添加过程间特征,从而找到每个函数的最佳优化策略。此外,我们想探索将强相关函数分组在一起并作为一个组进行优化,而不是每个函数进行优化的情况,这是否有帮助。

Expected results (possibilities)

  • Improved heuristics for existing (inter-procedural) passes, e.g. to weight inlining versus function cloning based on code features.
  • Machine learning models to select the best optimizations using code features and inter-procedural analysis. This model can be used for functions in isolation or groups of functions, e.g., CGSCCs.

准备资源

已确认导师:EJ Park, Giorgis Georgakoudis, Johannes Doerfert

期望技能: C++、Python,有 LLVM 和基于学习的预测经验者优先。

项目描述: 目前没有简单的方法在循环 pass 中使用 PostDominatorTreeAnalysis 的结果,因为 PostDominatorTreeAnalysis 是一个函数分析,并且它不包含在 LoopStandardAnalysisResults 中。如果在 LoopStandardAnalysisResults 中添加 PostDominatorTreeAnalysis,那么所有循环 pass 都需要保留它,这意味着所有循环 pass 都需要确保结果是最新的。在这个项目中,我们希望修改一些常用的实用程序,以生成更新列表,这些更新列表可以被不同的 updater 消费,例如 DomTreeUpdater 用于更新 DominatorTree 和 PostDominatorTree,以及 MSSAU 用于更新 MemorySSA 等,而不是仅更新 DominatorTree。此外,我们希望更改现有的循环 pass 以保留 PostDominatorTree。最后,在 LoopStandardAnalysisResults 中添加 PostDominatorTree。

Expected results (possibilities): PostDominatorTree added in LoopStandardAnalysisResults, and can be used by loop passes. More common utilities change to generate list of updates to be easily obtained by different updaters.

已确认导师: Whitney Tsang, Ettore Tiotto, Bardia Mahjour

期望技能: 中级 C++ 知识、自我激励。

准备资源:

项目描述: 目前,如果您想编写一个在循环嵌套上工作的 pass,您必须从函数 pass 或循环 pass 中选择一个。如果您选择将其编写为函数 pass,那么您将失去将循环动态添加回管道的能力。如果您决定将其编写为循环 pass,那么当给定的循环不是最外层循环时,您将浪费编译时间来遍历您的 pass 并立即返回。在这个项目中,我们希望创建一个 LoopNestPass,其中用于循环嵌套的转换可以从中继承,并具有与 LoopPass 相同的能力来动态地将循环添加到管道。此外,创建所有需要的适配器,以便在 pass 构建器的不同点添加循环嵌套 pass。

Expected results (possibilities): Transformations/Analyses can be written as LoopNestPass, without compromising compile time or usability.

已确认导师: Whitney Tsang, Ettore Tiotto

期望技能: 中级 C++ 知识、自我激励。

Preparation resources:

项目描述: TableGen 非常灵活,允许最终用户定义和设置记录(指令)的通用属性。每个目标都有几十个或数百个此类指令属性。随着目标代码的演变,td 文件变得越来越复杂,越来越难以确定某些属性的设置是否必要,甚至是否正确。例如:是否在所有指令上正确设置了 hasSideEffects 属性?人们可以手动搜索 TableGen 生成的文件;或者编写一些脚本来运行 TableGen 并匹配某些特定属性的输出,但是从构建过程管理的角度来看,一个可以系统地转储和检查指令属性的独立实用程序(例如:也允许目标定义一些验证规则)可能会更好。这可以帮助发现一些隐藏的错误,从而提高整体代码生成代码质量。此外,该实用程序可用于编写指令属性的回归测试,这将提高 LLVM 回归测试的质量和精度。

预期成果(可能性): 一个可以系统地转储和检查指令属性的独立 llvm 工具或实用程序

已确认导师: Hal Finkel, Jinsong Ji , Qingshan Zhang

期望技能: 中级 C++ 知识、自我激励。

项目描述: 确定移动代码是否安全在 LLVM 的多个转换中实现(例如 LICM 中的 canSinkOrHoistInst,或 Loop 中的 makeLoopInvariant)。这些实现中的每一个对于给定的查询都可能返回不同的结果,从而导致代码移动安全检查不一致且重复。另一方面,在每个转换中执行实际代码移动的机制也不同。代码重复会导致维护问题,并增加编写新转换所需的时间。在这个项目中,我们希望首先识别循环转换(可以是函数或循环 pass)中所有现有的方法,以检查代码是否可以安全移动以及移动代码,并创建一个标准化的方法来执行此操作。

Expected results (possibilities): A standardize/superset of all the existing ways in loop transformations of checking if code is safe to be moved and to move

已确认导师: Whitney Tsang, Ettore Tiotto, Bardia Mahjour

期望技能: 中级 C++ 知识、自我激励。

Preparation resources:

开放项目列表中所有项目都对 GSOC 开放。也欢迎在 Discourse 上提出您自己的想法。

项目描述: Clang 静态分析器已经知道如何防止由任意代码中的空指针解引用引起的崩溃,但是当代码太复杂时,它通常会“放弃”。特别是,C++ 标准类的实现细节,即使是像智能指针或 optional 这样简单的类,对于分析器来说也可能太复杂而无法完全理解。此外,确切的行为取决于使用了哪个标准库的实现(例如,GNU libstdc++ 或 LLVM 自己的 libc++)。

我们可以通过显式地教导分析器关于 C++ 标准类的行为,从而跳过分析器尝试自行理解所有实现细节的整个过程,使分析器能够在现代 C++ 代码中找到更多错误。例如,我们可以教导它默认构造的智能指针为空,并且任何尝试解引用的行为都会导致崩溃。因此,该项目将包括手动为标准类的各种方法提供实现。

预期成果: 我们希望静态分析器在代码中发生空智能指针解引用时发出警告。例如

    #include <memory>

    int foo(bool flag) {
      std::unique_ptr<int> x;  // note: Default constructor produces a null unique pointer;

      if (flag)                // note: Assuming 'flag' is false;
        return 0;              // note: Taking false branch

      return *x;               // warning: Dereferenced smart pointer 'x' is null.
    }
    
We should be able to cover at least one class fully, for example,std::unique_ptr, and then see if we can generalize our results to other classes, such asstd::shared_ptror the C++17std::optional.

已确认导师: Artem Dergachev, Gábor Horváth

期望技能: 中级 C++ 知识。

项目描述: LLDB 的命令行提供了几个方便的功能,这些功能受到 UNIX shell 的功能的启发,例如选项卡补全或命令历史记录。尚未实现的一项功能是“自动建议”。这些是用户可能想要键入的可能命令的建议,但与选项卡补全不同,它们在用户键入命令时直接显示在光标后面。fish shell 中实现的自动建议很好地演示了这可能是什么样子。

本项目是关于在 LLDB 基于 editline 的命令 shell 中实现自动建议。

已确认导师: Jonas Devlieghere 和 Raphael Isemann

期望技能: 中级 C++ 知识。

项目描述: LLDB 的命令行提供了几个方便的功能,这些功能受到 UNIX shell 的功能的启发,例如命令的选项卡补全。这些选项卡补全由一个补全引擎实现,该引擎不仅供 LLDB 的命令行界面使用,而且还供 LLDB 的图形界面(如 IDE)使用。虽然 LLDB 中的选项卡补全非常有用,但它们目前尚未为所有命令及其各自的参数实现。本项目是关于为 LLDB 中的命令实现剩余的补全,这将大大改善 LLDB 的用户体验。改进现有的补全也是项目的一部分。请注意,补全不是字符串的静态列表,而是通常需要检查和理解 LLDB 的内部状态。由于 LLDB 命令及其选项卡补全涵盖了 LLDB 的所有方面,因此本项目提供了一个很好的方式来了解 LLDB 中的所有功能。

已确认导师:Raphael Isemann

期望技能: 中级 C++ 知识。

项目描述: 正如 LLVM 是一个用于构建编译器的库一样,LLDB 是一个用于构建调试器的库。LLDB 提供了一个稳定的公共 SB API。由于历史原因,LLDB 命令行界面目前是在 LLDB 私有 API 之上实现的,并且它复制了许多已在公共 API 中实现的功能。在公共 API 之上重写 LLDB 的命令行界面将简化实现,消除重复代码,最重要的是减少测试面。

这项工作还将提供一个机会来清理 SB API 中随着时间推移积累了太多重载的命令,并将它们转换为利用选项类,以便收集所有变体并使 API 具有面向未来的能力。

已确认导师:Adrian Prantl 和 Jim Ingham

期望技能: 中级 C++ 知识。

项目描述: 测试套件中的一个紧张之处在于,启动一个进程并使其达到某个点不是一个廉价的操作,因此您希望在到达那里时进行一堆测试。但是当前的测试套件在第一次失败时就会中止,因此您不想进行太多测试,因为一个测试的失败会导致所有其他测试都失败。另一方面,在某些单独的测试断言中,断言的失败应该导致整个测试失败。例如,如果您在要检查一些变量值的位置未能停止在断点处,那么整个测试都应该失败。但是,如果您的测试然后想要检查五个独立局部变量的值,它应该能够完成所有五个,然后报告五个变量断言中有多少个失败。我们可以通过为一批测试添加开始和结束标记来做到这一点,执行批处理中的所有测试而不会使整个测试失败,然后在适当的情况下报告错误并使整个测试失败。在 Python 中使用作用域对象进行测试部分也可能有一种很好的方法。

已确认导师: Jim Ingham

期望技能: 中级 Python 知识。

2019 年 Google 编程之夏为 LLVM 项目做出了很大贡献。有关已接受和已完成项目的列表,请查看 Google 编程之夏 网站。

项目描述: 添加调试信息(使用 `clang -g` 编译)根本不应更改生成的代码。不幸的是,我们有错误。这些错误通常不太难修复,并且是发现代码库新部分的好方法!我们建议以两种方式构建对象文件并反汇编文本部分,这将比比较 .s 文件提供更清晰的差异。

预期成果: 减少的测试用例,带有分析的错误报告(例如,哪个 pass 负责),可能的补丁。

已确认导师: Paul Robinson

期望技能: 中级 C++ 知识,对 x86 或 ARM 指令集的一些熟悉。

项目描述: Clang 包含一个 ASTImporter,它允许将声明和语句从一个 Clang AST 移动到另一个 Clang AST。例如,这用于跨翻译单元的静态分析和 LLDB 的表达式求值器中。

当将简单的 C 代码从一个 AST 移动到另一个 AST 时,当前的 ASTImporter 可以按预期工作。但是,更复杂的声明(例如 C++ 的 OOP 功能和模板)尚未完全实现,可能会导致崩溃或无效的 AST 节点。与这些崩溃相关的错误报告通常针对 LLDB 的表达式求值器提交,并且很少使用最小的复现器提交。这使得改进 ASTImporter 成为一项耗时且乏味的任务。

本项目是关于编写一个模糊器,以主动发现这些 ASTImporter 错误并提供最小的复现器,从而更容易理解和修复底层错误。

这种模糊器和驱动程序的可能实现可能如下所示

  • 生成一些可以导入的源代码(完全随机或基于用户给定的代码语料库中的现有源代码)。
  • 从此 AST 中随机导入一些声明。导入它们的 AST 可能已经填充了声明。
  • 在导入的 AST 上运行 Clang 的代码生成器。
  • 如果在导入或代码生成步骤中遇到断言,我们可能发现了 ASTImporter 的错误。
  • 模糊测试驱动程序现在应该缩小源代码的大小,直到它尽可能小,并且仍然能重现崩溃(例如,通过使用自动生成的测试脚本运行 Creduce)。
  • 现在应该以某种格式存储重现器,以便它可以直接复制到 Clang 的 ASTImporter 回归测试套件中(参见 clang/test/Import/ 目录)。当作为测试套件的一部分运行时,重现器必须仍然能重现发现的错误。
这只是一种可能的方法,欢迎学生提交他们自己关于模糊测试器应如何运行的想法。鼓励采用可以自动验证导入的 AST 的更多方面(例如,AST 节点的源位置、RecordDecls 的大小)的方法。模糊测试器和驱动程序应该用 C++ 和/或 Python 实现。

已确认导师: Raphael Isemann, Shafik Yaghmour

期望技能: 中级 C++ 知识。

项目描述: Clang 具有新实现的自动补全功能,详情请见 LLVM 博客。我们希望通过为自动补全添加更多标志、支持更多 shell(目前仅支持 bash)并将此功能导出到其他项目(如 llvm-opt)来改进它。被录取的学生将从事 Clang Driver、LLVM Options 和 shell 脚本方面的工作。

预期结果: 自动补全在 bash 和 zsh 上工作,支持 llvm-opt 选项。

已确认导师: Yuka Takahashi 和 Vassil Vassilev

期望技能: C++ 和 shell 脚本的中级知识

Google Summer of Code 2018 为 LLVM 项目做出了很大贡献。有关已接受和已完成项目的列表,请查看 Google Summer of Code 网站。

Google Summer of Code 2017 为 LLVM 项目做出了很大贡献。有关已接受和已完成项目的列表,请查看 Google Summer of Code 网站。

本文档旨在成为 LLVM 的“大型 TODO 列表”。本文档中的每个项目都是 LLVM 需要的,并且也是熟悉该系统的好方法。其中一些项目很小且独立,可能在几天内就可以实现,另一些项目则更大。其中一些项目可能会发展成为有趣的独立研究项目。无论如何,我们欢迎所有贡献。

如果您正在考虑处理这些项目之一,请发送邮件至 LLVM 开发者 邮件列表,以便我们知道该项目正在进行中。此外,这也是获取有关特定项目的更多信息或建议将其他项目添加到此页面的好方法。

此页面中的项目是开放式的。更具体的项目作为未分配的增强功能记录在 LLVM 错误跟踪器 中。如果您希望帮助改进 LLVM,请参阅 当前未解决问题列表

除了在主 LLVM 项目上进行黑客攻击外,LLVM 还有几个子项目,包括 Clang 和其他项目。如果您有兴趣参与这些项目,请参阅其“开放项目”页面

对当前基础设施的改进总是非常受欢迎,并且往往很容易实现。以下是一些可以改进的关键领域...

目前,Clang 和 LLVM 都有单独的目标描述基础设施,其中一些功能重复,另一些功能“共享”(从 Clang 必须创建完整的 LLVM 目标描述来查询特定信息的意义上讲)。

这种分离是并行增长的,因为最初它们非常不同,并且服务于不同的目的。但是随着编译器的发展,越来越多功能必须在两者之间共享,以便编译器能够正常运行。一个例子是当目标在没有标志的特定配置上具有默认功能时。如果后端具有与前端不同的“默认”行为,并且后者无法强制执行行为,则它将无法工作。

另一种方法是为所有小的怪癖创建标志,但首先,Clang 不是唯一使用 LLVM 中间/后端的前端或工具,其次,这就是“默认行为”的用途,因此我们将错过重点。

围绕修复 Clang 驱动程序 WRT 识别架构、功能等等(表格生成、用户特定配置文件等)的几个想法已经出现,但它们都没有触及关键问题:与后端共享该信息。

最近,将目标描述基础设施从 Clang 和 LLVM 中分离出来,放入两者都使用的自己的库中的想法一直在流传。这将确保共享所有默认值、标志和行为,同时还将大大降低复杂性(以及维护成本)。这也将允许所有工具(lli、llc、lld、lldb 等)在整个范围内具有相同的行为。

主要的挑战是

  • 确保过渡不会破坏任何目标上的微妙平衡,因为某些默认值是隐式的,有时是未知的。
  • 能够一次迁移一个目标,一次迁移一个工具,并且仍然保持旧的基础设施完好无损。
  • 使前端和后端功能都易于检测目标的特性,并将两者合并为一组连贯的属性。
  • 为尚未迁移的工具(尤其是树外的工具)提供通往新系统的桥梁,这些工具将需要一些时间(至少一个版本)才能迁移。

LLVM 错误跟踪器 偶尔会提交 “代码清理”错误。选择其中一个并修复它是深入了解 LLVM 代码并了解其某些组件如何工作的好方法。其中一些包括一些主要的 IR 重新设计工作,这些工作具有很大的影响,因为它可以简化优化器中的许多事情。

一些特定的问题,如果能解决就太好了

此外,LLVM 中还有一些性能改进需要修复。这些都标有slow-compile关键字。使用 此 LLVM 错误跟踪器查询 查找它们。

llvm-test 测试套件是我们用于夜间测试生成的代码性能、编译时间、正确性等的程序的大集合。拥有大型测试套件为我们提供了广泛的程序覆盖率,使我们能够发现和改进编译器中的任何问题区域。

一项非常有用的任务,不需要深入了解编译器,就是扩展我们的测试套件以包括 新程序和基准测试。特别是,我们对具有少量库依赖项、产生一些可用于正确性测试的输出以及可以以源代码形式重新分发的 CPU 密集型程序感兴趣。许多不同的程序都适用,例如,请参阅 此列表 以获取一些潜在的候选程序。

我们一直在寻找用于 LLVM 的新测试用例和基准测试。特别是,尝试使用 LLVM 编译您最喜欢的 C 源代码很有用。如果它无法编译,请尝试找出原因或将其报告给 llvm-bugs 列表。如果您使程序能够编译,则将构建系统转换为与 LLVM Programs 测试套件兼容将非常有用,这样我们就可以将其检入 SVN,并且自动化测试器可以使用它来跟踪编译器的进度。

在测试代码时,尝试使用各种优化以及所有后端:CBE、llc 和 lli 运行它。

使用我们的 测试结果 或您自己的基准测试,在这些基准测试中,LLVM 代码生成器未生成最佳代码,或者另一个编译器生成了更好的代码。尝试最小化演示该问题的测试用例。然后,提交包含您的测试用例和 LLVM 生成的代码与它应该生成的代码的错误,甚至更好的是,看看您是否可以改进代码生成器并提交补丁。基本思想是,如果我们知道性能问题,通常很容易修复它们,但我们通常没有资源去找出为什么性能很差。

LNT 性能数据库 具有一些不错的功能,例如检测移动平均线、标准差、变化等。但是报告页面过于强调个别变化(其中噪声可能高于信号),例如 此案例

该项目的第一部分是创建一个分析工具,该工具将跟踪移动平均线并报告

  • 如果当前结果高于/低于之前的移动平均线超过(可配置的)S 个标准差
  • 如果当前移动平均线超过基准运行的 S 个标准差
  • 如果最后 A 个移动平均线持续增加/减少超过 P 个百分比

第二部分是创建一个网页,该网页将显示所有相关的基准测试(可能是可配置的,例如仪表板),并显示带有红色/黄色/绿色代码的基本统计信息以显示状态以及指向每个基准测试更详细分析的链接。

可能的第三部分是能够自动交叉引用不同的构建,这样,如果您按架构/编译器/CPU 数量对它们进行分组,则此自动化工具将了解这些更改在某个特定组中更为常见。

LLVM 覆盖率报告 具有一个不错的界面来显示测试覆盖了哪些源代码行,但它没有提及哪些测试、哪些修订版和覆盖了哪些架构。

翻新 LCOV 的一个项目将涉及

  • 使其在 buildbot 上运行,以便我们知道哪些提交/架构被覆盖
  • 更新网页以显示该信息
  • 开发一个系统,该系统将每个 buildbot 构建报告到可搜索数据库的网页中,例如 LNT

另一个想法是启用测试套件以运行所有已构建的后端,而不仅仅是主机架构,以便可以在快速机器中构建覆盖率报告,并且每个提交都有一个报告,而无需更新 buildbot。

  1. 完全重写 bugpoint。除了混乱之外,bugpoint 还存在许多问题,它会在缩减时“丢失”错误。应该从头开始重写它以解决这些和其他问题。
  2. 为 PassManager 添加事务支持,以改进 bugpoint。
  3. 改进 bugpoint 以支持在 MP 机器上并行运行测试.
  4. 为 SPARC 端口添加 MC 汇编器/反汇编器和 JIT 支持。
  5. 将更多优化移出-instcombinepass 并移入 InstructionSimplify。应该移动的优化是不创建新指令的优化,例如将sub i32 %x, 0变成%x。许多 pass 使用 InstructionSimplify 来清理它们的代码,因此使其更智能可以带来各方面的改进。

有时创建新事物比改进现有事物更有趣。这些项目往往涉及更多,可能需要更多工作,但也可能非常有益。

许多提出的 LLVM 核心的扩展和改进 正在等待设计和实现。

  1. 调试信息生成的改进
  2. 对非调用异常的 EH 支持
  3. 许多功能请求的想法都存储在 LLVM bugzilla 中。搜索 带有“new-feature”关键字的错误

我们为基于指针分析的优化以及指针分析本身的开发奠定了 强大的基础。我们想要利用这一点

  1. globals mod/ref pass 执行廉价的自下而上的上下文敏感别名分析。我们可以做一些廉价的事情来更好地捕获访问指针参数的函数的效果。这对于 C++ 方法来说非常重要,它们花费大量时间访问 'this' 上的指针。
  2. 别名分析 API 支持 getModRefBehavior 方法,该方法允许实现详细分析函数。例如,我们可以实现 完全了解 printf/scanf 副作用,这将非常有用。此功能已到位,但目前未用于任何用途。
  3. 我们需要某种方法来推理 errno。考虑如下循环
        for ()
          x += sqrt(loopinvariant);
    

    我们希望将其转换为

        t = sqrt(loopinvariant);
        for ()
          x += t;
    

    这种转换是安全的,因为 errno 的值在循环中没有其他更改,并且循环中 errno 的退出值是相同的。我们目前无法做到这一点,因为 sqrt 会破坏 errno,因此它不是“readonly”或“readnone”,并且我们没有很好的方法来建模它。

    该项目的重要部分是弄清楚如何在优化器中描述 errno:每个 libc #defines errno 似乎都不相同。也许解决方案是拥有一个 __builtin_errno_addr() 或类似的东西,并更改 sys 标头以使用它。

  4. 有很多方法可以优化掉和 改进 memcpy/memset 的处理

我们现在拥有一个统一的基础设施来编写配置文件引导的转换,它可以在离线编译时或 JIT 中工作,但我们没有很多转换。我们欢迎新的配置文件引导的转换以及对当前分析系统的改进。

配置文件引导的转换的想法

  1. 超块形成(具有许多优化)
  2. 循环展开/剥离
  3. 配置文件定向内联
  4. 代码布局
  5. ...

对现有支持的改进

  1. 当前插入的块和边缘分析代码非常简单且效率低下。通过使用控制依赖信息,可以向代码中插入更少的计数器。此外,如果已知循环的执行计数是编译时或运行时常量,则可以避免循环中的所有计数器。
  2. 您可以实现一种“静态分析”算法,该算法分析一段代码并对代码各个部分的相对执行频率进行有根据的猜测。
  3. 您可以添加路径分析支持,或调整现有的 LLVM 路径分析代码以使用通用分析接口。

LLVM 积极地针对性能进行优化,但尚未针对代码大小进行优化。随着新的 ARM 后端的出现,人们越来越关注在代码大小更重要的嵌入式系统中使用 LLVM。

有兴趣在 LLVM 中实现代码压缩的人可能想阅读 本文,其中描述了使用链接时优化进行代码大小优化。

  1. 实现循环依赖分析基础设施
    - 设计某种方式来表示和查询依赖分析
  2. 值范围传播 pass
  3. 更多关于循环的乐趣:预测公共化
  4. 类型推断(又名。devirtualization)
  5. 值断言 (也 PR810)。
  1. 通过添加必要的目标钩子并确保正确处理所有 IR/MI 功能(例如寄存器掩码和谓词指令),概括可以独立于目标的特定于目标的后端 pass。对于这样做明显有利的其他目标,启用这些 pass。例如
    1. lib/Target/Hexagon/RDF*
    2. lib/Target/AArch64/AArch64AddressTypePromotion.cpp
  2. 将延迟槽填充逻辑合并到 Sparc 和 Mips 后端(至少)重复到单个目标独立 pass 中。同样,几个目标中的分支缩短逻辑也应合并到一个 pass 中。
  3. 实现“堆栈槽着色”,如果两个帧索引的生存期不重叠,则将它们分配给相同的堆栈偏移量。这可以重用来自 LiveIntervals 的大量分析机制。使堆栈更小有利于缓存使用,并且在加载具有有限位移的目标(如 ppc、thumb、mips、sparc 等)上非常重要。这应该在序言/后记插入之前作为 pass 完成。这现在为寄存器分配器临时变量完成,但不为 allocas 完成。
  4. 实现“收缩包装”,这是被调用者保存寄存器保存/恢复的智能放置。现在 PrologEpilogInsertion 始终在序言中保存每个(修改后的)被调用者保存寄存器,并在后记中恢复它,但是,函数中的某些路径(例如,早期退出)可能不会使用所有寄存器。将保存下沉到 CFG 中可以避免在这些路径上进行无用的工作。这项工作已经开始,请在 llvm-dev 上咨询。
  5. 实现过程间寄存器分配。CallGraphSCCPass 可用于实现自下而上的分析,这将确定函数实际破坏的寄存器。使用 pass 根据被调用者使用的实际寄存器微调调用者中的寄存器使用。
  6. 为汇编器和反汇编器添加对 16 位 x86 汇编和实模式的支持,供 BIOS 代码使用。这包括 16 位指令编码以及特权指令(lgdt、lldt、ltr、lmsw、clts、invd、invlpg、wbinvd、hlt、rdmsr、wrmsr、rdpmc、rdtsc)以及控制和调试寄存器。
  1. Bigloo Scheme 编译器(来自 INRIA Sophia-Antipolis 的 Manuel Serrano)移植到输出 LLVM 字节码。似乎它已经可以输出 .NET 字节码、JVM 字节码和 C,因此 LLVM 表面上将是另一个不错的候选者。
  2. 为其他某种语言(Java?OCaml?Forth?)编写新的前端
  3. 随机测试向量生成器:使用 C 语法生成随机 C 代码,例如 quest;通过 llvm-gcc 运行它,然后使用 opt 在其上运行一组随机的 pass。尝试崩溃opt。当opt崩溃时,使用bugpoint来缩减测试用例并将其发布到网站或邮件列表。无限重复。
  4. 向解释器添加沙箱功能:捕获无效的内存访问、潜在的不安全操作(通过任意内存指针访问)等。
  5. 移植 Valgrind 以使用 LLVM 代码生成和优化 pass 而不是它自己的。
  6. 编写 LLVM IR 级别调试器(扩展解释器?)
  7. 编写 LLVM 超级优化器。将 x86 超级优化器的想法(论文 #1论文 #2)应用于 LLVM 代码将很有趣。

    对 LLVM 代码进行操作似乎可以节省大量时间,因为它的语义比 x86 简单得多。对 LLVM 进行操作的代价是会错过特定于目标的技巧。

    结果将是一个新的 LLVM pass,它至少包含指令组合器,可能还包含其他几个 pass。好处将包括不遗漏当前组合器遗漏的情况,并且更容易适应 LLVM IR 的更改。

    之前的所有超级优化器都对代码的线性序列进行操作。对程序依赖图的小子图进行操作似乎要好得多。

除了增强现有 LLVM 基础设施的项目外,还有一些项目改进了使用但不包含在 LLVM 编译器基础设施中的软件。这些项目包括使用 LLVM 的开源软件项目和研究项目。与增强核心 LLVM 基础设施的项目一样,这些项目通常具有挑战性和回报性。

至少一个项目(可能更多)需要在 MachineFunctionPass 中使用分析信息(例如调用图分析),但是,大多数分析 pass 在 LLVM IR 级别运行。在某些情况下,值(例如,函数指针)无法从 MachineInstr 级别可靠地映射回 LLVM IR 级别,从而使得从 MachineFunctionPass 中使用现有 LLVM 分析 pass 变得不可能(或至少是脆弱的)。

该项目是将来自 LLVM IR 级别的分析信息编码到生成的 MachineInstr IR 中,以便 MachineFunctionPass 可以使用它。示例是调用图分析(对于控制流完整性检测、代码重用防御分析和小工具编译器很有用);但是,其他 LLVM 分析可能也很有用。

在 LLVM JIT 中实现按需函数重定位器。这可以使用运行时分析信息来帮助改善代码局部性。这个想法是对每个函数使用重定位表。每次函数重定位时都需要更新重定位条目(请查看 本文)。(每个函数)基本块重新排序将是一个有用的扩展。

该项目的目标是使用引用亲缘性模型来实现更好的数据布局优化。这篇 论文 提供了一些背景信息。

Slimmer 是一个使用 LLVM 构建的原型工具,它使用动态分析来查找程序中潜在的性能错误。Slimmer 的开发始于 2015 年 Google Summer of Code,并产生了初始原型,但仍需要对原型进行评估和改进,使其具有可移植性和鲁棒性。该项目将让学生接手并完成 Slimmer 的工作。Slimmer 的源代码及其当前文档可以在其 Github 网页上找到。