常量传播/常量折叠
常量传播/常量折叠的目的在于发掘代码中可能存在的常量,尽量用对常量的引用替代对虚拟寄存器的引用(虚拟寄存器和变量是同一个概念,以下都使用变量),并尽量计算出可以计算的常量表达式。
常量传播通常依赖Use-Def和Def-Use数据流分析(这里有一个参考资料),这个数据流分析可以帮我们找到每个指令用到的变量是在哪里定义的。
例如,对于如下代码:
_main:
_T0 = 2
_T1 = 0
_T2 = _T0 + 3
_T3 = _T1 + 5
_T4 = _T2 * 2
_T5 = _T3 - _T1
_T6 = _T4 + _T5
ret _T6
经过常量传播/常量折叠优化后,代码变为:
_main:
_T0 = 2
_T1 = 0
_T2 = 5
_T3 = 5
_T4 = 10
_T5 = 5
_T6 = 15
ret _T6
常量传播/常量折叠的实现
常量传播/常量折叠的实现依赖于数据流分析,一种可能的实现方法如下:
遍历所有语句,找出常量定义,将其全部加入常量表。例如:
_T0 = 2 _T1 = 0 _T2 = _T0 + 3
_T0和_T1的值是常量,将_T0和_T1的值分别存入常量表。
依据Def-Use关系,找出所有用到常量_T0和_T1的地方,如果这些地方计算的结果也是常量,则将计算结果也加入常量表。上述代码中,_T2的值为5,也是一个常量,将_T2的值加入常量表。
重复上述过程,直到常量表不再增加为止。