编译原理实战课
宫文学
北京物演科技CEO
立即订阅
2831 人已学习
课程目录
已更新 27 讲 / 共 53 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | 在真实世界的编译器中游历
免费
学习指南 | 如何学习这门编译原理实战课?
预备知识篇 (9讲)
01 | 编译的全过程都悄悄做了哪些事情?
02 | 词法分析:用两种方式构造有限自动机
03 | 语法分析:两个基本功和两种算法思路
04 | 语义分析:让程序符合语义规则
05 | 运行时机制:程序如何运行,你有发言权
06 | 中间代码:不是只有一副面孔
07 | 代码优化:跟编译器做朋友,让你的代码飞起来
08 | 代码生成:如何实现机器相关的优化?
知识地图 | 一起来复习编译技术核心概念与算法
不定期加餐 (1讲)
不定期加餐1 | 远程办公,需要你我具备什么样的素质?
真实编译器解析篇 (15讲)
09 | Java编译器(一):手写的编译器有什么优势?
10 | Java编译器(二):语法分析之后,还要做些什么?
11 | Java编译器(三):属性分析和数据流分析
12 | Java编译器(四):去除语法糖和生成字节码
13 | Java JIT编译器(一):动手修改Graal编译器
14 | Java JIT编译器(二):Sea of Nodes为何如此强大?
15 | Java JIT编译器(三):探究内联和逃逸分析的算法原理
16 | Java JIT编译器(四):Graal的后端是如何工作的?
17 | Python编译器(一):如何用工具生成编译器?
18 | Python编译器(二):从AST到字节码
19 | Python编译器(三):运行时机制
20 | JavaScript编译器(一):V8的解析和编译过程
21 | JavaScript编译器(二):V8的解释器和优化编译器
22 | Julia编译器(一):如何让动态语言性能很高?
23 | Julia编译器(二):如何利用LLVM的优化和后端功能?
编译原理实战课
15
15
1.0x
00:00/00:00
登录|注册

08 | 代码生成:如何实现机器相关的优化?

宫文学 2020-06-17
你好,我是宫文学。我们继续来学习编译器后端的技术。
在编译过程的前几个阶段之后,编译器生成了 AST,完成了语义检查,并基于 IR 运行了各种优化算法。这些工作,基本上都是机器无关的。但编译的最后一步,也就是生成目标代码,则必须是跟特定 CPU 架构相关的。
这就是编译器的后端。不过,后端不只是简单地生成目标代码,它还要完成与机器相关的一些优化工作,确保生成的目标代码的性能最高。
这一讲,我就从机器相关的优化入手,带你看看编译器是如何通过指令选择、寄存器分配、指令排序和基于机器代码的优化等步骤,完成整个代码生成的任务的。
首先,我们来看看编译器后端的任务:生成针对不同架构的目标代码。

生成针对不同 CPU 的目标代码

我们已经知道,编译器的后端要把 IR 翻译成目标代码,那么要生成的目标代码是什么样子的呢?
我以 foo.c 函数为例:
int foo(int a, int b){
return a + b + 10;
}
执行“clang -S foo.c -o foo.x86.s”命令,你可以得到对应的 x86 架构下的汇编代码(为了便于你理解,我进行了简化):
#序曲
pushq %rbp
movq %rsp, %rbp #%rbp是栈底指针
#函数体
movl %edi, -4(%rbp) #把第1个参数写到栈里第一个位置(偏移量为4)
movl %esi, -8(%rbp) #把第2个参数写到栈里第二个位置(偏移量为8)
movl -4(%rbp), %eax #把第1个参数写到%eax寄存器
addl -8(%rbp), %eax #把第2个参数加到%eax
addl $10, %eax #把立即数10加到%eax,%eax同时是放返回值的地方
#尾声
popq %rbp
retq
小提示:上述汇编代码采用的是 GNU 汇编器的代码格式,源操作数在前面,目的操作数在后面。
我在第 1 讲中说过,要翻译成目标代码,编译器必须要先懂得目标代码,就像做汉译英一样,我们必须要懂得英语。可是,通常情况下,我们会对汇编代码比较畏惧,觉得汇编语言似乎很难学。其实不然。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《编译原理实战课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(2)

  • 阿木
    老师,我用clang -target armv7a-none-eabi 想交叉编译生成一个打印hello world的程序,老是报错,找不到头文件,请问在mac上还需要配置什么吗

    作者回复: 看看这篇文档对你有没有用:https://clang.llvm.org/docs/CrossCompilation.html

    我的习惯,是在本机自行编译一下LLVM,里面也带了clang等工程。这有几个好处:
    首先,可以拥有一个debug版本的LLVM,方便用一些针对开发者的工具和参数。
    第二,可以选择合适的LLVM/Clang版本。
    第三,可以不依赖本机原来带的clang,所有的配置,包括头文件什么的,都用自己的这一套。

    2020-06-27
    1
  • 蹦哒
    老师请问:
    1.iOS中OC语言的内存管理采用引用计数管理,编译器会给对象调用retain或release方法来增加或者减少引用计数,这个过程是在编译器哪个阶段进行的呢?是在代码优化或者代码生成阶段,由LLVM完成的吗
    2.JavaScript的垃圾回收,应该就不属于编译器的职责范围了吧?应该是运行之后单独的垃圾回收程序来负责垃圾回收了吧
    2020-07-22
收起评论
2
返回
顶部