-break-crit-edges: Break Critical Edges in CFG

在了解这个 pass 之前需要学习的背景知识是 Critical Edges in CFG

Description

-break-crit-edges 就是通过加入一个虚假的 basic block (i.e. dummy bb),去把这个 critical edges 给打破。 如下图所示,本来 BB0 和 BB3 之间的 edge 是一个 critical edge,但是这里加入了一个 BB4。 这个 BB4 里面没有任何 functional instruction,就是单纯的跳转一下。 这样,每一个 BB 都只有一个 successor,且每一个 BB 都只有一个 predecessor。Critical edges就被打破了。

Breaking a critical edge

Breaking a critical edge (Original Link)

这样做的意义是什么呢?如果存在 critical edges 的话,这会造成 suboptimal 的 code generation,进而阻止其他的 compiler 的优化,从而影响性能。

在 LLVM 的 implementation 中, -break-crit-edges 还可以同时 update forward dominator(包括set, immediate dominator, tree, and frontier),从而保持 IR 功能上的正确性。

Code Example

原始的 IR。

define void @foo(i32 %a) {
entry:
    %cmp = icmp eq i32 %a, 0
    br i1 %cmp, label %iftrue, label %iffalse

    other:
    ; Code for the other branch
    br label %iffalse

iftrue:
    ; Code for the true branch
    br label ......

iffalse:
    ; Code for the false branch
    br label ......
}

-break-crit-edges transform 之后的 IR。

define void @foo(i32 %a) {
entry:
    %cmp = icmp eq i32 %a, 0
    br i1 %cmp, label %iftrue, label %split

split: ; I am a dummy BB, do nothing here :)
    br label %iffalse

other:
    ; Code for the other branch
    br label %ifflase

iftrue:
    ; Code for the true branch
    br label ......

iffalse:
    ; Code for the false branch
    br label ......
}

原理很简单,其实就是加入了一个 dummy BB。