[llvm-commits] [llvm] r142018 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp

Bill Wendling isanbard at gmail.com
Fri Oct 14 16:34:38 PDT 2011


Author: void
Date: Fri Oct 14 18:34:37 2011
New Revision: 142018

URL: http://llvm.org/viewvc/llvm-project?rev=142018&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=142018&r1=142017&r2=142018&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Oct 14 18:34:37 2011
@@ -5883,11 +5883,15 @@
     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 @@
     }
 
     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.





More information about the llvm-commits mailing list