Check-pointing the new SjLj EH lowering.
authorBill Wendling <isanbard@gmail.com>
Mon, 3 Oct 2011 21:25:38 +0000 (21:25 +0000)
committerBill Wendling <isanbard@gmail.com>
Mon, 3 Oct 2011 21:25:38 +0000 (21:25 +0000)
This code will replace the version in ARMAsmPrinter.cpp. It creates a new
machine basic block, which is the dispatch for the return from a longjmp
call. It then shoves the address of that machine basic block into the correct
place in the function context so that the EH runtime will jump to it directly
instead of having to go through a compare-and-jump-to-the-dispatch bit. This
should be more efficient in the common case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141031 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMISelLowering.h

index 316e4fa12cae55fcc28188661eb2125d014004c4..9ba97a91dc1318eea099c32546a1286b2958afd6 100644 (file)
@@ -5482,6 +5482,80 @@ ARMTargetLowering::EmitAtomicBinary64(MachineInstr *MI, MachineBasicBlock *BB,
   return BB;
 }
 
+MachineBasicBlock *ARMTargetLowering::
+EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+  DebugLoc dl = MI->getDebugLoc();
+  MachineFunction *MF = MBB->getParent();
+  MachineRegisterInfo *MRI = &MF->getRegInfo();
+  MachineConstantPool *MCP = MF->getConstantPool();
+  ARMFunctionInfo *AFI = MF->getInfo<ARMFunctionInfo>();
+  const Function *F = MF->getFunction();
+  MachineFrameInfo *MFI = MF->getFrameInfo();
+  MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
+  int FI = MFI->getFunctionContextIndex();
+  MachineBasicBlock *Last = &MF->back();
+  MF->insert(MF->end(), DispatchBB);
+  MF->RenumberBlocks(Last);
+
+  // Shove the dispatch's address into the return slot in the function context.
+  DispatchBB->setIsLandingPad();
+  MBB->addSuccessor(DispatchBB);
+
+  BuildMI(DispatchBB, dl, TII->get(ARM::TRAP));
+
+  bool isThumb = Subtarget->isThumb();
+  unsigned PCLabelId = AFI->createPICLabelUId();
+  unsigned PCAdj = isThumb ? 4 : 8;
+  ARMConstantPoolValue *CPV =
+    ARMConstantPoolMBB::Create(F->getContext(), DispatchBB, PCLabelId, PCAdj);
+  unsigned CPI = MCP->getConstantPoolIndex(CPV, 4);
+
+  const TargetRegisterClass *TRC =
+    isThumb ? ARM::tGPRRegisterClass : ARM::GPRRegisterClass;
+
+  MachineMemOperand *CPMMO =
+    MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(),
+                             MachineMemOperand::MOLoad, 4, 4);
+
+  MachineMemOperand *FIMMO =
+    MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
+                             MachineMemOperand::MOStore, 4, 4);
+
+  // Load the address of the dispatch MBB into the jump buffer.
+  if (isThumb) {
+    unsigned NewVReg = MRI->createVirtualRegister(TRC);
+    BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci_pic), NewVReg)
+      .addConstantPoolIndex(CPI)
+      .addImm(1)
+      .addMemOperand(CPMMO);
+    AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRspi))
+                   .addReg(NewVReg, RegState::Kill)
+                   .addFrameIndex(FI)
+                   .addImm(36)  // &jbuf[1] :: pc
+                   .addMemOperand(FIMMO));
+  } else {
+    unsigned NewVReg1 = MRI->createVirtualRegister(TRC);
+    AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12),  NewVReg1)
+                   .addConstantPoolIndex(CPI)
+                   .addImm(0)
+                   .addMemOperand(CPMMO));
+    unsigned NewVReg2 = MRI->createVirtualRegister(TRC);
+    AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2)
+                   .addReg(NewVReg1, RegState::Kill)
+                   .addImm(1));
+    AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12))
+                   .addReg(NewVReg2, RegState::Kill)
+                   .addFrameIndex(FI)
+                   .addImm(36)  // &jbuf[1] :: pc
+                   .addMemOperand(FIMMO));
+  }
+
+  MI->eraseFromParent();   // The instruction is gone now.
+
+  return MBB;
+}
+
 static
 MachineBasicBlock *OtherSucc(MachineBasicBlock *MBB, MachineBasicBlock *Succ) {
   for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(),
index 3b1023ee3a5278455c2e0bcf83252162fbaa861a..0946f07cc3d078f5e8a012eb7a734e33d3b81cad 100644 (file)
@@ -512,6 +512,9 @@ namespace llvm {
                                                bool signExtend,
                                                ARMCC::CondCodes Cond) const;
 
+    MachineBasicBlock *EmitSjLjDispatchBlock(MachineInstr *MI,
+                                             MachineBasicBlock *MBB) const;
+
     bool RemapAddSubWithFlags(MachineInstr *MI, MachineBasicBlock *BB) const;
   };