0

我正在调试一个 LLVM 目标后端,并且我正在寻找一个问题,即某个基本块最终会跳转到“无”,即在函数结束之后,在打开优化的情况下进行编译。

我注意到的一件事是,在指令选择之后,机器基本块有一个后继但没有实际跳转到那里的指令:

BB#1: derived from LLVM BB %switch.lookup
    Predecessors according to CFG: BB#0
        %vreg5<def> = SEXT %vreg2, %SREG<imp-def,dead>; DLDREGS:%vreg5 GPR8:%vreg2
        %vreg6<def,tied1> = ANDIWRdK %vreg5<tied0>, -2, %SREG<imp-def,dead>; DLDREGS:%vreg6,%vreg5
        %vreg7<def> = LDIWRdK 4; DLDREGS:%vreg7
        %vreg8<def> = LDIRdK 0; LD8:%vreg8
        %vreg9<def> = LDIRdK 1; LD8:%vreg9
        CPWRdRr %vreg6<kill>, %vreg7<kill>, %SREG<imp-def>; DLDREGS:%vreg6,%vreg7
        %vreg0<def> = Select8 %vreg9<kill>, %vreg8<kill>, 1, %SREG<imp-use>; GPR8:%vreg0 LD8:%vreg9,%vreg8
    Successors according to CFG: BB#2(?%)

我从 x86 LLVM 后端看到了类似的 ISel 结果,并且最终结果没有跳转到虚无,所以我认为这本身不是问题:

BB#1: derived from LLVM BB %switch.lookup
    Predecessors according to CFG: BB#0
        %vreg7<def> = MOVSX32rr8 %vreg3; GR32:%vreg7 GR8:%vreg3
        %vreg8<def,tied1> = AND32ri %vreg7<tied0>, 65534, %EFLAGS<imp-def,dead>; GR32:%vreg8,%vreg7
        %vreg9<def,tied1> = SUB32ri8 %vreg8<tied0>, 4, %EFLAGS<imp-def>; GR32:%vreg9,%vreg8
        %vreg0<def> = SETNEr %EFLAGS<imp-use>; GR8:%vreg0
    Successors according to CFG: BB#2(?%)

所以我的问题是:这些 CFG 指定的继任者应该通过什么机制变成真正的跳跃?x86 后端是否实现了一些特殊的功能,而我正在调试的后端却没有?

我应该将我的ISelLowering班级更改Select8为以显式跳转结束的东西,还是不必要的(可能甚至可能不利于某些优化的启动)并且我需要做一些其他的魔法才能正确降低这些隐式继任者?

4

1 回答 1

1

MachineBasicBlock 落入下一个 Block 是完全有效的

这是有效的。AnalyzeBranch只有在相关的目标钩子 ( Insert/ Remove) 允许的情况下,想要重新排序基本块的通道才应该这样做。

于 2017-06-05T03:48:15.087 回答