文章目录
LLVM整体设计
Clang前端
基本概念
Clang 项目为LLVM项目提供C 语言系列语言C、C++、Objective C/C++、OpenCL、CUDA 和RenderScript)的语言前端和工具基础设施
Clangdriver(命令行表示是clang)和Clang前端(依照详细实现来说就是Clang的那些库所实现的前端)是不同的。Clang driver不只包括了
Clang前端,还包括使用LLVM的库实现的编译器的中间阶段以及后端,同时也集成了assembler。除了普通的前端工作,Clang还在不断发展,将其功能划分为库和模块,以便开发人员可以使用它们创建各种与源代码处理相关的工具;例如,代码重构编码格式化和语法高亮。

功能分析
| 阶段 | 任务描述 | 关键输入 | 关键输出 |
|---|---|---|---|
| 预处理(Preprocessor) | 处理头文件、宏展开、条件编译等预处理指令。 | 源代码(含预处理指令) | 展开后的纯代码(无预处理指令) |
| 词法分析(Lexer) | 逐字符扫描源代码,识别单词(如标识符、关键字、运算符等),并转换为统一的词法单元(Token)。 | 预处理后的代码 | Token序列(如 [int, x, =, 5]) |
| 语法分析(Parser) | 根据语法规则将Token序列转换为语法分析树(如AST),检查语法结构是否正确(如括号匹配、语句结构)。 | Token序列 | 抽象语法树(AST) |
| 语义分析(Sema) | 收集标识符属性(类型、作用域等),检查语义错误(如未声明变量、类型不匹配、重复定义)。 | AST | 带语义信息的AST(符号表填充) |
| 代码生成(CodeGen) | 将AST转换为目标平台的中间代码(如LLVM IR)或机器代码。 | 带语义信息的AST | LLVM IR/汇编代码/机器代码 |
AST结构
在使用自定义逻辑扩展Clang时,AST是最重要的原语。所有常见的Clang扩展/插件都是
基于ASTi运行的:clang-Xclang-ast-dump -fsyntax-only test.c
Clang中语法分析器会从之前的分析中提取要使用的标记信息,确定它的语法元素后会被推送到语义分析Sema,并为它创建AST节点,建立一颗与(词法分析出的)输入单词流对应的正确语法树。Clang构建AST树的核心类是ParseAST函数,初始化Compilerlnstance之后,调用其成员函数ExcuteAction进行解析与处理。

AST可细分为:declaration(Decl)声明,statement(Stmt)语句,expression(Expr)表达。


IR优化
基本概念

高级语言经过Clang等前端解析为平台无关的中间表示(Intermediate Representation,IR),使编译器能够在编译、链接以及代码生成的各个阶段忽略语言特性,进行全面有效的优化和分析。
LLVM基于统一的中间表示来实现优化遍,中间表示采用静态单赋值形式,该形式的虚拟指令集能够高效的表示高级语言,具有灵活性好、类型安全、底层操作等特点。如图所示,当同一变量出现多次赋值时,通过SSA变量重命名的方式加以区分,可以避免出现多次定义的情况。
IR的设计很大程度体现着LLVM插件化、模块化的设计哲学,LLVM的各种pass其实都是作用在LLVMIR上的。通常情况下,设计一门新的编程语言只需要完成能够生成LLVMIR的编译器前端即可,然后就可以轻松使用LLVM的各种编译优化、JIT支持、目标代码生成等功能。
IR表示
- LLVM IR 的三种存在形式
| 名称 | 特点 | 典型载体 |
|---|---|---|
| 内存表示 | C++ 对象模型(llvm::BasicBlock, llvm::Instruction …) |
编译器进程内存 |
| Bitcode | 二进制序列化格式,体积小、不可读 | .bc 文件 |
| LLVM 汇编 | 文本序列化格式,人类可读 | .ll 文件 |
- IR 的四大核心 C++ 类层次

最低0.47元/天 解锁文章
1884

被折叠的 条评论
为什么被折叠?



