summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp42
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;
}
OpenPOWER on IntegriCloud