diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp b/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp index 9d2577eed95..92130a1107c 100644 --- a/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp +++ b/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp @@ -25,7 +25,7 @@ using namespace llvm; #define DEBUG_TYPE "aarch64-branch-relax" STATISTIC(NumSplit, "Number of basic blocks split"); -STATISTIC(NumRelaxed, "Number of conditional branches relaxed"); +STATISTIC(NumConditionalRelaxed, "Number of conditional branches relaxed"); namespace llvm { void initializeAArch64BranchRelaxationPass(PassRegistry &); @@ -477,13 +477,43 @@ bool AArch64BranchRelaxation::relaxBranchInstructions() { if (J == MBB.end()) continue; - MachineInstr &MI = *J; - if (MI.isConditionalBranch() && !isBlockInRange(MI, *getDestBlock(MI))) { - fixupConditionalBranch(MI); - ++NumRelaxed; - Changed = true; + MachineBasicBlock::iterator Next; + for (MachineBasicBlock::iterator J = MBB.getFirstTerminator(); + J != MBB.end(); J = Next) { + Next = std::next(J); + MachineInstr &MI = *J; + + if (MI.isConditionalBranch()) { + MachineBasicBlock *DestBB = getDestBlock(MI); + if (!isBlockInRange(MI, *DestBB)) { + if (Next != MBB.end() && Next->isConditionalBranch()) { + // If there are multiple conditional branches, this isn't an + // analyzable block. Split later terminators into a new block so + // each one will be analyzable. + + MachineBasicBlock *NewBB = splitBlockBeforeInstr(*Next); + NewBB->transferSuccessors(&MBB); + MBB.addSuccessor(NewBB); + MBB.addSuccessor(DestBB); + + // Cleanup potential unconditional branch to successor block. + NewBB->updateTerminator(); + MBB.updateTerminator(); + } else { + fixupConditionalBranch(MI); + ++NumConditionalRelaxed; + } + + Changed = true; + + // This may have modified all of the terminators, so start over. + Next = MBB.getFirstTerminator(); + } + + } } } + return Changed; } |

