[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