编译原理之美
宫文学
北京物演科技CEO
立即订阅
8171 人已学习
课程目录
已完结 43 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 为什么你要学习编译原理?
免费
实现一门脚本语言 · 原理篇 (13讲)
01 | 理解代码:编译器的前端技术
02 | 正则文法和有限自动机:纯手工打造词法分析器
03 | 语法分析(一):纯手工打造公式计算器
04 | 语法分析(二):解决二元表达式中的难点
05 | 语法分析(三):实现一门简单的脚本语言
06 | 编译器前端工具(一):用Antlr生成词法、语法分析器
07 | 编译器前端工具(二):用Antlr重构脚本语言
08 | 作用域和生存期:实现块作用域和函数
09 | 面向对象:实现数据和方法的封装
10 | 闭包: 理解了原理,它就不反直觉了
11 | 语义分析(上):如何建立一个完善的类型系统?
12 | 语义分析(下):如何做上下文相关情况的处理?
13 | 继承和多态:面向对象运行期的动态特性
实现一门脚本语言 · 应用篇 (2讲)
14 | 前端技术应用(一):如何透明地支持数据库分库分表?
15 | 前端技术应用(二):如何设计一个报表工具?
实现一门脚本语言 · 算法篇 (3讲)
16 | NFA和DFA:如何自己实现一个正则表达式工具?
17 | First和Follow集合:用LL算法推演一个实例
18 | 移进和规约:用LR算法推演一个实例
实现一门脚本语言 · 热点答疑与用户故事 (2讲)
19 | 案例总结与热点问题答疑:对于左递归的语法,为什么我的推导不是左递归的?
用户故事 | 因为热爱,所以坚持
编译原理 · 期中考试周 (1讲)
期中考试 | 来赴一场100分的约定吧!
免费
实现一门编译型语言 · 原理篇 (12讲)
20 | 高效运行:编译器的后端技术
21 | 运行时机制:突破现象看本质,透过语法看运行时
22 | 生成汇编代码(一):汇编语言其实不难学
加餐 | 汇编代码编程与栈帧管理
23 | 生成汇编代码(二):把脚本编译成可执行文件
24 | 中间代码:兼容不同的语言和硬件
25 | 后端技术的重用:LLVM不仅仅让你高效
26 | 生成IR:实现静态编译的语言
27 | 代码优化:为什么你的代码比他的更高效?
28 | 数据流分析:你写的程序,它更懂
29 | 目标代码的生成和优化(一):如何适应各种硬件架构?
30 | 目标代码的生成和优化(二):如何适应各种硬件架构?
实现一门编译型语言 · 应用篇 (2讲)
31 | 内存计算:对海量数据做计算,到底可以有多快?
32 | 字节码生成:为什么Spring技术很强大?
实现一门编译型语言 · 扩展篇 (3讲)
33 | 垃圾收集:能否不停下整个世界?
34 | 运行时优化:即时编译的原理和作用
35 | 案例总结与热点问题答疑:后端部分真的比前端部分难吗?
面向未来的编程语言 (3讲)
36 | 当前技术的发展趋势以及其对编译技术的影响
37 | 云编程:云计算会如何改变编程模式?
38 | 元编程:一边写程序,一边写语言
结束语 (1讲)
结束语 | 用程序语言,推动这个世界的演化
编译原理之美
登录|注册

29 | 目标代码的生成和优化(一):如何适应各种硬件架构?

宫文学 2019-10-30
在编译器的后端,我们要能够针对不同的计算机硬件,生成优化的代码。在23 讲,我曾带你试着生成过汇编代码,但当时生成汇编代码的逻辑是比较幼稚的,一个正式的编译器后端,代码生成部分需要考虑得更加严密才可以。
那么具体要考虑哪些问题呢?其实主要有三点:
指令的选择。同样一个功能,可以用不同的指令或指令序列来完成,而我们需要选择比较优化的方案。
寄存器分配。每款 CPU 的寄存器都是有限的,我们要有效地利用它。
指令重排序。计算执行的次序会影响所生成的代码的效率。在不影响运行结果的情况下,我们要通过代码重排序获得更高的效率。
我会用两节课的时间,带你对这三点问题建立直观认识,然后,我还会介绍 LLVM 的实现策略。这样一来,你会对目标代码的生成,建立比较清晰的顶层认知,甚至可以尝试去实现自己的算法。
接下来,我们针对第一个问题,聊一聊为什么需要选择指令,以及如何选择指令。

选择正确的指令

你可能会问:我们为什么非要关注指令的选择呢?我来做个假设。
如果我们不考虑目标代码的性能,可以按照非常机械的方式翻译代码。比如,我们可以制定一个代码翻译的模板,把形如“a := b + c”的代码都翻译成下面的汇编代码:
mov b, r0 //把b装入寄存器r0
add c, r0 //把c加到r0上
mov r0, a //把r0存入a
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《编译原理之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(3)

  • 写点啥呢
    请问老师,对于需要通过栈保存寄存器溢出的变量,在使用的时候是不是还是要占用一个寄存器呀?比如文章中的最后例子,硬件是3个寄存器约束,溢出一个变量作为临时变量,但是后段代码生成的时候,是不是其实还是需要4个寄存器(load/save指令都需要一个寄存器的)?

    作者回复: 不是的。
    对于溢出到内存里的变量,在读(load)和写(store)的时候,确实要使用一个寄存器。但是使用的时间很短。所以你看看我配的图,之前很多个集合里都有f。溢出到内存以后,含有f1、f2、f3、f4的集合,反而少了。这就导致再次分配寄存器的时候,3个就够了。文稿里有这个推导过程,你仔细看一下。

    2019-11-05
  • 沉淀的梦想
    最近几讲有种在学《算法导论》的感觉,感觉学编译原理真的能够帮助我们贯通整个计算机科学,涉及到的东西好多

    作者回复: 是。你总结得很对。编译原理要把计算机组成、数据结构、算法、操作系统,以及离散数学中的某些知识都用上。

    比如,我们讲到指令选择、寄存器分配和指令排序,都是NP Complete的。这个时候,如果提前已经知道什么是NP Complete,那么马上就对这类算法有概念,也马上想到可以用什么样的方式来对待这类问题。

    再比如,编译原理中很多算法都是基于树和图的,所以对这两个数据结构的理解也会有帮助。

    至于计算机组成原理,跟后端技术的关联很密切。

    程序运行时的环境,内存管理等内容,则跟操作系统有关。

    2019-11-01
  • 💪😊
    老师,已经跟不上了… 还是好希望我们最后有没有类似研究一下实现一下图查询的sql,如gsql标准。或者js2019的开源大佬的实现类的成果

    作者回复: 后端需要更多对计算机组成等知识的理解,确实会有点挑战。
    后端算法的特点也不一样,往往都是NP-Complete的,不追求最优解,次优解就挺好。这方面在思维上也要适应一下。

    相对来说,前端比较纯粹。基本上把逻辑搞清楚就行了,而且肯定有最优解。

    图查询?有同事用过node4j。我本人并没有深入研究过。不过,从编译原理的角度,这都是不同的应用领域。语言的部分,编译技术可以解决,它只是个接口,是个封装;落地机制部分,要运用每个领域的知识,比如关系数据库的原理、图数据库的原理。

    2019-10-30
收起评论
3
返回
顶部