[llvm-dev] Update control flow graph when splitting a machine basic block?
章明 via llvm-dev
llvm-dev at lists.llvm.org
Fri Nov 10 18:00:09 PST 2017
> The right way to update the CFG very much depends on how you're
> transforming it.
I would like to export the CFG for control flow checking.
Theoretically, it should be possible for a compiler to know every target of every control flow instruction, except for computed targets that are not known at compile-time.
When a machine basic block is split between two branches, as shown below:
BB: ; Old machine basic block shortened by the split
branch to A
------------------- ; Split here
BB': ; New machine basic block created by the split
branch to B
BB' is a successor of BB (if there is no control flow barrier near the end of BB).
In addition, targets of terminators like A should be added to the set of successors of BB and possibly removed from the set of successors of BB'.
It is not always safe to remove B from the successors of BB', because A and B may be the same machine basic block.
If edges in the CFG are interpreted as possible control flow transfers, rather than definite control flow transfers, the most conservative way to update the CFG might be:
1) Let BB' have all successors of the original machine basic block before the split.
2) Add BB' and all successors of BB' to the set of successors of BB.
However, this introduce false control flow transfers into the CFG. False control flow transfers are harmful to control flow checking, because different basic blocks have to be assigned the same signature, which is called aliasing.
To update the CFG without introducing any false control flow transfers, one needs to determine the target(s) of each terminator.
That is what I desire. I am not quite familiar with LLVM, so I am asking whether it is possible to achieve that with the current LLVM API.
> Your pseudo-code looks similar to ARMBaseInstrInfo::analyzeBranch.
ARMBaseInstrInfo::analyzeBranch also attempts to determine targets of terminators.
However, that method is not adequate to achieve what I desire, because it only works for simple conditional/unconditional branches. When it sees something else, e.g., a jump table, it simply reports that the machine basic block cannot be analyzed.
More information about the llvm-dev