E-BOOK LLVM编译器原理与实践 吴建明,吴一昊 LLVM编译器原理与实践

LLVM编译器原理与实践

👤 吴建明,吴一昊 📖 机械工业出版社 📋 9787111763543 🌐 zh-CN
28
下载次数
4.8
用户评分

📦 下载本书

  • 环境搭建困难:详细讲解LLVM与Clang的下载、配置、编译及安装流程,解决开发者从零开始搭建LLVM开发环境的问题。
  • 架构理解模糊:系统阐述LLVM三段式编译架构、核心子项目及工作原理,帮助读者理清LLVM整体设计脉络。
  • IR实践不足:通过大量示例深入解析LLVM IR的语法、生成流程及优化方法,提升读者对中间表示的实际运用能力。
  • 后端开发入门难:结合芯片编译器案例,讲解后端开发的关键技术如SSA、目标信息分析,降低后端开发的学习门槛。
  • 前沿技术陌生:专门介绍MLIR编译器,帮助读者了解并掌握这一新兴编译基础设施的核心概念与应用场景。
★★★
中级
入门初级中级进阶高级
  • 编译器开发工程师:需要深入理解LLVM内部机制,并希望在实际项目中应用LLVM进行定制化开发。
  • 人工智能芯片工程师:从事AI芯片编译器相关工作,需要掌握LLVM在芯片后端优化与部署中的实践方法。
  • 高校计算机专业师生:学习编译原理课程或进行相关研究,需要一本理论与实践结合的LLVM参考书。
  • 软件架构师:希望了解现代编译技术如何提升软件性能,从而在系统设计中更好地利用编译优化。
  • 科研工作人员:从事编程语言、编译优化或程序分析等方向的研究,需要掌握LLVM作为实验平台。
  1. 基础先行:建议先阅读第1章和第3章,掌握LLVM的安装与整体架构,为后续实践打下基础。
  2. 重点攻克:第4至6章是核心内容,涉及Clang前端和LLVM IR,需配合代码示例反复练习。
  3. 实践为主:第7至10章包含大量芯片编译器和优化案例,建议动手运行代码并修改参数观察效果。
  4. 拓展提升:最后阅读第11章MLIR,了解编译技术前沿,可结合官方文档深入学习。
  5. 配套练习:每章后的示例代码尽量独立完成,并尝试用不同优化选项对比生成结果。
  • 环境搭建技能:能够独立完成LLVM及Clang的编译安装,并配置适合的开发环境。
  • 架构理解深化:清晰掌握LLVM三段式编译架构、各子项目职责及与传统编译器的区别。
  • IR应用能力:熟练生成、阅读和优化LLVM IR,理解SSA形式及优化原理。
  • 后端开发入门:了解后端开发流程,掌握目标描述、指令选择等关键技术。
  • 前沿技术认知:对MLIR有系统性认识,能理解其在多级中间表示中的价值。
  • 实战经验积累:通过芯片编译器案例,积累将LLVM应用于实际项目的经验。

📖 书籍简介

产品特色

编辑推荐
这本书是关于LLVM这一强大而灵活的编译技术的详尽指南,它将帮助开发者理解编译器的设计和实现。鼓励每位对编译器技术有兴趣的读者阅读这本书,从而提升自身技术能力。
内容简介
LLVM是伊利诺伊大学的一个研究项目,提供一个现代化的,基于SSA的编译策略,并能够同时支持静态和动态的任意编程语言的编译目标。LLVM由不同的子项目组成,其中许多是正在生产中使用的商业和开源的项目。它也被广泛用于学术研究。
本书力求将LLVM基础知识理论与案例实践融合在一起进行详细的介绍,帮助读者理解LLVM工作原理,同时按照应用与设备需要,使用 LLVM进行相应的优化与部署。本书包含大量示例和代码片段,帮助读者掌握LLVM的编译器开发环境。
本书共11章,包括编译和安装LLVM、LLVM外部项目、LLVM编译器、Clang前端基础、Clang架构与实践示例、LLVM IR实践、LLVM芯片编译器实践示例、LLVM编译器示例代码分析、LLVM优化示例、LLVM 后端实践,以及MLIR编译器。
本书适合算法、软件、编译器、人工智能、硬件等专业方向的企业工程技术人员、高校师生、科研工作人员和技术管理人员阅读。
作者简介
吴建明,上海交通大学模式识别与智能系统专业博士毕业。长期从事人工智能芯片设计,尤其擅长TVM/LLVM编译器、AI框架、自动驾驶、芯片制造,嵌入式系统等领域的理论研究与技术创新。长期在一线工作,包括产品设计与代码实现等,主持和参与过30多项产品的研发。还参与过国家自然科学基金、上海市科委项目,并在核心期刊公开发表过8篇论文,其中6篇是第一作者。
目录

前言

第1章 编译和安装LLVM/

1.1LLVM系统入门/

 1.1.1查看LLVM(包括Clang等子项目)/

 1.1.2配置和构建LLVM与Clang/

1.2独立构建/

1.3软硬件环境要求/

 1.3.1硬件环境/

 1.3.2软件环境/

 1.3.3主机C++编译器和标准库/

 1.3.4获取流行主机C++工具链/

1.4LLVM入门/

 1.4.1术语和符号/

 1.4.2打开LLVM存档文件/

 1.4.3从Git中签出LLVM源代码/

 1.4.4本地LLVM配置/

 1.4.5编译LLVM套件源代码/

 1.4.6交叉编译LLVM/

 1.4.7LLVM目标文件的位置/

 1.4.8可选配置项目/

1.5目录布局/

1.6使用LLVM工具链的示例/

1.7LLVM常见问题/

1.8LLVM相关链接/

第2章 LLVM外部项目/

2.1LLDB调试器/

 2.1.1LLDB基础知识/

 2.1.2LLDB控制台/

2.2C++标准库libc++/

 2.2.1libc++库概述/

 2.2.2Ubuntu下安装Clang和libc++ /

2.3compiler-rt运行时库/

 2.3.1compiler-rt项目组成/

 2.3.2compiler-rt的作用/

 2.3.3平台支持/

 2.3.4compiler-rt源代码结构/

 2.3.5构建compiler-rt/

2.4DragonEgg /

 2.4.1DragonEgg将LLVM作为GCC后端/

 2.4.2DragonEgg实践/

2.5构建RISC-V LLVM并编译和运行test-suite/

 2.5.1构建RISC-V的前期准备/

 2.5.2开始构建/

 2.5.3编译test-suite/

 2.5.4运行LLVM test-suite/

2.6Clang附加工具/

第3章 LLVM编译器/

3.1LLVM与Clang源代码的下载及编译/

 3.1.1下载并编译 LLVM/

 3.1.2Clang源代码的下载与编译/

3.2LLVM编译器基础结构/

 3.2.1LLVM工作原理/

 3.2.2LLVM的主要子项目/

 3.2.3LLVM与Clang语法/

3.3LLVM三段式编译 /

 3.3.1传统编译器三段式设计及其实现/

 3.3.2LLVM的三段式设计的实现/

3.4LLVM与Clang架构/

 3.4.1LLVM与Clang架构简介/

 3.4.2编译架构特点分析/

3.5LLVM与GCC的区别/

3.6LLVM IR/

 3.6.1什么是LLVM IR/

 3.6.2LLVM IR编译流程/

 3.6.3如何得到IR/

 3.6.4IR文件链接/

 3.6.5IR文件编译流程/

 3.6.6IR语法中的关键字/

3.7词法分析与语法分析/

 3.7.1词法分析/

 3.7.2AST结构分析/

3.8交叉编译器/

 3.8.1主机与目标机/

 3.8.2为什么要交叉编译/

 3.8.3交叉编译难点/

3.9后端开发/

 3.9.1XLA后端分析/

 3.9.2SSA问题分析/

 3.9.3目标信息代码分析/

3.10LLVM示例实践/

 3.10.1如何在ARM上编译LLVM/Clang/

 3.10.2如何编写LLVM Pass/

 3.10.3基于LLVM的依赖分析方案/

3.11LLVM数据并行、时间并行和多核并行/

第4章 Clang前端基础/

4.1编译器Clang会代替GCC吗/

 4.1.1GCC概述/

 4.1.2Clang概述/

 4.1.3GCC基本设计与示例/

 4.1.4GCC与Clang的区别/

4.2使用 Clang 静态分析器进行分析调试/

 4.2.1静态分析器概述/

 4.2.2静态分析器库的结构/

 4.2.3静态分析器工作原理/

 4.2.4内部检查器/

 4.2.5关于 Clang 静态分析器/

4.3如何进行编译时间混编优化/

4.4Clang模块实现原理探究/

 4.4.1ModuleMap 与 Umbrella/

 4.4.2模块的构建/

 4.4.3Clang模块复用机制/

 4.4.4PCH与PCM文件/

4.5使用Clang校验AST/

 4.5.1制作Clang命令行工具的初衷/

 4.5.2制作Clang命令行工具主要步骤/

 4.5.3环境搭建/

 4.5.4开发框架选择/

 4.5.5代码开发/

4.6LLVM与Clang的底层原理/

 4.6.1传统编译器设计/

 4.6.2Clang前端/

 4.6.3IR的优化/

 4.6.4bitcode/

 4.6.5编译流程总结示例/

4.7自定义Clang命令,利用LLVM Pass实现对Objective-C函数的静态插桩/

 4.7.1Objective-C中的常见的函数hook实现思路/

 4.7.2什么是LLVM Pass/

 4.7.3编译过程/

4.8指令系统/

 4.8.1指令系统概述/

 4.8.2指令格式/

 4.8.3指令的寻址方式/

 4.8.4指令的类型与功能/

 4.8.5CISC和RISC的比较/

第5章 Clang架构与实践示例/

5.1C语言编译器Clang/

 5.1.1Clang和GCC编译器架构/

 5.1.2Clang起源/

5.2Clang模块内部实现原理及源代码分析/

 5.2.1编译参数分析/

 5.2.2预处理/

5.3好用的代码检查工具/

5.4Clang在Objective-C中的使用/

 5.4.1终端使用特点/

 5.4.2Clang的简单使用/

5.5Clang重排对象类结构分析/

 5.5.1概述/

 5.5.2根类、超类、子类/

5.6使用Clang编译C程序并在安卓设备中执行/

5.7分析Swift高效的原因/

 5.7.1Swift的函数派发机制/

 5.7.2结构体定义的内存分配/

 5.7.3编译SIL/

 5.7.4Clang编译流程的缺点/

 5.7.5Swift的特点及其编译器的使用流程/

5.8LLVM中矩阵的实现分析/

 5.8.1背景说明/

 5.8.2功能实现/

 5.8.3举例说明/

第6章 LLVM IR实践/

6.1LLVM架构简介/

 6.1.1LLVM IR的演变/

 6.1.2LLVM IR是什么/

 6.1.3LLVM架构/

 6.1.4前端生成中间代码/

 6.1.5LLVM后端优化IR/

 6.1.6LLVM后端生成汇编代码/

6.2获取LLVM IR/

 6.2.1LLVM IR的三种形式/

 6.2.2LLVM IR结构/

 6.2.3标识符与变量/

6.3LLVM IR实践——Hello world/

 6.3.1LLVM IR程序设计方法概述/

 6.3.2最基本的程序/

 6.3.3基本概念解释/

 6.3.4主程序/

6.4LLVM IR数据表示/

 6.4.1汇编层次的数据表示/

 6.4.2LLVM IR中的数据表示/

 6.4.3链接类型/

 6.4.4可见性/

 6.4.5寄存器/

6.5LLVM IR类型系统/

 6.5.1类型系统/

 6.5.2元数据类型/

 6.5.3属性/

6.6LLVM IR控制语句/

 6.6.1汇编语言层面的控制语句/

 6.6.2LLVM IR层面的控制语句/

6.7LLVM IR语法链接类型/

6.8LLVM IR函数/

 6.8.1定义与声明/

 6.8.2传递参数与获得返回值/

 6.8.3内置函数、属性和元数据/

6.9LLVM IR异常处理/

 6.9.1异常处理的要求/

 6.9.2LLVM IR的异常处理/

 6.9.3怎么抛/

 6.9.4怎么接/

第7章 LLVM芯片编译器实践示例/

7.1编译器基本概念/

 7.1.1LLVM的模块化编译器框架/

 7.1.2前端在干什么/

 7.1.3后端在干什么/

 7.1.4DAG下译/

 7.1.5DAG合法化/

 7.1.6小结/

7.2从无到有开发/

 7.2.1不必从头开始开发/

 7.2.2需要添加的文件类型/

 7.2.3从文件角度看整体框架/

 7.2.4从类继承与派生角度看整体框架/

7.3芯片的整体架构部分/

 7.3.1×××.h类文件/

 7.3.2×××.td类文件/

 7.3.3×××TargetMachine.cpp和×××TargetMachine.h类文件/

 7.3.4×××MCTargetDesc类文件/

 7.3.5×××baseInfo类文件/

 7.3.6×××TargetInfo类文件/

 7.3.7×××Subtarget类文件/

 7.3.8几个容易混淆的概念/

 7.3.9小结/

7.4寄存器信息/

 7.4.1×××Registerinfo.td类文件/

 7.4.2×××RegisterInfo类文件/

 7.4.3×××SERegisterinfo类文件/

7.5指令描述的.td文件/

 7.5.1×××InstrFormats.td类文件/

 7.5.2×××InstrInfo.td类文件/

 7.5.3依次定义指令/

 7.5.4定义指令的自动转换/

 7.5.5小结/

7.6指令描述的.cpp文件/

 7.6.1×××InstrInfo.cpp(.h)类文件/

 7.6.2×××SEInstrInfo.cpp(.h)类文件/

 7.6.3×××AnalyzeImmediate.cpp(.h)类文件/

第8章 LLVM编译器示例代码分析/

8.1建立编译器的基础框架/

8.2使用 LLVM 实现一个简单编译器/

 8.2.1目标/

 8.2.2词法分析/

 8.2.3语法分析/

 8.2.4LLVM IR的代码生成/

 8.2.5优化器/

 8.2.6添加JIT编译器/

 8.2.7静态单一赋值/

 8.2.8控制流/

 8.2.9用户自定义操作符/

 8.2.10可变变量/

第9章 LLVM优化示例/

9.1LLVM优化示例介绍/

 9.1.1编译器优化目标/

 9.1.2LLVM优化Pass如何工作/

 9.1.3聚集对象的标量替换/

 9.1.4公共子表达式消除/

 9.1.5全局变量优化器 /

 9.1.6指令合并器/

9.2改进优化条件/

 9.2.1偏转循环移动代码/

 9.2.2运行规范化自然循环/

 9.2.3归纳变量简化/

 9.2.4进行比特追踪死代码消除/

9.3链接时优化/

 9.3.1LTO基本概念/

 9.3.2LTO优化处理/

 9.3.3linkmap分析/

9.4Nutshell LLVM LTO/

 9.4.1ThinLTO/

 9.4.2高度并行的前端处理和初始优化/

9.5LLVM完全LTO/

 9.5.1LLVM完全LTO的目标/

 9.5.2LLD的整个执行流程/

9.6LLVM核心类简明示例/

第10章 LLVM后端实践/

10.1LLVM后端概述/

 10.1.1LLVM后端基本概念/

 10.1.2使用Cpu0作为硬件的例子/

10.2LLVM新后端初始化和软件编译/

 10.2.1新后端初始化和软件编译/

 10.2.2LLVM 代码结构/

 10.2.3Cpu0后端初始化/

 10.2.4LLVM后端结构/

 10.2.5增加 AsmPrinter/

 10.2.6增加 DAGToDAGISel/

 10.2.7增加 Prologue和Epilogue 部分代码/

 10.2.8操作数模式/

 10.2.9小结/

10.3算术和逻辑运算指令/

 10.3.1算术运算指令/

 10.3.2逻辑运算指令/

10.4生成目标文件/

 10.4.1简要说明/

 10.4.2文件新增/

 10.4.3文件修改/

 10.4.4检验成果/

10.5全局变量/

 10.5.1全局变量编译选项/

 10.5.2代码修改/

 10.5.3检验成果/

 10.5.4小结/

10.6更多数据类型/

 10.6.1实现类型/

 10.6.2代码修改/

 10.6.3检验成果/

10.7控制流/

 10.7.1控制流语句/

 10.7.2消除无用的JMP指令/

 10.7.3填充跳转延迟槽/

 10.7.4条件MOV指令/

10.8函数调用/

 10.8.1栈帧结构/

 10.8.2传入参数/

 10.8.3函数调用优化/

10.9ELF文件支持/

 10.9.1ELF文件/

 10.9.2支持反汇编/

10.10汇编/

 10.10.1栈帧管理/

 10.10.2汇编器/

 10.10.3内联汇编/

10.11使用仿真器验证编译器/

 10.11.1运行仿真器/

 10.11.2小结/

第11章 MLIR编译器/

11.1MLIR语言参考/

 11.1.1高层结构/

 11.1.2MLIR符号/

 11.1.3MLIR作用域/

 11.1.4控制流和SSACFG作用域/

 11.1.5类型系统/

 11.1.6方言类型/

11.2MLIR方言及运行分析/

 11.2.1MLIR简介/

 11.2.2常见的IR表示系统/

 11.2.3MLIR的提出/

11.3方言及运行详解/

 11.3.1方言/

 11.3.2运行结构拆分/

 11.3.3创建新的方言操作/

 11.3.4将方言加载到 MLIRContext 中/

 11.3.5定义操作/

 11.3.6创建方言流程总结(使用ODS)/

11.4MLIR 运算与算子/

 11.4.1MLIR 运算与算子概述/

 11.4.2运算类(Operation)/

 11.4.3算子类(Op)/

 11.4.4MLIR OpBase.td算子类的作用/

 11.4.5MLIR 运算的构建过程/

 11.4.6MLIR TableGen后端生成算子代码/

11.5MLIR的缘起/

11.6MLIR部署/

 11.6.1MLIR部署流程/

 11.6.2MLIR应用/

11.7MLIR介绍/

11.8MLIR基本数据结构/

 11.8.1MLIR源代码目录/

 11.8.2MLIR简易UML类图/

 11.8.3开发中用到的具体数据结构/

11.9MLIR的出现背景与提供的解决方案/

 11.9.1概述/

 11.9.2解决方案/

11.10机器学习编译器:MLIR方言体系/

 11.10.1基础组件/

 11.10.2方言体系/

参考文献/


前言/序言
LLVM(Low Level Virtual Machine)是架构编译器的框架系统,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)及空闲时间(idle-time),对开发者开放,并兼容已有脚本。
LLVM用C++编写而成,能够进行程序语言的编译器优化、链接优化、在线编译优化、代码生成。简单来说,LLVM是一个模块化的编译器,可以根据需要选择不同组件以满足各自需求。与之形成鲜明对比的是GCC。虽然GCC的功能也很强大,但是它把所有功能都集成在包里,不能独自拆解出来。举个例子,假设需要一个代码静态检查工具,对于GCC,就要把整个GCC包都包括进来,这样包就大多了;而对于LLVM,只需要其中一个代码静态检查组件,可想而知,包就小多了。
构造一个编译器是一项复杂的任务。LLVM项目为编译器提供可重用组件。LLVM核心库实现了一个优化代码生成器,并为所有流行的硬件设备提供了一种与源语言无关的机器代码中间表示形式。
LLVM是一个庞大且复杂的AI编译器框架系统。关于本书,作者有以下几点想法:
1)LLVM非常重要。在多年的工作中,作者深感LLVM的重要性。LLVM几乎完全取代了传统GCC编译器。在AI芯片、自动计算、手机等领域的产品开发中,它是关键模块,也是这些产品开发优化的核心模块。
2)LLVM涉及的知识点非常多。LLVM涉及的知识点太多了,需要技术人员具有深厚的理论基础与丰富的实践经验。LLVM涉及的知识点包括芯片、接口、通信、底层驱动、操作系统、系统软件、应用软件、AI算法、算子理论、AI框架、汇编预言、C/C++/Python语言等。
3)入门学习与动手开发。本书描述了如何学习LLVM知识点,以及如何动手开发,并提供了多个典型开发示例。
本书包含11章,主要内容总结如下。
1)LLVM安装与编译环境配置,以及LLVM外部依赖的相关软件工具的介绍。
2)LLVM的前端Clang的基本原理与开发实践。
3)LLVM IR的基本原理与开发实践。
4)LLVM后端的关键技术与开发示例、LLVM芯片编译器实践示例、LLVM优化示例、LLVM 后端实践。
5)基于LLVM派生的算子开发框架的原理与开发示例,以及MLIR编译器等。
在本书写作过程中,得到了家人的全力支持,在此,对他们表示深深的感谢。感谢机械工业出版社的编辑,因为他们的辛勤劳作和付出,本书才得以顺利出版。由于作者能力有限,书中难免存在纰漏,还望广大读者不吝赐教。

吴建明

📑 章节目录

  1. 编译和安装LLVM
  2. LLVM外部项目
  3. LLVM编译器
  4. Clang前端基础
  5. Clang架构与实践示例
  6. LLVM IR实践
  7. LLVM芯片编译器实践示例
  8. LLVM编译器示例代码分析
  9. LLVM优化示例
  10. LLVM后端实践
  11. MLIR编译器