我们这里只讲 llvm 子目录,其他的 module 暂时不讲。

本笔记记录于我接触 LLVM 20 个月左右,已经对源码构成和编码风格有了大致的了解。为了进一步解读 LLVM 的实际代码构成,方便综合性分析性能缺陷,同时为了在遇到性能缺陷时第一时间给出 LLVM 中的可能存在的问题。

本文用例是 LLVM 官方 19.1.0.

导览

首先可以简要 ls 看一下一级文件夹的组成部分:

benchmarks  cmake-build-debug  CMakeLists.txt  docs      lib             projects             resources  tools
bindings    CMakeCache.txt     configure       examples  LICENSE.TXT     README.txt           runtimes   unittests
cmake       CMakeFiles         CREDITS.TXT     include   Maintainers.md  RELEASE_TESTERS.TXT  test       utils

其中首先需要关注的是 lib 和 include 文件夹;其次需要关注 tools, unittests, utils, runtimes 文件夹。其中:

  • lib : LLVM 的核心代码库都放在这个目录下,包括各种编译器中间表示(IR)、优化、代码生成、后端实现等模块。可以认为 lib 是 LLVM “引擎”的实现所在,很多关键算法和数据结构均在此处实现。
  • include :与 lib 配套,include 文件夹存放的是 LLVM 的公共头文件(API 接口声明、数据结构定义等)。当外部代码或 LLVM 内部模块需要使用某个功能时,通常会包含这里的头文件。lib 和 include 合起来构成了 LLVM 的核心库及其接口。

  • tools :这个目录包含了 LLVM 自身提供的一系列工具,例如编译器前端 Clang(尽管 Clang 可能在 projects 或独立仓库中)、调试器、汇编工具、静态分析工具等。==这是 LLVM 工具链的实现的地方==。

  • unittests :单元测试代码放在这个目录中,用于对 LLVM 各个模块进行功能验证。单元测试帮助确保代码在修改后仍能保持正确性,并且对日常开发和持续集成非常重要。
  • utils :包含一些辅助工具和脚本,这些工具可能是构建、测试、代码格式化、自动化任务的支持程序。它们在 ==LLVM 的开发过程中提供了很多便利==,帮助维护代码质量和开发效率。
  • runtimes :存放的是与 LLVM 运行时相关的代码和库,例如编译器运行时库(compiler-rt)、各种运行时支持模块。这些运行时库通常被生成的代码调用,用于支持例如内置函数、数学库替换等功能。

llvm/lib

初学者往往认为 LLVM 的工程非常庞大,无从下手,但是参考附录 A 的统计数据,C++文件仅有 2000 余个,完全可以归类和进行大体分析。我们首先按照重要性给这些二级目录分一下类:

  • ★★★★★:==IR==、==CodeGen==、MC、==Target==、==TableGen==、==LTO==、Support、Option、Passes、Object、Bitcode、Bitstream、==Transforms==、TargetParser、==ExecutionEngine==等模块构成了 LLVM 的核心体系,直接影响编译器的整体功能与性能。
  • ★★★★☆:FrontEnd、IRPrinter、IRReader、DebugInfo、CodeGenTypes、MCA、ProfileData、XRay 等在关键流程中发挥重要作用,但作为辅助工具或细化功能可略逊于核心模块。
  • ★★★☆☆:Analysis、AsmParser、BinaryFormat、Debuginfod、Demangle、DWARFLinker、DWP、Fuzzer、FuzzMutate、LineEditor、ObjectYAML、InterfaceStub、SandboxIR、Telemetry、TextAPI、ToolDrivers、Testing、WindowsDriver、WindowsManifest 等则主要属于辅助、扩展或测试支持功能,对核心编译流程影响较小。
    下面是对上述归类的一览表:
文件夹重要性评分说明
Analysis★★★★★提供静态分析支持,辅助优化和验证,但不直接参与核心代码生成。
AsmParser★★★☆☆汇编解析工具,对处理汇编代码有用,属于辅助功能。
BinaryFormat★★★☆☆负责处理二进制格式,支持性功能较强。
Bitcode★★☆☆☆LLVM IR 的二进制序列化格式,是跨平台传递 IR 的核心。
Bitstream★★★☆☆处理 Bitcode 的读写与序列化,为核心底层支持。
CGData★★★☆☆为代码生成提供数据结构支持,属于后端的重要辅助模块。
CodeGen★★★★★后端代码生成的核心模块,直接影响机器代码输出。
CodeGenTypes★★★★☆定义和管理代码生成时的数据类型,支撑后端生成。
DebugInfo★★★★☆提供调试信息支持,对调试和诊断至关重要。
Debuginfod★★☆☆☆专用于调试信息分发,属于扩展支持功能。
Demangle★★★☆☆用于符号解码,方便调试信息展示,不影响编译核心。
DWARFLinker★★☆☆☆针对 DWARF 调试信息链接,主要服务于调试支持。
DWP★★☆☆☆DWARF 信息打包工具,属于调试辅助工具。
Fuzzer★★☆☆☆==面向安全和==测试的工具,不属于常规编译流程。
FuzzMutate★★☆☆☆==用于模糊测试的辅助工具。==
LineEditor★★☆☆☆文本编辑辅助工具,对核心流程无直接影响。
Object★★★★★处理目标文件和二进制对象,核心于目标代码的组织与操作。
ObjectYAML★★☆☆☆提供 YAML 格式支持,主要用于辅助性展示。
Frontend★★★★★前端解析和初步转换模块,是整个编译流程的入口。
ExecutionEngine★★★★★支持 JIT 编译与运行时执行,关系到程序执行。
InterfaceStub★★☆☆☆提供接口占位支持,辅助性较强。
IR★★★★★LLVM 中间表示的核心,整个编译优化的基础。
IRPrinter★★★★☆将 IR 转为可读格式,调试和验证时非常重要。
IRReader★★★★☆从文本或其他格式读取 IR,核心 I/O 功能。
TableGen★★★★★自动生成大量描述代码,是自动化配置 Target 等模块的关键工具。
LTO★★★★★链接时优化模块,实现全程序优化,至关重要。
MC★★★★★负责机器码相关处理,生成目标代码的关键环节。
MCA★★★★☆Machine Code Analyzer,用于性能调优和分析。
Option★★★★★命令行选项解析库,为整个编译器提供基础支持。
Passes★★★★★包含各种优化 Pass,对整个编译优化流程核心。
ProfileData★★★★☆收集和管理性能数据,对反馈和调优非常关键。
SandboxIR★★☆☆☆用于实验和测试 IR 转换,不属于生产核心。
Support★★★★★提供通用工具和基础库,贯穿各模块,极为重要。
Target★★★★★定义目标平台,后端代码生成的基础。
TargetParser★★★★★解析目标描述,对生成目标代码起关键作用。
Transforms★★★★★执行 IR 转换和优化,编译优化核心。
Telemetry★★☆☆☆数据上报与监控,辅助于系统运行统计。
TextAPI★★☆☆☆文本处理接口,属于辅助性工具。
ToolDrivers★★☆☆☆提供工具驱动支持,辅助功能。
Testing★★★☆☆测试框架,确保各模块正确性,但不直接影响产品编译。
XRay★★★★☆内置的跟踪与性能分析工具,对调试性能非常有帮助。
WindowsDriver★★☆☆☆针对 Windows 平台的专用支持,不是跨平台核心。
WindowsManifest★★☆☆☆针对 Windows 的配置文件,辅助于平台适配。

附录 A-代码统计

❯ cloc .
   72785 text files.
   72220 unique files.                                          
    7063 files ignored.

github.com/AlDanial/cloc v 1.90  T=42.02 s (1566.0 files/s, 520304.0 lines/s)
---------------------------------------------------------------------------------------
Language                             files          blank        comment           code
---------------------------------------------------------------------------------------
LLVM IR                              38638         724163        8547726        3521229
C++                                   4102         353147         401906        2152276
JSON                                  2862              1              0        1085693
YAML                                  5216          77069          70500         998111
Assembly                              8673         582930        1381465         847763
C/C++ Header                          3191         110011         183250         418580
reStructuredText                      1180          46066          54138          98981
CMake                                 1062           9137           7298          45198
Python                                 328           7319          10706          29648
Windows Module Definition              100           2405            202          19681
C                                      109           2647           3136          16357
Markdown                                34           2806              0           8722
SVG                                      8              0              0           7804
OCaml                                   38           1446           2385           5073
Bourne Shell                            26            477            614           3966
Pascal                                  19           1262           5852           2602
XML                                     34             51             44           2261
HTML                                    18            209              1           1890
Windows Resource File                  110            131             37           1116
CSS                                      5            114             45            850
Perl                                     5            120            146            657
DOS Batch                                2             77             45            582
vim script                              12             61             76            404
Jupyter Notebook                         3              0           2434            319
Lisp                                     4             47             92            239
Bourne Again Shell                       2             20             92            166
TypeScript                               2             13              3             78
make                                     1             17              5             74
Objective-C                              6             34            209             69
Dockerfile                               3             14             54             51
INI                                      7             10              0             42
TOML                                     2              3              0             22
Swift                                    2              6              0             17
NAnt script                              1              0              0             13
CSV                                      2              0              0              6
OpenCL                                   1              0              0              6
Logos                                    2              4              0              2
---------------------------------------------------------------------------------------
SUM:                                 65810        1921817       10672461        9270548
---------------------------------------------------------------------------------------

❯ cloc lib
    4647 text files.
    4647 unique files.                                          
     557 files ignored.

github.com/AlDanial/cloc v 1.90  T=3.31 s (1235.4 files/s, 786675.1 lines/s)
---------------------------------------------------------------------------------------
Language                             files          blank        comment           code
---------------------------------------------------------------------------------------
C++                                   2870         284487         347766        1742709
C/C++ Header                           915          25575          31342         113928
Assembly                                12            125            118          26285
C                                       16            931           1407           9056
CMake                                  230            789             98           6566
Windows Module Definition               22            200              0           3824
Pascal                                  13           1116           5256           1734
Python                                   6             99            107            391
Markdown                                 5            161              0            389
YAML                                     1              0              0              2
---------------------------------------------------------------------------------------
SUM:                                  4090         313483         386094        1904884
---------------------------------------------------------------------------------------