一、构造控制流图(CFG)
关于优化,真的是一个令人生畏的事情,大致来说,一个优化分为两个部分:
但是在课程中大多只交第一个部分,而不讲第二个部分,这就导致一种“无意义性”,如果分析不能用于改造程序,那么就没有什么学习的动力。所以如果想要学好理论,那么必须要有一个宏观的角度去看发生的一切事情。
按照 《Engineering a Complier》的观点,按照优化的范围去给优化分类,大致可以分为以下四类
类型 |
范围 |
举例 |
局部优化 |
限制在某个基本块中 |
公共子表达式提取,局部值编号,树高平衡,窥孔优化 |
区域性优化 |
某几个有联系的基本块 |
循环展开 |
全局优化(过程内优化) |
组成一个完整过程的基本块 |
图着色寄存器分配 |
过程间优化 |
多个过程 |
函数内联,过程间常数传递 |
至于为什么有这么多分类,是因为优化是一个很严谨而且需求具有多样性的事情,不同的范围对应的条件和限制是不一样的,那么可以进行优化的力度和策略也就是不一样的。
对于局部优化,因为它在一个基本块内,所以有两个极好的性质可以应用
- 语句是顺序执行的。
- 如果一条语句被执行,那么整个基本块的语句都会被执行。
从某种意义上讲,基本块让人们不再直面指令,而是变成面对一个数据流图。
而其他三种方法,都需要建立在对于 CFG 图上,也就是说,首先就是分析 CFG 图。另外还有一段话很有意思:
在进行区域性优化的时候,我们可以考虑通过某种图论性质定义的 CFG 子集,比如说支配图或者强联通分量。
通过一道题来介绍一下分法,不过介绍之前,还是说一下,此时的代码一定是 ir 了,但是对于课设用到的是那种 ir 呢?应该是某种神秘的四元式(这里插一嘴,llvm 也可以被认为成一种神秘四元式,即只有一小部分指令有大于 2 个的操作数)。
有三条规则:
- 程序入口第一条语句
- 任何可以被当做跳转目标的语句
- 跳转语句后面的一条语句