[llvm-dev] Update control flow graph when splitting a machine basic block?
Friedman, Eli via llvm-dev
llvm-dev at lists.llvm.org
Mon Nov 13 12:37:22 PST 2017
On 11/11/2017 12:20 AM, 章明 wrote:
> Thank you for your reply!
>> Every MachineBasicBlock has a list of successors; you can access it with
>> the successors() accessor. That's what you should be using for any CFG
> I am aware of these methods of class MachineBasicBlock, which allows one to access a MachineBasicBlock's successors and predecessors in the CFG.
> But the CFG itself may no longer be valid if a MachineBasicBlock is split between two control flow instructions.
> The accessors of class MachineBasicBlock do not automatically update the CFG.
> So there is no way to access the up-to-date CFG.
>> I don't think this actually has any impact in practice; I mean, I guess
>> it's an issue in theory, but in practice we don't stick branches into
>> the middle of basic blocks.
> I did not expect a branch in the middle of a basic block either, until yesterday LLVM Release 4.0.0 produced the following machine basic block before the pass ARMConstantIslands is run:
> successors: %bb.3.for.body(0x80000000)
> liveins: %r4
> %r0 = tMOVr %r4, 14, _, debug-location !23
> tBL 14, _, $__aeabi_i2d, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit %r0, implicit-def %sp, implicit-def %r0, implicit-def %r1, debug-location !23
> tBL 14, _, @sqrt, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit %r0, implicit %r1, implicit-def %sp, implicit-def %r0, implicit-def %r1, debug-location !24
> tBL 14, _, $__aeabi_d2iz, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit %r0, implicit %r1, implicit-def %sp, implicit-def %r0, debug-location !25
> DBG_VALUE 2, 0, !17, !18, debug-location !27
> DBG_VALUE debug-use %r0, debug-use _, !16, !18, debug-location !26
> tCMPi8 %r0, 2, 14, _, implicit-def %cpsr, debug-location !32
> t2IT 11, 28, implicit-def %itstate
> %r0 = tMOVi8 _, 1, 11, %cpsr, implicit %r0, implicit %itstate
> tPOP_RET 11, %cpsr, def %r4, def %r6, def %r7, def %pc, implicit %r0, implicit %r4, implicit killed %itstate, debug-location !44
> %r1 = t2MOVi 2, 14, _, _
> t2B %bb.3.for.body, 14, _
> Note that a terminator tPOP_RET is before a non-terminator t2MOVi.
> The command line to produce this is as follows:
> llc -mtriple=thumbv7m-none-none-eabi -mcpu=cortex-m3 -O1 -stop-before=arm-cp-islands -o prime-factorize.mir prime-factorize.ll
> Attached are the input file prime-factorize.ll and output file prime-factorize.mir.
> The machine basic block above violates my previous assumption that only terminators and debug instructions may appear after the first terminator in a machine basic block.
> I don't know how "bad" this could be, i.e., how many non-terminators in a program could be generated between two terminators.
> So I have to consider split such basic blocks before I could instrument the program with control flow checks.
> I don't know whether this is a bug or not. If it is not a bug, this apparently isn't a purely theoretical issue.
It looks like what's happening is that IfConversion makes the return
conditional, then that gets merged with the following block. I mean, I
would say it's a bug in that there's a "terminator" in a position not at
the end of the block, but a return doesn't have any CFG successors, so
I'm not sure it has any practical effect.
I think we won't merge with the following block for an indirect branch
which is not a return.
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
More information about the llvm-dev