我正在尝试优化编译器中的表达式评估。
算术表达式都是 C 风格的,它们可能包含变量。我希望尽可能简化表达式。
例如,(3+100*A*B+100)*3+100
可以简化为409+300*A*B
.
它主要取决于分配律、结合律和交换律。
我遇到的主要困难是如何将这些算术定律与传统的堆栈扫描评估算法结合起来。
任何人都可以在编译器构建的上下文中分享与此或类似问题相关的经验吗?
我正在尝试优化编译器中的表达式评估。
算术表达式都是 C 风格的,它们可能包含变量。我希望尽可能简化表达式。
例如,(3+100*A*B+100)*3+100
可以简化为409+300*A*B
.
它主要取决于分配律、结合律和交换律。
我遇到的主要困难是如何将这些算术定律与传统的堆栈扫描评估算法结合起来。
任何人都可以在编译器构建的上下文中分享与此或类似问题相关的经验吗?
编译器通常有一些内部规范化规则,例如“左侧常量”。这意味着a + 3
将转换为3 + a
,但反之则不然。
在您的示例中,
(3+100*A*B+100)*3+100
将标准化为
(3+100+(100*A*B))*3+100
. 现在优化很明显了3+100
。
在和是常数的条件下,可能会发生另一种转换a*C1+C2
。直观地说,这将“在乘法之前加法”标准化。(a+(C2/C1))*C1
C1
C2
这些规范化不是优化。目的主要是将常量组合在一起,因此常量折叠更有效。
在编译的代码生成过程中应用常量折叠和强度降低。大多数编译器文本将提供一种算法来实现这一点。