Handle cases where the post-RA scheduler may move instructions between the

address calculation instructions leading up to a jump table when we're trying
to convert them into a TB[H] instruction in Thumb2. This realistically
shouldn't happen much, if at all, for well formed inputs, but it's more correct
to handle it. rdar://7387682

llvm-svn: 107830
This commit is contained in:
Jim Grosbach 2010-07-07 22:51:22 +00:00
parent 529728e82a
commit 40eda1076a
1 changed files with 21 additions and 6 deletions

View File

@ -1661,15 +1661,25 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
continue; continue;
unsigned IdxReg = MI->getOperand(1).getReg(); unsigned IdxReg = MI->getOperand(1).getReg();
bool IdxRegKill = MI->getOperand(1).isKill(); bool IdxRegKill = MI->getOperand(1).isKill();
// Scan backwards to find the instruction that defines the base
// register. Due to post-RA scheduling, we can't count on it
// immediately preceding the branch instruction.
MachineBasicBlock::iterator PrevI = MI; MachineBasicBlock::iterator PrevI = MI;
if (PrevI == MBB->begin()) MachineBasicBlock::iterator B = MBB->begin();
while (PrevI != B && !PrevI->definesRegister(BaseReg))
--PrevI;
// If for some reason we didn't find it, we can't do anything, so
// just skip this one.
if (!PrevI->definesRegister(BaseReg))
continue; continue;
MachineInstr *AddrMI = --PrevI; MachineInstr *AddrMI = PrevI;
bool OptOk = true; bool OptOk = true;
// Examine the instruction that calculates the jumptable entry address. // Examine the instruction that calculates the jumptable entry address.
// If it's not the one just before the t2BR_JT, we won't delete it, then // Make sure it only defines the base register and kills any uses
// it's not worth doing the optimization. // other than the index register.
for (unsigned k = 0, eee = AddrMI->getNumOperands(); k != eee; ++k) { for (unsigned k = 0, eee = AddrMI->getNumOperands(); k != eee; ++k) {
const MachineOperand &MO = AddrMI->getOperand(k); const MachineOperand &MO = AddrMI->getOperand(k);
if (!MO.isReg() || !MO.getReg()) if (!MO.isReg() || !MO.getReg())
@ -1686,9 +1696,14 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
if (!OptOk) if (!OptOk)
continue; continue;
// The previous instruction should be a tLEApcrel or t2LEApcrelJT, we want // Now scan back again to find the tLEApcrel or t2LEApcrelJT instruction
// that gave us the initial base register definition.
for (--PrevI; PrevI != B && !PrevI->definesRegister(BaseReg); --PrevI)
;
// The instruction should be a tLEApcrel or t2LEApcrelJT; we want
// to delete it as well. // to delete it as well.
MachineInstr *LeaMI = --PrevI; MachineInstr *LeaMI = PrevI;
if ((LeaMI->getOpcode() != ARM::tLEApcrelJT && if ((LeaMI->getOpcode() != ARM::tLEApcrelJT &&
LeaMI->getOpcode() != ARM::t2LEApcrelJT) || LeaMI->getOpcode() != ARM::t2LEApcrelJT) ||
LeaMI->getOperand(0).getReg() != BaseReg) LeaMI->getOperand(0).getReg() != BaseReg)