【问题标题】:Optimization passes that convert conditional branches to jumps将条件分支转换为跳转的优化过程
【发布时间】:2014-09-26 19:58:27
【问题描述】:

在优化编译器中,冗余代码可以通过不同的算法多次检测和消除,例如值编号、稀疏条件常量传播等。在这种情况下,我对检测冗余分支很感兴趣。假设目标代码是

block1:
    cmp r1, r2
    jne block3

block2:
    cmp r1, r2
    je block4

block3:
    ...     
block4:
    ...     
...

在这种情况下,如果控制达到block2,则意味着r1r2 相等,因此je block4 可以替换为jmp block4。此外,如果在 block2 中改为 jne block4,那么我们可以完全删除 je

那么我的问题是,什么样的优化通道能捕捉到这种代码?我想可以扩展值编号来解决这个问题,但从未在参考书目中看到它,所以也许有更好的方法。

编辑:更正了第一次跳转,它说je block3应该说jne block3

【问题讨论】:

    标签: compiler-construction compiler-optimization


    【解决方案1】:

    好吧,假设没有从其他任何地方进入 block2 的其他分支,编译器的布尔传播应该会捕捉到这一点。当然,根据编译器的不同,还有其他各种阶段也可以做优化。

    根据 bool prop 算法,可能发生的情况是块 3 保存一个数据流值“R1!= R2”,该值将传播到它下面的所有块。块 2 将类似地具有“R1 == R2”的值,该值也将传播到后续块(根据数据流),从而消除途中的死分支。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      我不确定优化通道的名称是否完全标准化,目前我找不到我的 Muchnick 副本,但在我上次使用的编译器中,您描述的情况将在两个阶段 - 一个优化阶段会检测到二次比较是多余的,并将其删除,随后的阶段会检测到相等跳转不需要是有条件的。

      但并不是每个编译器都会进行这种优化。

      【讨论】:

        【解决方案3】:

        优化通常发生在组装之前很久,而是某种形式的中间表示。

        IR 的不同形式各不相同,但一个典型的方面是它们在无限组寄存器上运行,而不是在机器寄存器上运行,并且每个寄存器不能更改,只能初始化一次。 (如果你需要可变变量,你需要alloca堆栈上的一个指针,然后通过它load/store。优化的第一个也是最难的阶段是从基于alloca的转换为基于SSA的,所以所有其他优化,比如这个,都可以完成)

        此示例使用 LLVM IR。

        define void @func2(i32 %r1, i32 %r2) {
        block1:
          %0 = icmp ne i32 %r1, %r2
          br i1 %0, label %block3, label %block2
        
        block2:                                           ; preds = %block1
          %1 = icmp eq i32 %r1, %r2
          br i1 %1, label %block4, label %block3
        
        block3:                                           ; preds = %block2, %block1
          unreachable
        
        block4:                                           ; preds = %block2
          unreachable
        }
        

        现在应该相当直观,%1 的定义可以替换为%1 = xor i1 %1, true(这是布尔值not 的样子),然后可以将常量传播到唯一的边缘,导致block2.

        【讨论】:

          猜你喜欢
          • 2012-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-05
          • 2014-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多