diff options
author | Tim Northover <tnorthover@apple.com> | 2016-11-09 22:39:54 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-11-09 22:39:54 +0000 |
commit | a9105be437546b3f5398781006c1479c9cfecba8 (patch) | |
tree | d0ae6d020f1ddc31e952a761bf20d3824556a613 /llvm/lib/CodeGen | |
parent | 58026af7f074dcf198d15d5b80452e178d962ab2 (diff) | |
download | bcm5719-llvm-a9105be437546b3f5398781006c1479c9cfecba8.tar.gz bcm5719-llvm-a9105be437546b3f5398781006c1479c9cfecba8.zip |
GlobalISel: translate invoke and landingpad instructions
Pretty bare-bones support for exception handling (no weird MSVC stuff, no SjLj
etc), but it should get things going.
llvm-svn: 286407
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 117 |
1 files changed, 116 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 79cce6a6f96..24707c53565 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -14,8 +14,11 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/Analysis.h" +#include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Constant.h" @@ -443,6 +446,13 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, case Intrinsic::smul_with_overflow: Op = TargetOpcode::G_SMULO; break; case Intrinsic::memcpy: return translateMemcpy(CI); + case Intrinsic::eh_typeid_for: { + GlobalValue *GV = ExtractTypeInfo(CI.getArgOperand(0)); + unsigned Reg = getOrCreateVReg(CI); + unsigned TypeID = MIRBuilder.getMF().getMMI().getTypeIDFor(GV); + MIRBuilder.buildConstant(Reg, TypeID); + return true; + } case Intrinsic::objectsize: { // If we don't know by now, we're never going to know. const ConstantInt *Min = cast<ConstantInt>(CI.getArgOperand(1)); @@ -529,6 +539,111 @@ bool IRTranslator::translateCall(const User &U) { return true; } +bool IRTranslator::translateInvoke(const User &U) { + const InvokeInst &I = cast<InvokeInst>(U); + MachineFunction &MF = MIRBuilder.getMF(); + MachineModuleInfo &MMI = MF.getMMI(); + + const BasicBlock *ReturnBB = I.getSuccessor(0); + const BasicBlock *EHPadBB = I.getSuccessor(1); + + const Value *Callee(I.getCalledValue()); + const Function *Fn = dyn_cast<Function>(Callee); + if (isa<InlineAsm>(Callee)) + return false; + + // FIXME: support invoking patchpoint and statepoint intrinsics. + if (Fn && Fn->isIntrinsic()) + return false; + + // FIXME: support whatever these are. + if (I.countOperandBundlesOfType(LLVMContext::OB_deopt)) + return false; + + // FIXME: support Windows exception handling. + if (!isa<LandingPadInst>(EHPadBB->front())) + return false; + + + // Emit the actual call, bracketed by EH_LABELs so that the MMI knows about + // the region covered by the try. + MCSymbol *BeginSymbol = MMI.getContext().createTempSymbol(); + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol); + + unsigned Res = I.getType()->isVoidTy() ? 0 : getOrCreateVReg(I); + SmallVector<CallLowering::ArgInfo, 8> Args; + for (auto &Arg: I.arg_operands()) + Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType()); + + if (!CLI->lowerCall(MIRBuilder, MachineOperand::CreateGA(Fn, 0), + CallLowering::ArgInfo(Res, I.getType()), Args)) + return false; + + MCSymbol *EndSymbol = MMI.getContext().createTempSymbol(); + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol); + + // FIXME: track probabilities. + MachineBasicBlock &EHPadMBB = getOrCreateBB(*EHPadBB), + &ReturnMBB = getOrCreateBB(*ReturnBB); + MMI.addInvoke(&EHPadMBB, BeginSymbol, EndSymbol); + MIRBuilder.getMBB().addSuccessor(&ReturnMBB); + MIRBuilder.getMBB().addSuccessor(&EHPadMBB); + + return true; +} + +bool IRTranslator::translateLandingPad(const User &U) { + const LandingPadInst &LP = cast<LandingPadInst>(U); + + MachineBasicBlock &MBB = MIRBuilder.getMBB(); + MachineFunction &MF = MIRBuilder.getMF(); + MachineModuleInfo &MMI = MF.getMMI(); + AddLandingPadInfo(LP, MMI, &MBB); + + MBB.setIsEHPad(); + + // If there aren't registers to copy the values into (e.g., during SjLj + // exceptions), then don't bother. + auto &TLI = *MF.getSubtarget().getTargetLowering(); + const Constant *PersonalityFn = MF.getFunction()->getPersonalityFn(); + if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 && + TLI.getExceptionSelectorRegister(PersonalityFn) == 0) + return true; + + // If landingpad's return type is token type, we don't create DAG nodes + // for its exception pointer and selector value. The extraction of exception + // pointer or selector value from token type landingpads is not currently + // supported. + if (LP.getType()->isTokenTy()) + return true; + + // Add a label to mark the beginning of the landing pad. Deletion of the + // landing pad can thus be detected via the MachineModuleInfo. + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL) + .addSym(MMI.addLandingPad(&MBB)); + + // Mark exception register as live in. + SmallVector<unsigned, 2> Regs; + SmallVector<uint64_t, 2> Offsets; + LLT p0 = LLT::pointer(0, DL->getPointerSizeInBits()); + if (unsigned Reg = TLI.getExceptionPointerRegister(PersonalityFn)) { + unsigned VReg = MRI->createGenericVirtualRegister(p0); + MIRBuilder.buildCopy(VReg, Reg); + Regs.push_back(VReg); + Offsets.push_back(0); + } + + if (unsigned Reg = TLI.getExceptionSelectorRegister(PersonalityFn)) { + unsigned VReg = MRI->createGenericVirtualRegister(p0); + MIRBuilder.buildCopy(VReg, Reg); + Regs.push_back(VReg); + Offsets.push_back(p0.getSizeInBits()); + } + + MIRBuilder.buildSequence(getOrCreateVReg(LP), Regs, Offsets); + return true; +} + bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) { if (!TPC->isGlobalISelAbortEnabled() && !AI.isStaticAlloca()) return false; @@ -613,7 +728,6 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) { return true; } - void IRTranslator::finalizeFunction() { finishPendingPhis(); @@ -665,6 +779,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &MF) { // Set the insertion point of all the following translations to // the end of this basic block. MIRBuilder.setMBB(MBB); + for (const Instruction &Inst: BB) { bool Succeeded = translate(Inst); if (!Succeeded) { |