aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-07-12 16:45:35 +0000
committerDale Johannesen <dalej@apple.com>2007-07-12 16:45:35 +0000
commit66a2a8f8782f55a9668c7f4200ff55b52fcddef6 (patch)
tree273b28659a03fe4c5a2d36eeaf402dcff5298d65
parentbb821dd79bf13c5137760c8fe0fa721912c4276d (diff)
ARM: make branch folder remove unconditional branches
following jump tables that it earlier inserted. This would be OK on other targets but is needed for correctness only on ARM (constant islands needs to find jump tables). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@39782 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp7
-rw-r--r--lib/Target/ARM/ARMInstrInfo.cpp15
2 files changed, 15 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index 13b812ca1a..1b936312c0 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -740,14 +740,11 @@ void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB,
delta -= 2;
}
}
- // Thumb jump tables require padding. They can be at the end, or
- // followed by an unconditional branch.
+ // Thumb jump tables require padding. They should be at the end;
+ // following unconditional branches are removed by AnalyzeBranch.
MachineInstr *ThumbJTMI = NULL;
if (prior(MBB->end())->getOpcode() == ARM::tBR_JTr)
ThumbJTMI = prior(MBB->end());
- else if (prior(MBB->end()) != MBB->begin() &&
- prior(prior(MBB->end()))->getOpcode() == ARM::tBR_JTr)
- ThumbJTMI = prior(prior(MBB->end()));
if (ThumbJTMI) {
unsigned newMIOffset = GetOffsetOf(ThumbJTMI);
unsigned oldMIOffset = newMIOffset - delta;
diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp
index f4b4dbe2e3..b404ec078e 100644
--- a/lib/Target/ARM/ARMInstrInfo.cpp
+++ b/lib/Target/ARM/ARMInstrInfo.cpp
@@ -350,8 +350,8 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
return false;
}
- // If the block ends with two B's or tB's, handle it. The second one is not
- // executed, so remove it.
+ // If the block ends with two unconditional branches, handle it. The second
+ // one is not executed, so remove it.
if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) &&
(LastOpc == ARM::B || LastOpc == ARM::tB)) {
TBB = SecondLastInst->getOperand(0).getMachineBasicBlock();
@@ -360,6 +360,17 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
return false;
}
+ // Likewise if it ends with a branch table followed by an unconditional branch.
+ // The branch folder can create these, and we must get rid of them for
+ // correctness of Thumb constant islands.
+ if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm ||
+ SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr) &&
+ (LastOpc == ARM::B || LastOpc == ARM::tB)) {
+ I = LastInst;
+ I->eraseFromParent();
+ return true;
+ }
+
// Otherwise, can't handle this.
return true;
}