diff options
| author | Bill Wendling <isanbard@gmail.com> | 2011-10-14 23:34:37 +0000 |
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2011-10-14 23:34:37 +0000 |
| commit | 6f3f9a391e4fa5a65c89945c02e5c6650f40343a (patch) | |
| tree | d5ec6767ba1d695f47bb9ed3e2c989bb97864fcb /llvm/lib/Target | |
| parent | f82017f3fed6fa6e742778de9b4316e9628b36cb (diff) | |
| download | bcm5719-llvm-6f3f9a391e4fa5a65c89945c02e5c6650f40343a.tar.gz bcm5719-llvm-6f3f9a391e4fa5a65c89945c02e5c6650f40343a.zip | |
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.
llvm-svn: 142018
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 2ac52cfc366..f3bc719450f 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/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. |

