summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2017-04-06 08:32:47 +0000
committerDavid Green <david.green@arm.com>2017-04-06 08:32:47 +0000
commit1b4b59a4156083c7703436a7d6bed2f6f56952f5 (patch)
tree9c3d4519e8802ac6b0b2d64cf648fc5e6076b723 /llvm/lib/Target
parent5eeb1dd42ef304c6a2f85d3fb9eda03c932f1fe0 (diff)
downloadbcm5719-llvm-1b4b59a4156083c7703436a7d6bed2f6f56952f5.tar.gz
bcm5719-llvm-1b4b59a4156083c7703436a7d6bed2f6f56952f5.zip
[ARM] Remove a dead ADD during the creation of TBBs
During the optimisation of jump tables in the constant island pass, an extra ADD could be left over, now dead but not removed. Differential Revision: https://reviews.llvm.org/D31389 llvm-svn: 299634
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMConstantIslandPass.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
index 0de628b2c19..23722f1b7f3 100644
--- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -2017,6 +2017,44 @@ static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) {
&*MBB->begin() == CPEMI;
}
+static void RemoveDeadAddBetweenLEAAndJT(MachineInstr *LEAMI,
+ MachineInstr *JumpMI,
+ unsigned &DeadSize) {
+ // Remove a dead add between the LEA and JT, which used to compute EntryReg,
+ // but the JT now uses PC. Finds the last ADD (if any) that def's EntryReg
+ // and is not clobbered / used.
+ MachineInstr *RemovableAdd = nullptr;
+ unsigned EntryReg = JumpMI->getOperand(0).getReg();
+
+ // Find the last ADD to set EntryReg
+ MachineBasicBlock::iterator I(LEAMI);
+ for (++I; &*I != JumpMI; ++I) {
+ if (I->getOpcode() == ARM::t2ADDrs && I->getOperand(0).getReg() == EntryReg)
+ RemovableAdd = &*I;
+ }
+
+ if (!RemovableAdd)
+ return;
+
+ // Ensure EntryReg is not clobbered or used.
+ MachineBasicBlock::iterator J(RemovableAdd);
+ for (++J; &*J != JumpMI; ++J) {
+ for (unsigned K = 0, E = J->getNumOperands(); K != E; ++K) {
+ const MachineOperand &MO = J->getOperand(K);
+ if (!MO.isReg() || !MO.getReg())
+ continue;
+ if (MO.isDef() && MO.getReg() == EntryReg)
+ return;
+ if (MO.isUse() && MO.getReg() == EntryReg)
+ return;
+ }
+ }
+
+ DEBUG(dbgs() << "Removing Dead Add: " << *RemovableAdd);
+ RemovableAdd->eraseFromParent();
+ DeadSize += 4;
+}
+
static bool registerDefinedBetween(unsigned Reg,
MachineBasicBlock::iterator From,
MachineBasicBlock::iterator To,
@@ -2172,7 +2210,10 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
NewJTMI->getOperand(0).setReg(ARM::PC);
NewJTMI->getOperand(0).setIsKill(false);
- if (CanDeleteLEA) {
+ if (CanDeleteLEA) {
+ if (isThumb2)
+ RemoveDeadAddBetweenLEAAndJT(User.MI, MI, DeadSize);
+
User.MI->eraseFromParent();
DeadSize += isThumb2 ? 4 : 2;
OpenPOWER on IntegriCloud