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


有用链接
发布邮件
18.1.8: 2024年6月
18.1.7: 2024年6月
18.1.6: 2024年5月
18.1.5: 2024年5月
18.1.4: 2024年4月
18.1.3: 2024年4月
18.1.2: 2024年3月
18.1.1: 2024年3月
18.1.0: 2024年3月
17.0.6: 2023年11月
17.0.5: 2023年11月
17.0.4: 2023年10月
17.0.3: 2023年10月
17.0.2: 2023年10月
17.0.1: 2023年9月
所有公告

维护者
llvm-admin 团队
开放 LLVM 项目

LLVM 团队 编写

欢迎未来的 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. 替换已知的模式,例如基于 undef/poison 的分支、使用无效指针的内存访问等,替换为非 UB 模式。
  2. 使用 Alive2 检测更多模式(通过搜索始终为 UB 的测试)。
  3. 报告 Alive2 发现的任何 LLVM 错误,这些错误在移除 UB 时会暴露出来。

预期结果: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 存储库,并附有详细的说明以复制转换过程,以便未来的维护人员能够在语法更改时重新生成文件。请注意,语法本身应保留在其现有的单独存储库中,不要移入 LLVM 中。

预期结果

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

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

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

确认导师: Natalie ChouinardNathan Gauër

讨论: URL

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

本项目旨在将 LLVM CAS 库集成到 LLVM 位流文件格式中。如果我们将位流文件中经常重复的部分分解到一个单独的 CAS 对象中,我们就可以用对规范 CAS 对象的小型引用替换所有副本,从而节省存储空间。

本项目的主要激励用例是支持“隐式发现、显式构建”Clang 模块的依赖项扫描程序。在现实世界中,即使在块级别进行粗略的重复数据删除,也可以将扫描模块缓存的大小减少一半。

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

技能: C++ 中级知识,对数据序列化有一定的了解,具备自我驱动力。

项目规模: 中等或大型

确认导师: Jan SvobodaSteven Wu

讨论: URL

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

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

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

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

技能: C++ 中级知识

项目规模: 中等或大型

难度:中等

确认导师: Nikita PopovDhruv Chawla

讨论: URL

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

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

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

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

技能: 了解静态网站生成器领域的网页开发知识。了解 html、css、bootstrap 和 markdown。耐心和自我驱动力。

难度: 困难

项目规模: 大型

确认导师: Tanya LattnerVassil Vassilev

讨论: 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(有关更多详细信息,请参阅此 演讲)。其次,用户代码中的崩溃会导致整个进程崩溃,从而阻碍整体可靠性和易用性。

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

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

技能: C++ 中级知识,了解 LLVM,尤其是 LLVM JIT。

项目规模: 中等或大型。

难度:中等

确认导师: Vassil Vassilev

讨论: 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 上的新功能。

预期结果: 本项目旨在允许 make 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 VassilevSaleem Abdulrasool

讨论: 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 的解析器和预处理器相对无状态,并且可以用于处理本质上非线性的字符序列。特别是命名空间范围的定义相对容易处理,并且在延迟解析某些内容时返回到命名空间范围并不困难。对于其他上下文(如局部类),我们将丢失一些基本信息,例如局部实体的名称查找表。但是,这些情况可能不太有趣,因为延迟解析粒度可能仅对顶级实体有意义。

这种实现可以帮助解决标准中已存在的问题,例如 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 和预处理器的知识。

项目规模:大型

难度: 困难

确认导师:Vassil VassilevMatheus Izvekov

讨论:URL

项目描述:Clang-Doc 是一款 C/C++ 文档生成工具,作为 Doxygen 的替代方案创建,并构建在 LibTooling 之上。这项工作始于 2018 年,并在 2019 年获得了关键的关注,但此后开发基本处于停滞状态,主要原因是缺乏资源。

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

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

预期结果:该项目的目的是解决现有缺点并提高 Clang-Doc 的可用性,使其能够用于生成 LLVM 等大型项目的文档。理想的结果是 LLVM 项目将使用 Clang-Doc 生成其参考文档

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

技能:网页技术(HTML、CSS、JS)经验以及 C++ 中级知识。以前使用 Clang/LibTooling 的经验是一个加分项,但不是必需的。

项目规模:中等或大型。

难度:中等

确认导师:Petr HosekPaul 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

目标是在某些明确情况下生成类似的输出,例如,常量变量或完全位于寄存器中的变量。

确认导师及其联系方式

所需/期望的技能

所需

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

期望

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

项目规模。

中等(~175 小时)

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

困难

讨论:URL

描述

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

预期成果

一个无需丢失原始错误即可减少 GPU 错误的工具。或者,其他属性可以成为减少的重点,而不仅仅是错误。

确认导师及其联系方式

所需/期望的技能

所需

  • 良好的 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 卸载,但我们知道其他算法,尤其是那些具有用户提供的函子的算法,还需要静态程序分析和潜在的转换以进行额外的数据管理。该项目的目的是探索不同的算法以及我们在主机和加速器设备(尤其是 GPU)上执行它们的选项,通过 OpenMP 自动执行。

预期成果

改进 libcxx 中卸载的原型支持。评估其他卸载方法,并记录缺失部分和不足之处。

确认导师及其联系方式

所需/期望的技能

所需

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

期望

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

项目规模。

大型

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

中等

讨论:URL

描述

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

预期成果

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

确认导师及其联系方式

所需/期望的技能

所需

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

期望

  • 对 LLVM 代码库和优化流程有很好的理解

项目规模。

中等

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

简单

讨论:URL

描述

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

预期成果

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

确认导师及其联系方式

所需/期望的技能

所需

  • 具备性能分析技能,并了解 GPU 架构

期望

  • 熟悉 libc 工具

项目规模。

小型

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

简单

讨论: 链接

描述

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

预期成果

更有效的 GPU First 框架,可以支持 NVIDIA 和 AMD GPU。可选地,将框架上游。

确认导师及其联系方式

所需/期望的技能

所需

  • 深入理解 C++ 和 GPU 架构
  • 熟悉 GPU 和 LLVM IR

期望

  • 深入理解 LLVM 代码库和 OpenMP 目标卸载

项目规模。

中等

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

中等

讨论: 链接

描述:异构编程模型,如 SYCLOpenMPOpenACC,帮助开发人员将计算密集型内核卸载到 GPU 和其他加速器上。 MLIR 有望为下一代异构编程模型编译器带来新的高级优化和更好的代码生成。然而,稳健的 MLIR 发射 C/C++ 前端是这些工作的前提条件。

ClangIR (CIR) 项目旨在为 Clang 建立一个新的中间表示 (IR)。它构建在 MLIR 之上,为 Clang 中基于 C/C++ 的语言提供了一种方言,以及从 Clang AST 发射它的必要基础设施,以及到 LLVM-IR 方言的降低路径。在过去的一年中,ClangIR 已发展成为一个成熟的孵化器项目,并且最近关于将其上游到 LLVM 单一代码库的 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

讨论: 链接

描述

半精度是一种 IEEE 754 浮点格式,最近得到了广泛的应用,尤其是在机器学习和人工智能领域。它在最新的 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

讨论: 链接

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

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

解决这两个问题的方案有很多种。例如,可以通过采样、使用现有的性能分析基础结构或通过实现自定义检测来识别热函数。重新优化可以应用于整个函数,或者可以使用轮廓来启用函数部分的优化。从 JIT 代码重新进入 JIT 基础结构可能是在现有延迟编译的基础上实现的,或者通过自定义路径实现。

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

预期结果

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

所需技能:中级 C++;特别是对 LLVM 和 LLVM JIT 的理解。

项目规模:大型。

难度:中等

确认导师:Vassil VassilevLang Hames

讨论: 链接

项目描述: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

讨论: 链接

项目描述:虽然编译器的首要任务是生成快速代码(良好的运行时性能),但优化花费的时间不能太长(良好的编译时性能)也很重要。该项目的目的是在不影响优化质量的情况下提高编译时间。
该项目的总体方法是

  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

讨论: 链接

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


解决这些问题的常用方法是

  1. 检查 Godbolt 上的--emit=llvm-ir输出。
  2. 创建一个 LLVM IR 测试用例,在通过opt -O3运行时不会被优化。
  3. 识别缺失的最小转换,并使用 alive2 证明其正确性。
  4. 确定哪个或哪些 LLVM Pass 可以执行转换。
  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 是一种优势,但不是必需的。

项目规模:根据 IPC 的重用情况,175 小时或 350 小时

难度:中等

确认导师: 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 运行。这种管道允许创建高效的解释器。解释器支持交互式探索,并使 C++ 语言更易于使用。交互式 C++ 在 Jupyter 中通过 xeus 内核协议使用增量编译模式。较新版本的协议允许可能的浏览器内执行,从而为 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 及其 API,特别是 LLVM JIT

    项目类型:大型

    讨论区 链接

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

可以对 LLD 进行改进的非全面列表:

  • --print-memory-usage 支持

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

  • 链接图(Linkmap)

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

  • --print-gc-sections 改进

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

项目规模:中等或大型

难度:中等/困难

技能:C++

预期结果:

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

确认导师:Prabhu Rajasekaran Petr Hosek

讨论区:链接

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

该项目的目标

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

预期成果:

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

期望技能:中等水平的 C++,基准测试经验

项目规模:大型

难度:中等

确认导师Kunwar Grover

讨论区链接

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

该项目的目标

  • 了解 MLIR IR 表示和用户通常进行的探索。
  • 实现一个 REPL 来执行对 MLIR IR 的查询。

预期成果:

  • 独立的工具,可用于交互式探索 IR。
  • 实现该工具可用的通用匹配器。
  • (扩展)启用将查询匹配的 IR 部分提取到自包含的 IR 片段中。

期望技能:中等水平的 C++,编写/调试窥孔优化经验

项目规模:中等或大型。

难度:中等

确认导师Jacques Pienaar

讨论区链接

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

项目规模:175 或 350 小时。

难度:中等

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

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

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

导师 Ondrej Sykora、Mircea Trofin、Aiden Grossman

讨论区 链接

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

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

整个功能被标记为实验性:它基本上是一个概念验证实现。它很可能能够真正发挥作用,但它需要通过在真实世界源代码上运行它来进行一些质量控制,并且需要解决许多错误,尤其是在单个检查中,然后我们才能宣布它稳定。此外,所有检查中最美味的检查——基于受污染的循环边界或大小参数的缓冲区溢出检测——从未实现。还有一个与受污染索引的数组访问相关的检查——这同样是实验性的;让我们看看我们是否也可以宣布这个稳定!

预期结果:许多与污点相关的检查要么默认对所有静态分析器用户启用,要么对关心安全的用户作为可选功能提供。它们在真实世界代码上被确认具有低误报率。希望缓冲区溢出检查也是其中之一。

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

项目规模:中等或大型。

难度:中等

确认导师:Artem DergachevGábor HorváthZiqing Luo

讨论区:链接

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

项目规模:175 或 350 小时。

难度:中等

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

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

导师 Tarindu Jayatilaka、Mircea Trofin、Johannes Doerfert

讨论区 链接

项目描述
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 仓库代码覆盖率报告中展示此功能的使用。

项目规模:中等或大型

难度:中等

确认导师:Gulfem Savrun Yeniceri Petr Hosek

讨论:URL

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

项目规模:中等

难度:中等

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

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

确认导师:Satish Guggilla ([email protected]) Karthik Senthil ([email protected])

讨论:URL

项目描述
Clang 代码生成通过使用 AST 访问者发出 LLVM IR 来工作。在 ClangIR 项目中,我们也从 AST 访问者发出 ClangIR (CIR)(CIRGen),然后降低到 (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 代码生成进行比较。

项目规模: 大型

难度:中等

确认导师:Bruno Cardoso Lopes Nathan Lanza

讨论:URL

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

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

确认导师:Manuel Drehwald William Moses

理想技能: 良好的 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 中添加此步骤对于审查人员也将有所帮助。

项目规模: 小或中

难度: 简单

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

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

确认导师:Henrik Olsson

讨论: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(reStructed Text);技术写作能力。

项目类型:中等

讨论 URL

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

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

确认导师: Vassil VassilevStefan GränitzLang Hames

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

项目类型:大型

讨论 URL

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

预期结果

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

确认导师: Jamie Schmeiser,Whitney Tsang

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

项目类型:175 或 350 小时

难度评级:简单 - 中等

讨论 URL

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

项目规模:175 或 350 小时。

难度:中等

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

预期成果:预训练模型选择最经济的优化管道,且性能不会下降;在 LLVM 中连接模型;(重新)训练工具。

导师 Tarindu Jayatilaka、Mircea Trofin、Johannes Doerfert

讨论区 链接

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

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

难度:中等/困难

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

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

导师 Johannes Doerfert,Mircea Trofin

讨论 URL

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

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

难度:中等/困难

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

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

导师 Kazu Hirata,Liqiang Tao,Mircea Trofin

讨论 URL

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

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

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

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

我们相信通过

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

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

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

预期结果

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

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

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

项目规模: 350 小时

难度: 中等/困难

讨论 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 传递。

有关更多信息,有一个 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 VassilevRichard 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 DergachevRashmi MudduluruGábor HorváthKristóf Umann

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

项目规模:350 小时

难度:中等/困难

Discourse URL

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

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

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

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

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

确认导师:Aaron BallmanErich KeaneShivam Gupta

理想技能:C++ 编码经验

项目类型:大型/350 小时

Discourse URL

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

预期结果:目标是使 Polly 更易于使用,只需使用 NPM。里程碑,不一定都在本次 GSoC 中实现,包括
1. 使 Polly 的所有功能在 NPM 中可用(或决定弃用/删除它)
2. 更好地集成到 NPM 中(例如支持 PassInstrumentation);如果 NPM 被证明不足,则仅使用单片函数 Pass。
3. 在回归测试中替换旧的 Pass Manager。
4. 为 LLVM 中完全删除旧的 Pass Manager 做好准备。

确认导师:Michael Kruse

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

项目规模:中等

难度:中等/困难

Discourse URL

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

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

确认导师:William Moses、Tim Gymnich

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

项目规模:中等

难度:中等

Discourse URL

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

预期结果:1. Enzyme 可以由新的 Pass Manager 调用
2. [可选] 额外的语法糖,使 Enzyme 更易于使用。

确认导师:William Moses、Valentin Churavy

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

项目规模:小型

难度:中等

讨论 URL

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

我们鼓励您浏览此列表,看看哪些项目让您兴奋并与您的技能相匹配。我们也邀请您提出不在此列表中的建议。您必须通过我们的开发者邮件列表([email protected] 或特定子项目邮件列表)向 LLVM 社区提出您的想法。社区的反馈是您的提案被考虑并最终被接受的必要条件。

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

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

预期结果:如上所述,易于使用的框架。一些证据表明,给定一个分布式系统,如果用户使用该框架,则可以预期测试套件执行速度会加快。

确认导师:James Henderson

所需技能:良好的 Python 知识。熟悉 LLVM lit 测试。一些分布式系统的知识也很有益。

项目描述:这是一个简短的描述,如果它听起来很有趣,请联系 Johannes(IRC 上的 jdoerfert)和 Mircea Trofin。我们成功地引入了用于内联决策的 ML 框架,现在我们希望扩展范围。在这个项目中,我们将研究循环转换启发式,例如展开因子。作为一个激励示例,我们可以看一下一个小 trip count dgemm,我们对其进行了非常糟糕的优化。使用 nounroll pragma,我们做得更好,但仍然没有接近 gcc。该项目是开放式的,我们可以同时研究各种 Pass/启发式。

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

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

确认导师:Johannes Doerfert,Mircea Trofin

所需技能:中级 ML、C++ 知识,自我激励。

项目描述:这是一个简短的描述,如果它听起来很有趣,请联系 Johannes(IRC 上的 jdoerfert)。模糊测试通常会发现大量的错误。CSmith(和其他工具)展示了如何在类似 C 的语言中做到这一点,并且我们过去成功地使用了LLVM-IR 模糊测试。在这个项目中,我们将模糊测试应用于正在开发的新 Pass,例如 Attributor Pass。我们希望找到并修复崩溃,以及其他错误,包括编译时间性能问题。

准备资源:LLVM 模糊测试基础设施。我们可能希望进行模糊测试的 LLVM Pass,例如 Attributor Pass。之前的 IR 模糊测试工作(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,并在给定的循环不是最外层循环时立即返回。在这个项目中,我们希望利用最近引入的 LoopNest Pass 用于循环嵌套的 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 执行各种算法,例如 ML 中的反向传播或任何降低到 LLVM 的语言的现有代码上的科学模拟。Enzyme 通过将链式法则应用于原始要微分函数调用的每个函数中的每个指令来做到这一点。虽然功能正常,但这对于可能具有更快导数计算的代数属性的高级矩阵运算来说不一定是最佳的。Enzyme 还具有一种机制,可以为给定函数指定自定义梯度。如果存在自定义导数,Enzyme 将使用该导数,而不是回退到实现自己的导数。许多程序使用 BLAS 库来有效地计算矩阵和张量运算。此项目将通过为其操作指定自定义导数规则,从而实现 BLAS 和类似库(如 Eigen)的高性能自动微分。

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

确认导师: William Moses,Johannes Doerfert

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

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

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

确认导师: William Moses

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

项目描述: Enzyme 对 LLVM 程序执行自动微分(在微积分意义上)。这使用户能够使用 Enzyme 执行各种算法,例如 ML 中的反向传播或任何降低到 LLVM 的语言的现有代码上的科学模拟。虽然这适用于发出 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 Summer of Code 中的参与非常成功,并为 LLVM 贡献了许多有趣的项目。有关已接受和已完成项目的列表,请查看 Google Summer of Code 网站。

项目描述:这是一个简短的描述,如果听起来很有趣,请联系 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 通道(正在审查中),我们开始教 LLVM 优化流水线了解编码为 OpenMP 运行时调用的 OpenMP 并行性。在这个 GSoC 项目中,我们将研究 OpenMPOpt 通道中尚不可用的功能,以及连接现有过程内和过程间优化(例如 Attributor)的可能性。在这个项目中,有很大的自由度来确定实际的任务,但我们也将提供一个可以从中选择的较小和中等规模的任务池。

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

预期结果:对于并行程序(重点关注 OpenMP)获得可衡量的更好的性能或程序分析结果。

确认导师:Johannes Doerfert

理想技能: 中级 C++ 知识,自我激励。

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

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

此问题可能没有单一原因,而是在不同架构上的不同传递过程中触发的。其中一个原因是在编译器后端帧降低和其他后续传递期间插入调用帧信息 (CFI)。CFI 指令的存在似乎会更改指令调度,因此会导致生成的代码不同。

准备资源

  • PR37728 是一个元错误,收集了几个相关的代码生成差异问题。
  • PR37240 是一个讨论上面提到的 CFI 问题的错误。

  • 以下RFC讨论了一些可能的缓解策略,并提供了一些关于CFI问题的背景信息。

预期结果

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

确认导师:Paul Robinson和David Tellenbach

所需技能:C++的中级知识,对通用计算机架构有一定的了解,对x86或Arm/AArch64指令集有一定的了解。

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

准备资源

预期结果

  • 改进MergeFunctions使其具有与MergeSimilarFunctions相同的特性。
  • 使MergeFunctions能够用于ThinLTO。

确认导师:Aditya Kumar(IRC和phabricator上的hiraditya),JF Bastien(phabricator上的jfb)

所需技能:编译器设计课程,SSA表示,C++的中级知识,熟悉LLVM核心。

项目描述: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级别实现的,所以所有后端目标都从中受益。这是一个相对较新的优化,它最近在2019年的LLVM开发者大会上进行了展示,幻灯片在这里。因为大多数好处来自概述小的块,例如__assert_rtn。本项目的目标是通过静态分析(例如异常处理代码,优化个性函数)来识别潜在的块。使用成本模型来确保概述减少了调用者的代码大小,在适当的时候使用尾调用来节省指令。

准备资源

  • 关于热冷分离的更新
  • 以下两篇论文提供了早期关于热冷分离的工作。虽然这些论文是一个良好的开端,但LLVM的HCS在两个方面具有完全不同的实现:a)它是在IR级别实现的,并且将基本块作为函数而不是裸分支进行概述。b)它基于区域,并概述了一组基本块。
  • 演示文稿的视频和幻灯片

预期结果

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

确认导师:Aditya Kumar(IRC和phabricator上的hiraditya)

所需技能:编译器设计课程,SSA表示,C++的中级知识,熟悉LLVM核心。

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

预期结果(可能性)

  • 关于现有pass之间(隐式)依赖关系的见解。
  • 用户可以选择的新pass管道(例如-O3a,-O3b,…),这些管道往往在某些类型的程序上表现得更好。
  • 改进的LLVM pass启发式方法或新的基于机器学习的模型,可以根据代码结构选择LLVM转换pass的最佳顺序。

准备资源

  • HERCULES:迈向更智能的预测建模的强大模式,Eunjung Park;Christos Kartsaklis;John Cavazos,IEEE ICPP’14 https://ieeexplore.ieee.org/abstract/document/6957226
  • 多面体优化空间中的预测建模,Eunjung Park,John Cavazos,Louis-Noël Pouchet,Cédric Bastoul,Albert Cohen & P. Sadayappan,IJPP’13 https://link.springer.com/article/10.1007/s10766-013-0241-1
  • 编译器优化中的机器学习,Zheng Wang和Michael O’Boyle,IEEE杂志2018。https://ieeexplore.ieee.org/document/8357388

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

所需技能:C++,Python,最好具备LLVM和基于学习的预测经验。

项目描述:当前用于编译器优化的机器学习模型根据孤立的每个函数分析选择最佳的优化策略。在这种方法中,构建的模型没有意识到与其周围的其他函数(调用者或被调用者)的任何关系,而这些关系可能有助于确定每个函数的最佳优化策略。在本项目中,我们希望探索SCC(强连通分量)调用图,在构建基于机器学习的模型以查找每个函数的最佳优化策略时添加过程间特征。此外,我们希望探索将密切相关的函数组合在一起并作为一个组进行优化,而不是每个函数单独优化的案例是否会有所帮助。

预期结果(可能性)

  • 改进现有(过程间)pass的启发式方法,例如根据代码特征权衡内联与函数克隆。
  • 使用代码特征和过程间分析选择最佳优化的机器学习模型。该模型可用于孤立的函数或函数组,例如CGSCC。

准备资源

  • HERCULES:迈向更智能的预测建模的强大模式,Eunjung Park;Christos Kartsaklis;John Cavazos,IEEE ICPP’14 https://ieeexplore.ieee.org/abstract/document/6957226
  • 多面体优化空间中的预测建模,Eunjung Park,John Cavazos,Louis-Noël Pouchet,Cédric Bastoul,Albert Cohen & P. Sadayappan,IJPP’13 https://link.springer.com/article/10.1007/s10766-013-0241-1
  • 编译器优化中的机器学习,Zheng Wang和Michael O’Boyle,IEEE杂志2018。https://ieeexplore.ieee.org/document/8357388

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

所需技能:C++,Python,最好具备LLVM和基于学习的预测经验。

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

预期结果(可能性):在LoopStandardAnalysisResults中添加PostDominatorTree,并且可以被循环pass使用。更多常见的实用程序更改为生成更新列表,以便不同的更新程序可以轻松获取。

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

所需技能:中级 C++ 知识,自我激励。

准备资源:

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

预期结果(可能性):转换/分析可以编写为LoopNestPass,而不会影响编译时间或可用性。

确认导师:Whitney Tsang,Ettore Tiotto

所需技能:中级 C++ 知识,自我激励。

准备资源:

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

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

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

所需技能:中级 C++ 知识,自我激励。

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

预期结果(可能性):循环转换中所有现有方法的标准化/超集,用于检查代码是否可以安全移动和移动

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

所需技能:中级 C++ 知识,自我激励。

准备资源:

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

项目描述:Clang 静态分析器已经知道如何防止任意代码中由空指针取消引用引起的崩溃,但是当代码过于复杂时,它通常会“放弃”。特别是,C++ 标准类的实现细节,即使是像智能指针或可选值这样简单的类,也可能过于复杂,以至于分析器无法完全理解。此外,确切的行为取决于使用哪个标准库的实现(例如,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.
    }
    
我们应该能够至少完全覆盖一个类,例如,std::unique_ptr,然后看看我们是否可以将我们的结果推广到其他类,例如std::shared_ptr或 C++17 的std::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 中级知识。

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

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

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

确认导师: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 驱动程序、LLVM 选项和 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 的一种“大型待办事项列表”。本文档中的每个项目都是 LLVM 拥有后将很有用的东西,并且也是熟悉该系统的好方法。其中一些项目很小且独立,可以在几天内完成,另一些则更大。其中一些项目本身可能会导致有趣的科研项目。无论如何,我们欢迎所有贡献。

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

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

除了在主要 LLVM 项目上进行开发之外,LLVM 还拥有多个子项目,包括 Clang 等。如果您有兴趣参与这些项目,请参阅它们的“开放项目”页面。

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

目前,Clang 和 LLVM 都拥有独立的目标描述基础设施,一些功能重复,另一些则“共享”(Clang 必须创建完整的 LLVM 目标描述才能查询特定信息)。

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

另一种方法是为所有小问题创建标志,但首先,Clang 不是唯一使用 LLVM 中间/后端的 Frontend 或工具,其次,这就是“默认行为”存在的意义,因此我们错过了重点。

围绕修复 Clang 驱动程序关于识别架构、功能等方面(table-gen 它、用户特定的配置文件等)有一些想法,但它们都没有触及关键问题:与后端共享这些信息。

最近,将目标描述基础设施从 Clang 和 LLVM 中分解到两者都使用的独立库中的想法一直在流传。这将确保所有默认值、标志和行为都是共享的,但也将大大降低复杂性(从而降低维护成本)。这也将允许所有工具(lli、llc、lld、lldb 等)在整个过程中具有相同的行为。

主要挑战是

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

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

一些非常需要修复的具体问题

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

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

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

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

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

查找基准测试,方法是使用我们的 测试结果 或您自己的基准测试,其中 LLVM 代码生成器不会生成最佳代码,或者其他编译器会生成更好的代码。尝试最小化演示问题的测试用例。然后,要么 提交一个错误,其中包含您的测试用例以及 LLVM 生成的代码与它应该生成的代码,或者更好的是,看看您是否可以改进代码生成器并提交补丁。基本思想是,如果我们知道性能问题,通常很容易修复它们,但我们通常没有资源去找出性能不佳的原因。

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

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

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

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

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

LLVM 覆盖率报告 具有一个很好的界面来显示哪些源代码行被测试覆盖,但它没有提到哪些测试、哪个版本以及覆盖了哪些架构。

翻新 LCOV 的项目将涉及

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

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

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

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

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

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

我们有 强大的开发基础,可以进行基于指针分析的优化以及指针分析本身。我们想利用这一点

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

    我们希望将其转换为

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

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

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

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

我们现在拥有了一个统一的基础架构来编写 profile-guided 变换,无论是在离线编译时还是在 JIT 中,它都可以工作,但我们没有太多变换。我们欢迎新的 profile-guided 变换以及对当前分析系统的改进。

profile-guided 变换的想法

  1. 超级块的形成(以及许多优化)
  2. 循环展开/剥离
  3. Profile 指导内联
  4. 代码布局
  5. ...

对现有支持的改进

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

LLVM 积极地优化性能,但尚未优化代码大小。随着新的 ARM 后端,人们越来越感兴趣地使用 LLVM 用于嵌入式系统,在嵌入式系统中,代码大小是一个更大的问题。

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

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

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

    结果将是一个新的 LLVM 传递,它至少包含指令组合器,可能还包括其他一些传递。好处包括不会错过当前组合器错过的案例,以及更容易适应 LLVM IR 的变化。

    所有以前的超优化器都曾在代码的线性序列上工作。似乎在程序依赖图的小子图上进行操作会好得多。

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

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

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

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

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

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