summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-10-14 23:34:37 +0000
committerBill Wendling <isanbard@gmail.com>2011-10-14 23:34:37 +0000
commit969c9ef0dd271905136f21a6c51dd0839ef01cce (patch)
tree67ac26f30c9d885f5cf8888b3c5ceb5bd4ff20f5 /lib
parentaeee2d3a297a2ca41a07d33285a75cee23ad97d9 (diff)
downloadllvm-969c9ef0dd271905136f21a6c51dd0839ef01cce.tar.gz
llvm-969c9ef0dd271905136f21a6c51dd0839ef01cce.tar.bz2
llvm-969c9ef0dd271905136f21a6c51dd0839ef01cce.tar.xz
Mark the invoke call instruction as implicitly defining the callee-saved registers.
The callee-saved registers cannot be live across an invoke call because the control flow may continue along the exceptional edge. When this happens, all of the callee-saved registers are no longer valid. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142018 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp33
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 2ac52cfc36..f3bc719450 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -5883,11 +5883,15 @@ EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
PrevMBB = CurMBB;
}
- // Remove the landing pad successor from the invoke block and replace it with
- // the new dispatch block.
+ const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
+ const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
+ const unsigned *SavedRegs = RI.getCalleeSavedRegs(MF);
for (SmallPtrSet<MachineBasicBlock*, 64>::iterator
I = InvokeBBs.begin(), E = InvokeBBs.end(); I != E; ++I) {
MachineBasicBlock *BB = *I;
+
+ // Remove the landing pad successor from the invoke block and replace it
+ // with the new dispatch block.
for (MachineBasicBlock::succ_iterator
SI = BB->succ_begin(), SE = BB->succ_end(); SI != SE; ++SI) {
MachineBasicBlock *SMBB = *SI;
@@ -5898,6 +5902,31 @@ EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
}
BB->addSuccessor(DispatchBB);
+
+ // Find the invoke call and mark all of the callee-saved registers as
+ // 'implicit defined' so that they're spilled. This prevents code from
+ // moving instructions to before the EH block, where they will never be
+ // executed.
+ for (MachineBasicBlock::reverse_iterator
+ II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) {
+ if (!II->getDesc().isCall()) continue;
+
+ DenseMap<unsigned, bool> DefRegs;
+ for (MachineInstr::mop_iterator
+ OI = II->operands_begin(), OE = II->operands_end();
+ OI != OE; ++OI) {
+ if (!OI->isReg()) continue;
+ DefRegs[OI->getReg()] = true;
+ }
+
+ MachineInstrBuilder MIB(&*II);
+
+ for (unsigned i = 0; SavedRegs[i] != 0; ++i)
+ if (!DefRegs[SavedRegs[i]])
+ MIB.addReg(SavedRegs[i], RegState::Implicit | RegState::Define);
+
+ break;
+ }
}
// The instruction is gone now.