本书以任务驱动的方式,带领读者编写基于LLVM 的编译器前端、优化器、后端。通过丰富的实例,
读者能够从中理解LLVM 的架构,以及如何使用LLVM 来编写自己的编译器。
相比于传统的介绍编译技术的书籍,此书更偏向于实战,因此适合熟悉编译但对LLVM 比较陌生的
人员,也适合正在学习编译技术并且在寻找实战机会的人员。
首部LLVM书籍!精准答疑高频问题 构建基于LLVM的编译器前端、优化器和代码生成器
译者序
LLVM 这个名字源于Lower Level Virtual Machine,但这个项目并不局限于创建一个虚拟机,它已经发展成为当今炙手可热的编译器基础框架。LLVM 最初以C/C++为编译目标,近年来经过众多机构和开源社区的努力,LLVM 已经能够为ActionScript、D、Fortran、Haskell、Java、Objective-C、Swift、Python、Ruby、Rust、Scala 等众多语言提供编译支持,而一些新兴语言则直接采用了LLVM 作为后端。可以说,LLVM 对编译器领域的发展起到了举足轻重的作用。
本书是目前为数不多的介绍LLVM 的书籍。本书从LLVM 的构建与安装开始说起,介绍了LLVM 的设计思想、LLVM 工具链、前端、优化器、后端,涵盖了LLVM 的绝大部分内容。本书以任务驱动的方式对内容进行介绍,围绕着实现TOY 语言的编译器,每一章节都会带领读者编写代码。在第2 章实现了编译器的前端,第4、5 章逐步实现优化器,后面的章节则实现了编译器后端。书中以实践的方式进行讲述,既阐述了原理,又让读者参与到编译器的开发当中,这一方面降低了学习LLVM 的门槛,另一方面也让读者在实践中理解LLVM 的细节。
作为译者,我觉得能够翻译此书也是一种缘分。最初是因为一次偶然的机会,我接触了一些自然语言处理的内容,在此过程中我领悟了词法分析和语法分析是怎么一回事;之后凭借着自己先前了解的零零碎碎的知识,在没有系统学习过编译原理的情况下写出了自己的第一个解释器(当然它很不完备);接着便去系统学习编译原理,由于有了一定的实践基础,理解那些概念也轻松了许多;而关于这本书的翻译,则是因为在豆瓣上看到了一位豆友转发的消息,遂联系出版社的张春雨老师;最后在翻译此书的过程中,也收获了很多。
所以在这里要感谢带我走近自然语言处理的那位朋友,要感谢转发此消息的那位豆友,还要感谢博文视点的张春雨老师。人生充满了机缘巧合,我很幸运能够遇见你们。
与此同时,我也希望此书能够揭开编译器的面纱,能够让国内更多的人了解编译技术。
王欢明
2015 年8 月
前言
程序员在编程时没有一刻可以离开编译器。简单来说,所谓编译器就是把人类可读的高级语言映射到机器执行码。但你知道这里面发生了什么吗?编译器在生成优化过的机器码之前还做了很多处理工作,一个好的编译器包含了很多复杂的算法。
这本书介绍了编译的几个阶段:前端处理、代码优化、代码生成等。为了将这个复杂的过程简化,LLVM 使用了模块化的思想,使得每一个编译阶段都被独立出来;LLVM 使用面向对象的C++语言完成,为编译器开发人员提供了易用而丰富的编程接口和API。所以,LLVM 可能是最容易学习的编译器框架了。
作为作者,我们认为简单的解决方案往往会比复杂的解决方案更加奏效;通过这本书,我们将会了解许多编译技术,它能提升你的能力,让你了解编译选项,理解编译过程。
我们也相信,那些从事编译器开发的程序员会从本书收益良多,因为对编译器技术的了解会帮助他们写出更好的代码。
我们希望你能喜欢这本书,享受这本书提供的技术盛宴,也能开发自己的编译器。迫不及待了吗?让我们开始吧。
本书概述
第1 章:LLVM 设计与使用。本章介绍了模块化的LLVM 基础架构设计,让你学会如何下载安装LLVM 和Clang,通过一些例子来了解如何使用LLVM 工作,也会介绍一些其他的编译器前端。
第2 章:实现编译器前端。本章介绍了如何为一门编程语言编写一个编译器前端,我们通过为一门玩具语言写一个玩具编译器,来了解如何把前端语言映射到LLVM IR。
第3 章:扩展前端并增加JIT 支持。本章为这门玩具语言增加了一些现代语言的高级特性,以及对前端的JIT 支持。
第4 章:准备优化。本章介绍LLVM IR 的Pass 结构,以及不同的优化级别和每一级别上的优化技术。我们也将看到如何一步一步编写自己的LLVM Pass。
第5 章:实现优化。本章介绍如何在LLVM IR 上实施诸多优化Pass,以及在LLVM开源代码上实现一些向量化技术。
第6 章:平台无关代码生成器。本章介绍了一个平台无关代码生成器的抽象结构,如何把LLVM IR 转换到有向无环图(DAG),以及如何进一步生成目标平台机器码。
第7 章:机器码优化。本章介绍了DAG 的优化过程,目标寄存器分配算法,还介绍了Selection DAG 上的各种优化技术及不同寄存器的分配技术。
第8 章:实现LLVM 后端。本章介绍了目标架构,包括寄存器、指令集、调用约定、编码、子平台特性等。
第9 章:LLVM项目最佳实践。本章介绍了一些使用LLVM IR 做代码分析的其他项目。
需要记住的是,LLVM 不仅仅是一个编译器,而且是一个编译器框架。本章介绍了一段可应用到各种项目的代码,可从中获取有用信息。
阅读背景
你只需要一台Linux 计算机,最好是Ubuntu 系统,就能完成本书的大部分例子。你也需要一个简单的文本或代码编辑器、网络连接,以及一个浏览器。我们建议安装两个文件的合并包,它在大部分Linux 平台都能运行。
读者对象
本书适合那些熟悉编译器概念并且想理解学习LLVM 的程序员。
本书也适合不直接参与编译器开发但参与大量代码开发的程序员。具备一定的编译器知识将会使你写出更加优秀的代码。
内容组织
在此书中你会频繁地看到一些标题,例如准备工作、详细步骤、工作原理、更多内容、
另请参阅。
为了更好地呈现本书内容,我们采用了如下的组织方式。
准备工作
这部分对章节做了概述,并且描述了如何配置软件及其他工具。
详细步骤
这部分涵盖了具体的实践步骤。
工作原理
这部分涵盖了前一部分的详细解释。
更多内容
这部分涵盖了关于章节的更多信息。
另请参阅
这部分涵盖了参考资料的链接。
约定
在本书中你会发现大量用不同格式展示的文字,这里举例说明它们的涵义。
嵌入代码、数据库表名、目录名、文件名、文件扩展名、路径名、URL、用户输入、Twitter 用如下方式展示:“我们可以用include 指令引入其他的上下文。”
代码块用如下格式:
primary := identifier_expr :
=numeric_expr
:=paran_expr
当我们想强调部分代码块时,相关行会使用粗体:
primary := identifier_expr
:=numeric_expr
:=paran_expr
命令行输入和输出用如下格式:
$ cat testfile.ll
新的术语和重要单词也会用黑体显示。你在屏幕上看到的内容,包括对话框或菜单,会这样显示:“单击下一步将进入下一屏”。
警告或者重要内容会在这块展示一些提示和技巧。
下载示例代码
你可以从http://www.broadview.com.cn 下载所有已购买的博文视点书籍的示例代码文件。
勘误表
虽然我们已经尽力谨慎地确保内容的准确性,但错误仍然存在。如果你发现了书中的错误,包括正文和代码中的错误,请告诉我们,我们会非常感激。这样,你不仅帮助了其他读者,也帮助我们改进后续的出版。如发现任何勘误,可以在博文视点网站相应图书的页面提交勘误信息。一旦你找到的错误被证实,你提交的信息就会被接受,我们的网站也会发布这些勘误信息。你可以随时浏览图书页面,查看已发布的勘误信息。
关于LLVM IR的更多信息,应参见https://llvm.org/docs/LangReg.html
改为:
https://llvm.org/docs/LangRef.html