该系列笔记是我对之前学过的 Tutorial LLVM Backend Cpu0 教程的填充完善与版本升级,首发于我的知乎专栏:https://www.zhihu.com/column/c_1250484713606819840
这是本教程的序言章节,其他章节请访问最后一节中链接访问。
本笔记对应的源码文件链接:https://github.com/P2Tree/LLVM_for_cpu0
已经上传大部分内容,剩余章节正在编写中。
序
0.1 动机
编译器是一个很复杂的软件系统,在这个系统中,包含的计算机理论非常之多,也和很多数学理论有直接关系。在学校学习编译原理课程中,大多只会讲解一些编译器前端的知识,既抽象、又过于理论化,让很多同学学习起来云里雾里,最后也不清楚编译原理是干什么的,对于实际工作中使用编译器、开发编译器或利用编译器原理完成相关工作来说,会感觉书到用时方恨少。
然而,当遇到实践问题时,只拿着编译原理教材,却依然不知道该怎么做,编译原理的复杂性,使理论和实践之间的鸿沟过宽。而不同的编译器工程师可能面对相关性不大的工作内容,有面向前端的、有面向后端的,也有专门做优化的,具体展开又有很多细分。
一部分商用编译器的代码是开源的,比如gcc 和 clang/LLVM,如果拿商用编译器的代码来学习,但没有掌握学习方法,会感觉跳入泥潭,花费很大精力和时间却无法快速上手。商用编译器的文档和教程非常少,对于国内开发者来说,还有英文阅读水平的阻碍,经常需要一边阅读英文文档,一边翻译编译原理教材,正所谓,每句话都能看懂,连起来还是没弄清什么道理,学习难度也很大。
LLVM 是一套编译器架构,它的设计非常灵活和清晰,相比 gcc 来说,学习会更容易一些。另一个原因是,LLVM 的开源协议(BSD)比较友好,通常是指基于 LLVM 来开发的编译器可以闭源自己的代码,而 gcc 是 GPL 协议,要求必须开源,商业化来讲,LLVM 更有优势。还有个优势是,LLVM 的可重用性强,即使不做编译器,也可以把其中一部分拿出来用在自己的软件中,比如静态分析,或自定义的 DSL 等。
我在学习 LLVM 的过程中,也苦于找不到适合初学者的学习材料,硬着头皮把 LLVM 官网上的几篇超级长的文章读完,并翻译了一部分。然而却发现官方文档很多也不全面,这让我意识到,我该写写代码了 (工作中也会改代码,但不会涉及整个模块重写的需求)。偶然中我遇到了一个教程,由台湾的陳鍾樞(https://github.com/Jonathan2251)编写的《Tutorial: Creating an LLVM Backend for the Cpu0 Architecture》,如获至宝。学习完毕后,颇有收获。书中讲解地非常细致,虽然并没有涉及很复杂的功能,但我认为作为入门材料足矣。
之后,我便有一个想法,LLVM 的中文学习材料中,还没有这样一个 Tutorial,能带着不熟悉 LLVM 后端的朋友一步步入门,为什么我不可以写一个呢?他的教程基于 LLVM 3.1 完成,虽然 3.1 是挺经典的一个版本,但现在都已经 10.0 了,我也刚好可