08 | 代码生成:如何实现机器相关的优化?
该思维导图由 AI 生成,仅供参考
生成针对不同 CPU 的目标代码
- 深入了解
- 翻译
- 解释
- 总结
编译器后端的关键任务是生成针对不同CPU架构的目标代码。在这一过程中,编译器通过指令选择、寄存器分配、指令排序和基于机器代码的优化等步骤,完成代码生成的任务。指令选择的作用是选择代价更低的指令组合来完成相同功能,例如使用lea指令代替多条mov和add指令。寄存器分配则通过算法将寄存器分配给使用最频繁的变量,以提高性能。指令排序利用流水线技术实现指令级并行,减少总的执行时间。这些优化措施都旨在充分发挥硬件性能,确保生成的目标代码性能最高。文章还提到了不同的算法和技术,如树覆盖算法、寄存器染色算法和基于数据依赖图的List Scheduling算法,用于实现指令选择、寄存器分配和指令排序。这些技术和算法对编译器后端的性能提升起着重要作用。文章还介绍了窥孔优化的思路,调用约定对目标代码生成的影响,以及后端处理的整体过程。总的来说,本文深入介绍了编译器后端的工作原理和优化技术,对于想深入了解编译器技术的读者具有重要参考价值。
《编译原理实战课》,新⼈⾸单¥59
全部留言(7)
- 最新
- 精选
- 蹦哒老师请问: 1.iOS中OC语言的内存管理采用引用计数管理,编译器会给对象调用retain或release方法来增加或者减少引用计数,这个过程是在编译器哪个阶段进行的呢?是在代码优化或者代码生成阶段,由LLVM完成的吗 2.JavaScript的垃圾回收,应该就不属于编译器的职责范围了吧?应该是运行之后单独的垃圾回收程序来负责垃圾回收了吧
作者回复: 我在32讲,重点讲了编译器和垃圾回收的关系。 总的来说,垃圾回收属于运行时机制。但垃圾回收机制的运行,需要编译器的支持。比如,在合适的时候(安全点)停下程序的运行,去垃圾回收机制去运行,这就需要编译器生成这样的代码,去和gc做协调。 另外,通常,编译器还要告诉gc,gc root(包括全局变量、本地变量、存放在寄存器中的变量等)都是哪些,便于垃圾收集机制的运行。 为了配合一些特定的垃圾收集算法,编译器还要插入一些其他的代码,比如读写屏障。 对于采用引用计数方法的gc,就更需要编译器的配合。编译器要插入相应的代码(机器码),增减引用计数。在引用计数为零的时候,还要调用回收内存的代码。
2020-07-2232 - 阿木老师,我用clang -target armv7a-none-eabi 想交叉编译生成一个打印hello world的程序,老是报错,找不到头文件,请问在mac上还需要配置什么吗
作者回复: 看看这篇文档对你有没有用:https://clang.llvm.org/docs/CrossCompilation.html 我的习惯,是在本机自行编译一下LLVM,里面也带了clang等工程。这有几个好处: 首先,可以拥有一个debug版本的LLVM,方便用一些针对开发者的工具和参数。 第二,可以选择合适的LLVM/Clang版本。 第三,可以不依赖本机原来带的clang,所有的配置,包括头文件什么的,都用自己的这一套。
2020-06-272 - 风请教一下,为什么特别地以-O2为例介绍优化后的代码,是有什么典型性吗
作者回复: -O1、-O2什么的,代表不同的优化深度。优化越多,编译时间越长。 你可以对比一下-O1和-O2生成的汇编代码的不同,可以加深理解。
2020-12-16 - A君循环展开可以减少count++和判断指令,另外还可以增加计算指令数,增加通过指令排序优化的机会。2022-04-23
- A君指令选择,一个IR可以生成多条指令,我们应该选择代价最小的那条指令。2022-04-23
- Self-devourer老师,关于流水线,指令并行那里有个问题想请教下。 我理解的是,每条指令虽然被拆分多个阶段,但一条指令的所有阶段还是由一个功能单元去执行。 假设指令间没有依赖性,那为什么会出现错位的情况,不能让所有功能单元都从指令的第一个阶段开始执行呢?2022-01-13
- Laputa“因为每个时钟周期都可以开始执行一条新指令,所以虽然一条指令需要 5 个时钟周期才能执行完,但在同一个时刻,却可以有 5 条指令并行执行。” 老师,一条指令需要5时钟周期,这块的依据是什么呢,任何指令都需要5个时钟周期吗,还是说不通指令需要的时钟周期不一样呢?2021-11-30