[llvm] r286407 - GlobalISel: translate invoke and landingpad instructions

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 9 14:39:54 PST 2016


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) {
       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
+}




More information about the llvm-commits mailing list