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

24 | 中间代码:兼容不同的语言和硬件

基本块
元数据
全局变量和常量
类型系统
操作码
标识符
函数
模块
细节信息
静态单赋值代码形式
循环语句
条件语句
布尔值的计算
基本的算术运算
与汇编语言相比
与高级语言相比
一课一思
课程小结
LLVM汇编码
三地址代码(TAC)
介于中间的语言
IR

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

前几节课,我带你尝试不通过 IR,直接生成汇编代码,这是为了帮你快速破冰,建立直觉。在这个过程中,你也遇到了一些挑战,比如:
你要对生成的代码进行优化,才有可能更好地使用寄存器和内存,同时也能减少代码量;
另外,针对不同的 CPU 和操作系统,你需要调整生成汇编代码的逻辑。
这些实际体验,都进一步验证了20 讲中,IR 的作用:我们能基于 IR 对接不同语言的前端,也能对接不同的硬件架构,还能做很多的优化。
既然 IR 有这些作用,那你可能会问,IR 都是什么样子的呢?有什么特点?如何生成 IR 呢?
本节课,我就带你了解 IR 的特点,认识常见的三地址代码,学会如何把高级语言的代码翻译成 IR。然后,我还会特别介绍 LLVM 的 IR,以便后面使用 LLVM 这个工具。
首先,来看看 IR 的特征。

介于中间的语言

IR 的意思是中间表达方式,它在高级语言和汇编语言的中间,这意味着,它的特征也是处于二者之间的。
与高级语言相比,IR 丢弃了大部分高级语言的语法特征和语义特征,比如循环语句、if 语句、作用域、面向对象等等,它更像高层次的汇编语言;而相比真正的汇编语言,它又不会有那么多琐碎的、与具体硬件相关的细节。
相信你在学习汇编语言的时候,会发现汇编语言的细节特别多。比如,你要知道很多指令的名字和用法,还要记住很多不同的寄存器。在 22 讲,我提到,如果你想完整地掌握 x86-64 架构,还需要接触很多指令集,以及调用约定的细节、内存使用的细节等等(参见 Intel 的手册)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

LLVM汇编码是一种关键的中间代码表示形式,具有精确描述目标机器相关信息的特点,适用于生成高效的目标代码。文章介绍了中间代码的概念及其特点,重点讨论了三地址代码(TAC)和LLVM的IR格式。相比之下,LLVM的IR能够准确地描述与目标机器相关的具体信息,因此更适合用于生成目标代码,真正能够用于生产环境。此外,文章还详细介绍了LLVM汇编码的特点,采用静态单赋值代码形式,具有更多的细节信息,包括类型系统、全局变量和常量、元数据等。通过对LLVM汇编码的解析,读者可以了解其与传统汇编的区别,以及在代码优化方面的优势。总的来说,本文提供了全面的概览和实用信息,帮助读者了解中间代码及其特点。文章还介绍了LLVM IR的用法,通过示例代码和对应的LLVM汇编码,帮助读者更好地理解LLVM IR的特点和用法。通过本文的阅读,读者可以快速了解中间代码的技术特点,以及LLVM汇编码的应用概览,为进一步深入学习和应用提供了基础知识。

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

全部留言(8)

  • 最新
  • 精选
  • minghu6
    AST也是一种IR说得不严谨, AST显然是语义相关的, 要把AST转成类似LISP形式的树, 在这个过程中结构化地抽象掉语义, 这才算是一种IR 作者可能混淆了这两个概念.

    作者回复: 你专注了一个有意思的问题。对概念的分析,往往非常有用。概念是一切的基础。值得我认真回答一下。 对于IR的定义,有狭义和窄义两种不同的理解。 从狭义的角度,IR是在AST之后,用于做优化的数据结构,这是我们大部分场景里提到IR时候的含义。我们用狭义的定义的时候,通常字节码也不算IR,因为它已经算是目标代码了,也主要不是用于优化的目的。 从广义的角度,IR是处于源代码和目标代码之间的各种能够表示代码的数据结构。 在wikipedia中,对AST有这么一段描述: Abstract syntax trees are data structures widely used in compilers to represent the structure of program code. An AST is usually the result of the syntax analysis phase of a compiler. It often serves as an intermediate representation of the program through several stages that the compiler requires, and has a strong impact on the final output of the compiler. 这里面,就指出AST是一种“intermediate representation”。而如果你去查IR的词条,里面也会有对AST的引用,跟字节码并列。 再加深一下理解: 1.基于AST能否做优化? 是可以的。在看JDK的编译器代码的时候,就能发现很多基于AST的优化。优化是不嫌早的。而因为JDK的前端编译器只是生成字节码而已,所以很多优化都是在AST上去做。 2.IR是否可以是树状结构(甚至直接就基于AST)? 我们把IR根据抽象层次的高低,分为HIR、MIR和LIR。对于HIR来说,不少是采用树状结构的,也保留了像循环、分枝判断这样的高层次结构。 根据方舟编译器早期释放出来的代码和文档,其Maple IR就是一个树状结构的。随着优化的进程,树的节点逐步变成低级别的操作,树的高度也会降低。不过,我不知道方舟编译器最新的版本是否还会保持这个设计。我最近会问问内部相关的人员。 3.字节码算不算IR? 我的观点:广义上算,因为它毕竟是中间格式,基于字节码还可以进一步做优化,比如Web Assembly就是这个设计。运行时读入Web Assembly以后,会启动JIT的过程,在这个过程中可以做优化。 狭义上不算,因为它已经是某个虚拟机的目标代码。 4.AST能否作为目标代码? 这是另一个极端。AST通常并不用于执行程序。但是,对于特别简单的脚本语言,或者一个公式解释器,基于AST运行也无不可。 5.中间代码是否包含语义? 不同层次的IR在语义上是等价的。虽然从AST到HIR一直到LIR使用的操作是不同的,语义的抽象程度是从高到低的,但它们是等价的。不同层次的IR适合做不同的优化。

    2021-05-30
    5
    9
  • 沉淀的梦想
    对与LLVM的SSA有点不太理解,`=`和`store`指令的区别是什么呢?为什么`store`就不算赋值呢,看llvm字节码里经常`store`到同一个寄存器多次,这是不是有点违背SSA?

    作者回复: store是把寄存器的内容,写到内存中。与之对应的指令是load。 是的,涉及内存访问的时候,是可以违背SSA的。这点你看得很细。非常值得表扬!我在第26讲提到了这个知识点。你提前就发现了。

    2019-10-23
    7
  • 独钓寒江雪
    老师好,文中说,从其他基本块不可以跳转到入口基本块,也就是函数中的第一个基本块。那么,如果出现递归调用,是怎么处理的呢?

    作者回复: (我对另一个同学的回答,这里拷贝一份) 递归相当于调用另一个函数。所有的参数、本地变量,要再来一份,也就是要创建一个新的活动记录(栈帧)。 不过,对于递归调用中的尾递归,编译器是可以做优化的,也就是不用再进行一次新的函数调用,从而节省了系统资源的开销。

    2020-06-02
    2
  • ztxc
    第一行是整个基本块的唯一入口,从其他基本块跳转过来的时候,只能跳转到这个入口行,不能跳转到基本块中的其他行。 最后我要强调,从其他基本块不可以跳转到入口基本块,也就是函数中的第一个基本块。这个规定也是有利于做数据优化。 老师好,这两段不太理解。第一段是说跳转的入口基本块。第二段说不可以跳转。第二段的意思是说从本基本块内部不能跳转到本基本块的入口基本块吗?

    作者回复: 不是。 第一段的意思:每个基本块中的代码都是从第一行执行到最后一行,不可能从别的地方跳转到这个基本块中间的一行,然后再继续执行,也不可能执行到中间就跳转出去。 第二段的意思:入口基本块是CFG中的一个特殊基本块,函数开始运行时就进入这个基本块。

    2020-07-03
    1
  • coconut
    IfZ t1 Goto L1; 这个是不是不能算作tac,因为包含了ifZ、Goto两个操作
    2021-07-15
    1
  • Geek_e8d55e
    nsw 无符号环绕怎么理解呢?
    2021-05-26
  • lion_fly
    Static Single Assignment:SSA(静态单赋值) Three Address Code,:TAC(三地址代码)
    2020-12-11
  • 超越杨超越
    老师的demo,if条件语句的ir是不是写错了?看起来有些奇怪。
    2020-05-06
    2
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部