1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[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
This commit is contained in:
David Green 2017-04-06 08:32:47 +00:00
parent c3e279d063
commit be4cc9fc51
2 changed files with 166 additions and 1 deletions

View File

@ -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;

View File

@ -0,0 +1,124 @@
#RUN: llc -run-pass arm-cp-islands %s -o - | FileCheck %s
--- |
; ModuleID = 'test.ll'
source_filename = "test.c"
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv8r-arm-none-eabi"
define void @Func(i32 %i, i32* nocapture %p) local_unnamed_addr {
entry:
switch i32 %i, label %sw.epilog [
i32 0, label %sw.bb
i32 1, label %sw.bb1
i32 2, label %sw.epilog.sink.split
i32 4, label %sw.bb3
]
sw.bb: ; preds = %entry
br label %sw.epilog.sink.split
sw.bb1: ; preds = %entry
store i32 0, i32* %p, align 4
br label %sw.epilog.sink.split
sw.bb3: ; preds = %entry
br label %sw.epilog.sink.split
sw.epilog.sink.split: ; preds = %sw.bb3, %sw.bb1, %sw.bb, %entry
%.sink = phi i32 [ 2, %sw.bb3 ], [ 0, %sw.bb ], [ 1, %entry ], [ 1, %sw.bb1 ]
store i32 %.sink, i32* %p, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.epilog.sink.split, %entry
ret void
}
...
---
name: Func
alignment: 1
exposesReturnsTwice: false
noVRegs: true
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
liveins:
- { reg: '%r0' }
- { reg: '%r1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
maxCallFrameSize: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
jumpTable:
kind: inline
entries:
- id: 0
blocks: [ '%bb.2.sw.bb', '%bb.3.sw.bb1', '%bb.5.sw.epilog.sink.split',
'%bb.6.sw.epilog', '%bb.4.sw.bb3' ]
# The ADD should be deleted along with the LEA
# CHECK-NOT: t2LEApcrelJT
# CHECK-NOT: t2ADDrs
# CHECK: tMOVi8
# CHECK: t2TBB_JT
body: |
bb.0.entry:
successors: %bb.6.sw.epilog(0x0ccccccb), %bb.1.entry(0x73333335)
liveins: %r0, %r1
tCMPi8 %r0, 4, 14, _, implicit-def %cpsr
t2Bcc %bb.6.sw.epilog, 8, killed %cpsr
bb.1.entry:
successors: %bb.2.sw.bb(0x1c71c71c), %bb.3.sw.bb1(0x1c71c71c), %bb.5.sw.epilog.sink.split(0x1c71c71c), %bb.6.sw.epilog(0x0e38e38e), %bb.4.sw.bb3(0x1c71c71c)
liveins: %r0, %r1
%r2 = t2LEApcrelJT %jump-table.0, 14, _
%r3 = t2ADDrs killed %r2, %r0, 18, 14, _, _
%r2, dead %cpsr = tMOVi8 1, 14, _
t2BR_JT killed %r3, killed %r0, %jump-table.0
bb.2.sw.bb:
successors: %bb.5.sw.epilog.sink.split(0x80000000)
liveins: %r1
%r2, dead %cpsr = tMOVi8 0, 14, _
t2B %bb.5.sw.epilog.sink.split, 14, _
bb.3.sw.bb1:
successors: %bb.5.sw.epilog.sink.split(0x80000000)
liveins: %r1
%r0, dead %cpsr = tMOVi8 0, 14, _
%r2, dead %cpsr = tMOVi8 1, 14, _
tSTRi killed %r0, %r1, 0, 14, _ :: (store 4 into %ir.p)
t2B %bb.5.sw.epilog.sink.split, 14, _
bb.4.sw.bb3:
successors: %bb.5.sw.epilog.sink.split(0x80000000)
liveins: %r1
%r2, dead %cpsr = tMOVi8 2, 14, _
bb.5.sw.epilog.sink.split:
successors: %bb.6.sw.epilog(0x80000000)
liveins: %r1, %r2
tSTRi killed %r2, killed %r1, 0, 14, _ :: (store 4 into %ir.p)
bb.6.sw.epilog:
tBX_RET 14, _
...