[llvm] r286407 - GlobalISel: translate invoke and landingpad instructions
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 10 15:06:08 PST 2016
> On Nov 9, 2016, at 2:39 PM, Tim Northover via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Author: tnorthover
> Date: Wed Nov 9 16:39:54 2016
> New Revision: 286407
>
> URL: http://llvm.org/viewvc/llvm-project?rev=286407&view=rev
> Log:
> 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.
>
> Added:
> llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll
> Modified:
> llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
> llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
> llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h?rev=286407&r1=286406&r2=286407&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Wed Nov 9 16:39:54 2016
> @@ -132,6 +132,10 @@ private:
> /// \pre \p U is a call instruction.
> bool translateCall(const User &U);
>
> + bool translateInvoke(const User &U);
> +
> + bool translateLandingPad(const User &U);
> +
> /// Translate one of LLVM's cast instructions into MachineInstrs, with the
> /// given generic Opcode.
> bool translateCast(unsigned Opcode, const User &U);
> @@ -287,7 +291,6 @@ private:
> // translation.
> bool translateSwitch(const User &U) { return false; }
> bool translateIndirectBr(const User &U) { return false; }
> - bool translateInvoke(const User &U) { return false; }
> bool translateResume(const User &U) { return false; }
> bool translateCleanupRet(const User &U) { return false; }
> bool translateCatchRet(const User &U) { return false; }
> @@ -304,7 +307,6 @@ private:
> bool translateExtractElement(const User &U) { return false; }
> bool translateInsertElement(const User &U) { return false; }
> bool translateShuffleVector(const User &U) { return false; }
> - bool translateLandingPad(const User &U) { return false; }
>
> /// @}
>
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=286407&r1=286406&r2=286407&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Wed Nov 9 16:39:54 2016
> @@ -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::translateKnownIntrins
> 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 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 Const
> return true;
> }
>
> -
> void IRTranslator::finalizeFunction() {
> finishPendingPhis();
>
> @@ -665,6 +779,7 @@ bool IRTranslator::runOnMachineFunction(
> // 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) {
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=286407&r1=286406&r2=286407&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Wed Nov 9 16:39:54 2016
> @@ -915,7 +915,7 @@ bool AArch64InstructionSelector::select(
> .addUse(SrcXReg)
> .addImm(0)
> .addImm(SrcTy.getSizeInBits() - 1);
> - } else if (DstTy == LLT::scalar(32)) {
> + } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
This change seems unrelated to EH support.
> const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
> ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
> .addDef(DefReg)
>
> Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll?rev=286407&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll (added)
> +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll Wed Nov 9 16:39:54 2016
> @@ -0,0 +1,44 @@
> +; RUN: llc -O0 -mtriple=aarch64-apple-ios -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
> +
> + at _ZTIi = external global i8*
> +
> +declare i32 @foo(i32)
> +declare i32 @__gxx_personality_v0(...)
> +declare i32 @llvm.eh.typeid.for(i8*)
> +
> +; CHECK: name: bar
> +; CHECK: body:
> +; CHECK: bb.0:
> +; CHECK: successors: %bb.2{{.*}}%bb.1
> +; CHECK: EH_LABEL
> +; CHECK: %w0 = COPY
> +; CHECK: BL @foo, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %w0, implicit-def %w0
> +; CHECK: {{%[0-9]+}}(s32) = COPY %w0
> +; CHECK: EH_LABEL
> +
> +; CHECK: bb.1
> +; CHECK: EH_LABEL
> +; CHECK: [[PTR:%[0-9]+]](p0) = COPY %x0
> +; CHECK: [[SEL:%[0-9]+]](p0) = COPY %x1
> +; CHECK: [[PTR_SEL:%[0-9]+]](s128) = G_SEQUENCE [[PTR]](p0), 0, [[SEL]](p0), 64
> +; CHECK: [[PTR_RET:%[0-9]+]](s64), [[SEL_RET:%[0-9]+]](s32) = G_EXTRACT [[PTR_SEL]](s128), 0, 64
> +; CHECK: %x0 = COPY [[PTR_RET]]
> +; CHECK: %w1 = COPY [[SEL_RET]]
> +
> +; CHECK: bb.2:
> +; CHECK: [[SEL:%[0-9]+]](s32) = G_CONSTANT 1
> +; CHECK: {{%[0-9]+}}(s128) = G_INSERT {{%[0-9]+}}(s128), [[SEL]](s32), 64
> +
> +define { i8*, i32 } @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
> + %res32 = invoke i32 @foo(i32 42) to label %continue unwind label %broken
> +
> +
> +broken:
> + %ptr.sel = landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
> + ret { i8*, i32 } %ptr.sel
> +
> +continue:
> + %sel.int = tail call i32 @llvm.eh.typeid.for(i8* bitcast(i8** @_ZTIi to i8*))
> + %res.good = insertvalue { i8*, i32 } undef, i32 %sel.int, 1
> + ret { i8*, i32 } %res.good
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list