summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-10-03 21:25:38 +0000
committerBill Wendling <isanbard@gmail.com>2011-10-03 21:25:38 +0000
commitf7e4aefd0f78441bef3b9eb683ecccbed9582b8a (patch)
tree749c2228f7d42cfcfe879074ee7dfb730deabcff /lib
parentbbb47b320ddeae77833fb0350a04a6de659071c8 (diff)
downloadllvm-f7e4aefd0f78441bef3b9eb683ecccbed9582b8a.tar.gz
llvm-f7e4aefd0f78441bef3b9eb683ecccbed9582b8a.tar.bz2
llvm-f7e4aefd0f78441bef3b9eb683ecccbed9582b8a.tar.xz
Check-pointing the new SjLj EH lowering.
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
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp74
-rw-r--r--lib/Target/ARM/ARMISelLowering.h3
2 files changed, 77 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 316e4fa12c..9ba97a91dc 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -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(),
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index 3b1023ee3a..0946f07cc3 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -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;
};