mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
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
This commit is contained in:
parent
aeee2d3a29
commit
969c9ef0dd
@ -5883,11 +5883,15 @@ EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
|
|||||||
PrevMBB = CurMBB;
|
PrevMBB = CurMBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the landing pad successor from the invoke block and replace it with
|
const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
|
||||||
// the new dispatch block.
|
const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
|
||||||
|
const unsigned *SavedRegs = RI.getCalleeSavedRegs(MF);
|
||||||
for (SmallPtrSet<MachineBasicBlock*, 64>::iterator
|
for (SmallPtrSet<MachineBasicBlock*, 64>::iterator
|
||||||
I = InvokeBBs.begin(), E = InvokeBBs.end(); I != E; ++I) {
|
I = InvokeBBs.begin(), E = InvokeBBs.end(); I != E; ++I) {
|
||||||
MachineBasicBlock *BB = *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
|
for (MachineBasicBlock::succ_iterator
|
||||||
SI = BB->succ_begin(), SE = BB->succ_end(); SI != SE; ++SI) {
|
SI = BB->succ_begin(), SE = BB->succ_end(); SI != SE; ++SI) {
|
||||||
MachineBasicBlock *SMBB = *SI;
|
MachineBasicBlock *SMBB = *SI;
|
||||||
@ -5898,6 +5902,31 @@ EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BB->addSuccessor(DispatchBB);
|
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.
|
// The instruction is gone now.
|
||||||
|
Loading…
Reference in New Issue
Block a user