编译原理之美
宫文学
北京原点代码 CEO
46197 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
编译原理 · 期中考试周 (1讲)
编译原理之美
15
15
1.0x
00:00/00:00
登录|注册

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

Maximal Munch算法
匹配小树生成指令
瓦片
树状结构表示IR
例子:a[i] = b
实现同一种功能可以使用多种指令
生成更加优化的代码
要点
寄存器溢出
图染色算法
寄存器干扰图
寄存器共享原则
树覆盖算法
指令选择的原因
一课一思
课程小结
分配寄存器
选择正确的指令
目标代码的生成和优化

该思维导图由 AI 生成,仅供参考

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

选择正确的指令

你可能会问:我们为什么非要关注指令的选择呢?我来做个假设。
如果我们不考虑目标代码的性能,可以按照非常机械的方式翻译代码。比如,我们可以制定一个代码翻译的模板,把形如“a := b + c”的代码都翻译成下面的汇编代码:
mov b, r0 //把b装入寄存器r0
add c, r0 //把c加到r0上
mov r0, a //把r0存入a
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了目标代码生成和优化的关键问题,着重介绍了指令选择的重要性以及相关算法。指令选择不仅关乎代码性能,还涉及到选择最优指令以及寻找最佳覆盖方式的问题。文章通过具体例子和图形化展示,生动地解释了树覆盖算法的原理和应用。此外,还提及了Maximal Munch算法,强调了图形化理解和直观认知在学习指令选择时的重要性。整体而言,本文为读者提供了深入理解指令选择的机会,使其能够掌握相关技术特点并应用于实际编程中。 在寄存器分配方面,文章介绍了寄存器优化的任务和原理,以及如何使用图染色算法来确定所需的寄存器数量。此外,还详细讨论了寄存器溢出的处理方式,强调了在选择溢出变量时应考虑使用次数最少的变量,以提高程序性能。 总的来说,本文通过生动的例子和图形化展示,帮助读者建立直观理解,使其能够更好地理解指令选择和寄存器分配的实质,为进一步研究相关算法提供了基础。同时,文章还提出了思考问题的引导,鼓励读者分享其他例子,以促进技术交流和学习。 通过本文的阅读,读者可以快速了解目标代码生成和优化的关键问题,以及指令选择和寄存器分配的重要性和相关算法,为深入学习和应用相关技术奠定了基础。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理之美》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

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

    作者回复: 是。你总结得很对。编译原理要把计算机组成、数据结构、算法、操作系统,以及离散数学中的某些知识都用上。 比如,我们讲到指令选择、寄存器分配和指令排序,都是NP Complete的。这个时候,如果提前已经知道什么是NP Complete,那么马上就对这类算法有概念,也马上想到可以用什么样的方式来对待这类问题。 再比如,编译原理中很多算法都是基于树和图的,所以对这两个数据结构的理解也会有帮助。 至于计算机组成原理,跟后端技术的关联很密切。 程序运行时的环境,内存管理等内容,则跟操作系统有关。

    2019-11-01
    7
  • lion_fly
    染色算法,看起来很像数学中的四色问题

    作者回复: 有共同点。 另一个同学也说过,跟约束求解有相似性。只不过,编译器中的算法特别强调速度,所以一般不用那种通用的求解器。

    2020-12-24
  • 瓜瓜
    但是,如果所需要寄存器比实际寄存器的数量少,该怎么办呢 --------------------- 这个是不是写错了??

    作者回复: 是的,文稿写错了,刚好写反了!感谢你帮忙检查出来;-D

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

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

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

    作者回复: 后端需要更多对计算机组成等知识的理解,确实会有点挑战。 后端算法的特点也不一样,往往都是NP-Complete的,不追求最优解,次优解就挺好。这方面在思维上也要适应一下。 相对来说,前端比较纯粹。基本上把逻辑搞清楚就行了,而且肯定有最优解。 图查询?有同事用过node4j。我本人并没有深入研究过。不过,从编译原理的角度,这都是不同的应用领域。语言的部分,编译技术可以解决,它只是个接口,是个封装;落地机制部分,要运用每个领域的知识,比如关系数据库的原理、图数据库的原理。

    2019-10-30
  • Allen_Go
    感觉跟不上了,那就先过一遍,再啃几遍慢慢消化了,还是有信心拿下的。
    2022-09-11归属地:广东
    1
  • linfei
    按那个算法,能把图删空确实说明该图可以用k种颜色着色,但如果不能删空却不说明它不能用k种颜色着色。例如四个节点,按照1-2-3-4-1这样的方式连接起来,每个节点都有2条边,但它是可以用2种颜色来着色的。
    2022-07-03
  • ifelse
    每篇都能学到新知识
    2021-10-24
  • Geek_89bbab
    像 f1 := load fa 这个指令,fa也需要一个寄存器存储吧,f1也需要一个寄存器存储。它们可以共用一个寄存器。
    2020-05-06
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部