<div dir="rtl"><div dir="ltr">Hi Saleem,</div><div dir="ltr"><br></div><div dir="ltr">Please see r271278,</div><div dir="ltr"><br></div><div dir="ltr">Yaron</div><div dir="ltr"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div dir="ltr">2016-05-31 4:48 GMT+03:00 Saleem Abdulrasool via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span>:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: compnerd<br>
Date: Mon May 30 20:48:07 2016<br>
New Revision: 271244<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=271244&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=271244&view=rev</a><br>
Log:<br>
X86: permit using SjLj EH on x86 targets as an option<br>
<br>
This adds support to the backed to actually support SjLj EH as an exception<br>
model.  This is *NOT* the default model, and requires explicitly opting into it<br>
from the frontend.  GCC supports this model and for MinGW can still be enabled<br>
via the `--using-sjlj-exceptions` options.<br>
<br>
Addresses PR27749!<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/X86/sjlj-eh.ll<br>
Modified:<br>
    llvm/trunk/include/llvm/Analysis/EHPersonalities.h<br>
    llvm/trunk/include/llvm/CodeGen/CommandFlags.h<br>
    llvm/trunk/include/llvm/MC/MCAsmInfo.h<br>
    llvm/trunk/lib/Analysis/EHPersonalities.cpp<br>
    llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
    llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Analysis/EHPersonalities.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/EHPersonalities.h?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/EHPersonalities.h?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Analysis/EHPersonalities.h (original)<br>
+++ llvm/trunk/include/llvm/Analysis/EHPersonalities.h Mon May 30 20:48:07 2016<br>
@@ -23,7 +23,9 @@ enum class EHPersonality {<br>
   Unknown,<br>
   GNU_Ada,<br>
   GNU_C,<br>
+  GNU_C_SjLj,<br>
   GNU_CXX,<br>
+  GNU_CXX_SjLj,<br>
   GNU_ObjC,<br>
   MSVC_X86SEH,<br>
   MSVC_Win64SEH,<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/CommandFlags.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CommandFlags.h?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CommandFlags.h?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/CommandFlags.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/CommandFlags.h Mon May 30 20:48:07 2016<br>
@@ -90,6 +90,22 @@ CMModel("code-model",<br>
                               "Large code model"),<br>
                    clEnumValEnd));<br>
<br>
+cl::opt<llvm::ExceptionHandling><br>
+ExceptionModel("exception-model",<br>
+               cl::desc("exception model"),<br>
+               cl::init(ExceptionHandling::None),<br>
+               cl::values(clEnumValN(ExceptionHandling::None, "default",<br>
+                                     "default exception handling model"),<br>
+                          clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",<br>
+                                     "DWARF-like CFI based exception handling"),<br>
+                          clEnumValN(ExceptionHandling::SjLj, "sjlj",<br>
+                                     "SjLj exception handling"),<br>
+                          clEnumValN(ExceptionHandling::ARM, "arm",<br>
+                                     "ARM EHABI exceptions"),<br>
+                          clEnumValN(ExceptionHandling::WinEH, "wineh",<br>
+                                     "Windows exception model"),<br>
+                          clEnumValEnd));<br>
+<br>
 cl::opt<TargetMachine::CodeGenFileType><br>
 FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),<br>
   cl::desc("Choose a file type (not all types are supported by all targets):"),<br>
@@ -293,6 +309,7 @@ static inline TargetOptions InitTargetOp<br>
   Options.FunctionSections = FunctionSections;<br>
   Options.UniqueSectionNames = UniqueSectionNames;<br>
   Options.EmulatedTLS = EmulatedTLS;<br>
+  Options.ExceptionModel = ExceptionModel;<br>
<br>
   Options.MCOptions = InitMCTargetOptionsFromFlags();<br>
   Options.JTType = JTableType;<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Mon May 30 20:48:07 2016<br>
@@ -535,6 +535,10 @@ public:<br>
   ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }<br>
   WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }<br>
<br>
+  void setExceptionsType(ExceptionHandling EH) {<br>
+    ExceptionsType = EH;<br>
+  }<br>
+<br>
   /// Returns true if the exception handling method for the platform uses call<br>
   /// frame information to unwind.<br>
   bool usesCFIForEH() const {<br>
<br>
Modified: llvm/trunk/lib/Analysis/EHPersonalities.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/EHPersonalities.cpp?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/EHPersonalities.cpp?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Analysis/EHPersonalities.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/EHPersonalities.cpp Mon May 30 20:48:07 2016<br>
@@ -27,7 +27,9 @@ EHPersonality llvm::classifyEHPersonalit<br>
   return StringSwitch<EHPersonality>(F->getName())<br>
     .Case("__gnat_eh_personality", EHPersonality::GNU_Ada)<br>
     .Case("__gxx_personality_v0",  EHPersonality::GNU_CXX)<br>
+    .Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj)<br>
     .Case("__gcc_personality_v0",  EHPersonality::GNU_C)<br>
+    .Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj)<br>
     .Case("__objc_personality_v0", EHPersonality::GNU_ObjC)<br>
     .Case("_except_handler3",      EHPersonality::MSVC_X86SEH)<br>
     .Case("_except_handler4",      EHPersonality::MSVC_X86SEH)<br>
<br>
Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon May 30 20:48:07 2016<br>
@@ -75,6 +75,9 @@ void LLVMTargetMachine::initAsmInfo() {<br>
<br>
   TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations);<br>
<br>
+  if (Options.ExceptionModel != ExceptionHandling::None)<br>
+    TmpAsmInfo->setExceptionsType(Options.ExceptionModel);<br>
+<br>
   AsmInfo = TmpAsmInfo;<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon May 30 20:48:07 2016<br>
@@ -405,6 +405,9 @@ X86TargetLowering::X86TargetLowering(con<br>
   // LLVM/Clang supports zero-cost DWARF exception handling.<br>
   setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);<br>
   setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);<br>
+  setOperationAction(ISD::EH_SJLJ_SETUP_DISPATCH, MVT::Other, Custom);<br>
+  if (TM.Options.ExceptionModel == ExceptionHandling::SjLj)<br>
+    setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume");<br>
<br>
   // Darwin ABI issue.<br>
   for (auto VT : { MVT::i32, MVT::i64 }) {<br>
@@ -448,7 +451,8 @@ X86TargetLowering::X86TargetLowering(con<br>
<br>
   // FIXME - use subtarget debug flags<br>
   if (!Subtarget.isTargetDarwin() && !Subtarget.isTargetELF() &&<br>
-      !Subtarget.isTargetCygMing() && !Subtarget.isTargetWin64()) {<br>
+      !Subtarget.isTargetCygMing() && !Subtarget.isTargetWin64() &&<br>
+      TM.Options.ExceptionModel != ExceptionHandling::SjLj) {<br>
     setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);<br>
   }<br>
<br>
@@ -17841,6 +17845,16 @@ static SDValue LowerINTRINSIC_WO_CHAIN(S<br>
     return DAG.getNode(Opcode, dl, VTs, NewOps);<br>
   }<br>
<br>
+  case Intrinsic::eh_sjlj_lsda: {<br>
+    MachineFunction &MF = DAG.getMachineFunction();<br>
+    const TargetLowering &TLI = DAG.getTargetLoweringInfo();<br>
+    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());<br>
+    auto &Context = MF.getMMI().getContext();<br>
+    MCSymbol *S = Context.getOrCreateSymbol(Twine("GCC_except_table") +<br>
+                                            Twine(MF.getFunctionNumber()));<br>
+    return DAG.getNode(X86ISD::Wrapper, dl, VT, DAG.getMCSymbol(S, PtrVT));<br>
+  }<br>
+<br>
   case Intrinsic::x86_seh_lsda: {<br>
     // Compute the symbol for the LSDA. We know it'll get emitted later.<br>
     MachineFunction &MF = DAG.getMachineFunction();<br>
@@ -18487,6 +18501,13 @@ SDValue X86TargetLowering::lowerEH_SJLJ_<br>
                      Op.getOperand(0), Op.getOperand(1));<br>
 }<br>
<br>
+SDValue X86TargetLowering::lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,<br>
+                                                       SelectionDAG &DAG) const {<br>
+  SDLoc DL(Op);<br>
+  return DAG.getNode(X86ISD::EH_SJLJ_SETUP_DISPATCH, DL, MVT::Other,<br>
+                     Op.getOperand(0));<br>
+}<br>
+<br>
 static SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) {<br>
   return Op.getOperand(0);<br>
 }<br>
@@ -21401,6 +21422,8 @@ SDValue X86TargetLowering::LowerOperatio<br>
   case ISD::EH_RETURN:          return LowerEH_RETURN(Op, DAG);<br>
   case ISD::EH_SJLJ_SETJMP:     return lowerEH_SJLJ_SETJMP(Op, DAG);<br>
   case ISD::EH_SJLJ_LONGJMP:    return lowerEH_SJLJ_LONGJMP(Op, DAG);<br>
+  case ISD::EH_SJLJ_SETUP_DISPATCH:<br>
+    return lowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);<br>
   case ISD::INIT_TRAMPOLINE:    return LowerINIT_TRAMPOLINE(Op, DAG);<br>
   case ISD::ADJUST_TRAMPOLINE:  return LowerADJUST_TRAMPOLINE(Op, DAG);<br>
   case ISD::FLT_ROUNDS_:        return LowerFLT_ROUNDS_(Op, DAG);<br>
@@ -21827,6 +21850,8 @@ const char *X86TargetLowering::getTarget<br>
   case X86ISD::TLSCALL:            return "X86ISD::TLSCALL";<br>
   case X86ISD::EH_SJLJ_SETJMP:     return "X86ISD::EH_SJLJ_SETJMP";<br>
   case X86ISD::EH_SJLJ_LONGJMP:    return "X86ISD::EH_SJLJ_LONGJMP";<br>
+  case X86ISD::EH_SJLJ_SETUP_DISPATCH:<br>
+    return "X86ISD::EH_SJLJ_SETUP_DISPATCH";<br>
   case X86ISD::EH_RETURN:          return "X86ISD::EH_RETURN";<br>
   case X86ISD::TC_RETURN:          return "X86ISD::TC_RETURN";<br>
   case X86ISD::FNSTCW16m:          return "X86ISD::FNSTCW16m";<br>
@@ -23613,6 +23638,237 @@ X86TargetLowering::emitEHSjLjLongJmp(Mac<br>
   return MBB;<br>
 }<br>
<br>
+void X86TargetLowering::SetupEntryBlockForSjLj(MachineInstr *MI,<br>
+                                               MachineBasicBlock *MBB,<br>
+                                               MachineBasicBlock *DispatchBB,<br>
+                                               int FI) const {<br>
+  DebugLoc DL = MI->getDebugLoc();<br>
+  MachineFunction *MF = MBB->getParent();<br>
+  MachineRegisterInfo *MRI = &MF->getRegInfo();<br>
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();<br>
+<br>
+  MVT PVT = getPointerTy(MF->getDataLayout());<br>
+  assert((PVT == MVT::i64 || PVT == MVT::i32) && "Invalid Pointer Size!");<br>
+<br>
+  unsigned Op = 0;<br>
+  unsigned VR = 0;<br>
+<br>
+  Reloc::Model RM = MF->getTarget().getRelocationModel();<br>
+  bool UseImmLabel = (MF->getTarget().getCodeModel() == CodeModel::Small) &&<br>
+                     (RM == Reloc::Static || RM == Reloc::DynamicNoPIC);<br>
+<br>
+  if (UseImmLabel) {<br>
+    Op = (PVT == MVT::i64) ? X86::MOV64mi32 : X86::MOV32mi;<br>
+  } else {<br>
+    const TargetRegisterClass *TRC =<br>
+        (PVT == MVT::i64) ? &X86::GR64RegClass : &X86::GR32RegClass;<br>
+    VR = MRI->createVirtualRegister(TRC);<br>
+    Op = (PVT == MVT::i64) ? X86::MOV64mr : X86::MOV32mr;<br>
+<br>
+    /* const X86InstrInfo *XII = static_cast<const X86InstrInfo *>(TII); */<br>
+<br>
+    if (Subtarget.is64Bit())<br>
+      BuildMI(*MBB, MI, DL, TII->get(X86::LEA64r), VR)<br>
+          .addReg(X86::RIP)<br>
+          .addImm(1)<br>
+          .addReg(0)<br>
+          .addMBB(DispatchBB)<br>
+          .addReg(0);<br>
+    else<br>
+      BuildMI(*MBB, MI, DL, TII->get(X86::LEA32r), VR)<br>
+          .addReg(0) /* XII->getGlobalBaseReg(MF) */<br>
+          .addImm(1)<br>
+          .addReg(0)<br>
+          .addMBB(DispatchBB, Subtarget.classifyBlockAddressReference())<br>
+          .addReg(0);<br>
+  }<br>
+<br>
+  MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(Op));<br>
+  addFrameReference(MIB, FI, 36);<br>
+  if (UseImmLabel)<br>
+    MIB.addMBB(DispatchBB);<br>
+  else<br>
+    MIB.addReg(VR);<br>
+}<br>
+<br>
+MachineBasicBlock *<br>
+X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr *MI,<br>
+                                         MachineBasicBlock *BB) const {<br>
+  DebugLoc DL = MI->getDebugLoc();<br>
+  MachineFunction *MF = BB->getParent();<br>
+  MachineModuleInfo *MMI = &MF->getMMI();<br>
+  MachineFrameInfo *MFI = MF->getFrameInfo();<br>
+  MachineRegisterInfo *MRI = &MF->getRegInfo();<br>
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();<br>
+  int FI = MFI->getFunctionContextIndex();<br>
+<br>
+  // Get a mapping of the call site numbers to all of the landing pads they're<br>
+  // associated with.<br>
+  DenseMap<unsigned, SmallVector<MachineBasicBlock *, 2>> CallSiteNumToLPad;<br>
+  unsigned MaxCSNum = 0;<br>
+  for (auto &MBB : *MF) {<br>
+    if (!MBB.isEHPad())<br>
+      continue;<br>
+<br>
+    MCSymbol *Sym = nullptr;<br>
+    for (const auto &MI : MBB) {<br>
+      if (MI.isDebugValue())<br>
+        continue;<br>
+<br>
+      assert(MI.isEHLabel() && "expected EH_LABEL");<br>
+      Sym = MI.getOperand(0).getMCSymbol();<br>
+      break;<br>
+    }<br>
+<br>
+    if (!MMI->hasCallSiteLandingPad(Sym))<br>
+      continue;<br>
+<br>
+    for (unsigned CSI : MMI->getCallSiteLandingPad(Sym)) {<br>
+      CallSiteNumToLPad[CSI].push_back(&MBB);<br>
+      MaxCSNum = std::max(MaxCSNum, CSI);<br>
+    }<br>
+  }<br>
+<br>
+  // Get an ordered list of the machine basic blocks for the jump table.<br>
+  std::vector<MachineBasicBlock *> LPadList;<br>
+  SmallPtrSet<MachineBasicBlock *, 32> InvokeBBs;<br>
+  LPadList.reserve(CallSiteNumToLPad.size());<br>
+<br>
+  for (unsigned CSI = 1; CSI <= MaxCSNum; ++CSI) {<br>
+    for (auto &LP : CallSiteNumToLPad[CSI]) {<br>
+      LPadList.push_back(LP);<br>
+      InvokeBBs.insert(LP->pred_begin(), LP->pred_end());<br>
+    }<br>
+  }<br>
+<br>
+  assert(!LPadList.empty() &&<br>
+         "No landing pad destinations for the dispatch jump table!");<br>
+<br>
+  // Create the MBBs for the dispatch code.<br>
+<br>
+  // Shove the dispatch's address into the return slot in the function context.<br>
+  MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();<br>
+  DispatchBB->setIsEHPad(true);<br>
+<br>
+  MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();<br>
+  BuildMI(TrapBB, DL, TII->get(X86::TRAP));<br>
+  DispatchBB->addSuccessor(TrapBB);<br>
+<br>
+  MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();<br>
+  DispatchBB->addSuccessor(DispContBB);<br>
+<br>
+  // Insert MBBs.<br>
+  MF->push_back(DispatchBB);<br>
+  MF->push_back(DispContBB);<br>
+  MF->push_back(TrapBB);<br>
+<br>
+  // Insert code into the entry block that creates and registers the function<br>
+  // context.<br>
+  SetupEntryBlockForSjLj(MI, BB, DispatchBB, FI);<br>
+<br>
+  // Create the jump table and associated information<br>
+  MachineJumpTableInfo *JTI =<br>
+      MF->getOrCreateJumpTableInfo(getJumpTableEncoding());<br>
+  unsigned MJTI = JTI->createJumpTableIndex(LPadList);<br>
+<br>
+  const X86InstrInfo *XII = static_cast<const X86InstrInfo *>(TII);<br>
+  const X86RegisterInfo &RI = XII->getRegisterInfo();<br>
+<br>
+  // Add a register mask with no preserved registers.  This results in all<br>
+  // registers being marked as clobbered.<br>
+  if (RI.hasBasePointer(*MF)) {<br>
+    const bool FPIs64Bit =<br>
+        Subtarget.isTarget64BitLP64() || Subtarget.isTargetNaCl64();<br>
+    X86MachineFunctionInfo *MFI = MF->getInfo<X86MachineFunctionInfo>();<br>
+    MFI->setRestoreBasePointer(MF);<br>
+<br>
+    unsigned FP = RI.getFrameRegister(*MF);<br>
+    unsigned BP = RI.getBaseRegister();<br>
+    unsigned Op = FPIs64Bit ? X86::MOV64rm : X86::MOV32rm;<br>
+    addRegOffset(BuildMI(DispatchBB, DL, TII->get(Op), BP), FP, true,<br>
+                 MFI->getRestoreBasePointerOffset())<br>
+        .addRegMask(RI.getNoPreservedMask());<br>
+  } else {<br>
+    BuildMI(DispatchBB, DL, TII->get(X86::NOOP))<br>
+        .addRegMask(RI.getNoPreservedMask());<br>
+  }<br>
+<br>
+  unsigned IReg = MRI->createVirtualRegister(&X86::GR32RegClass);<br>
+  addFrameReference(BuildMI(DispatchBB, DL, TII->get(X86::MOV32rm), IReg), FI,<br>
+                    4);<br>
+  BuildMI(DispatchBB, DL, TII->get(X86::CMP32ri))<br>
+      .addReg(IReg)<br>
+      .addImm(LPadList.size());<br>
+  BuildMI(DispatchBB, DL, TII->get(X86::JA_1)).addMBB(TrapBB);<br>
+<br>
+  unsigned JReg = MRI->createVirtualRegister(&X86::GR32RegClass);<br>
+  BuildMI(DispContBB, DL, TII->get(X86::SUB32ri), JReg)<br>
+      .addReg(IReg)<br>
+      .addImm(1);<br>
+  BuildMI(DispContBB, DL,<br>
+          TII->get(Subtarget.is64Bit() ? X86::JMP64m : X86::JMP32m))<br>
+      .addReg(0)<br>
+      .addImm(Subtarget.is64Bit() ? 8 : 4)<br>
+      .addReg(JReg)<br>
+      .addJumpTableIndex(MJTI)<br>
+      .addReg(0);<br>
+<br>
+  // Add the jump table entries as successors to the MBB.<br>
+  SmallPtrSet<MachineBasicBlock *, 8> SeenMBBs;<br>
+  for (auto &LP : LPadList)<br>
+    if (SeenMBBs.insert(LP).second)<br>
+      DispContBB->addSuccessor(LP);<br>
+<br>
+  // N.B. the order the invoke BBs are processed in doesn't matter here.<br>
+  SmallVector<MachineBasicBlock *, 64> MBBLPads;<br>
+  const MCPhysReg *SavedRegs =<br>
+      Subtarget.getRegisterInfo()->getCalleeSavedRegs(MF);<br>
+  for (MachineBasicBlock *MBB : InvokeBBs) {<br>
+    // Remove the landing pad successor from the invoke block and replace it<br>
+    // with the new dispatch block<br>
+    for (auto MBBS : make_range(MBB->succ_rbegin(), MBB->succ_rend())) {<br>
+      if (MBBS->isEHPad()) {<br>
+        MBB->removeSuccessor(MBBS);<br>
+        MBBLPads.push_back(MBBS);<br>
+      }<br>
+    }<br>
+<br>
+    MBB->addSuccessor(DispatchBB);<br>
+<br>
+    // Find the invoke call and mark all of the callee-saved registers as<br>
+    // 'implicit defined' so that they're spilled.  This prevents code from<br>
+    // moving instructions to before the EH block, where they will never be<br>
+    // executed.<br>
+    for (auto &II : make_range(MBB->rbegin(), MBB->rend())) {<br>
+      if (!II.isCall())<br>
+        continue;<br>
+<br>
+      DenseMap<unsigned, bool> DefRegs;<br>
+      for (auto &MOp : II.operands())<br>
+        if (MOp.isReg())<br>
+          DefRegs[MOp.getReg()] = true;<br>
+<br>
+      MachineInstrBuilder MIB(*MF, &II);<br>
+      for (unsigned RI = 0; SavedRegs[RI]; ++RI) {<br>
+        unsigned Reg = SavedRegs[RI];<br>
+        if (!DefRegs[Reg])<br>
+          MIB.addReg(Reg, RegState::ImplicitDefine | RegState::Dead);<br>
+      }<br>
+<br>
+      break;<br>
+    }<br>
+  }<br>
+<br>
+  // Mark all former landing pads as non-landing pads.  The dispatch is the only<br>
+  // landing pad now.<br>
+  for (auto &LP : MBBLPads)<br>
+    LP->setIsEHPad(false);<br>
+<br>
+  // The instruction is gone now.<br>
+  MI->eraseFromParent();<br>
+  return BB;<br>
+}<br>
+<br>
 // Replace 213-type (isel default) FMA3 instructions with 231-type for<br>
 // accumulator loops. Writing back to the accumulator allows the coalescer<br>
 // to remove extra copies in the loop.<br>
@@ -23917,6 +24173,9 @@ X86TargetLowering::EmitInstrWithCustomIn<br>
   case X86::EH_SjLj_LongJmp64:<br>
     return emitEHSjLjLongJmp(MI, BB);<br>
<br>
+  case X86::Int_eh_sjlj_setup_dispatch:<br>
+    return EmitSjLjDispatchBlock(MI, BB);<br>
+<br>
   case TargetOpcode::STATEPOINT:<br>
     // As an implementation detail, STATEPOINT shares the STACKMAP format at<br>
     // this point in the process.  We diverge later.<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon May 30 20:48:07 2016<br>
@@ -272,6 +272,9 @@ namespace llvm {<br>
       // SjLj exception handling longjmp.<br>
       EH_SJLJ_LONGJMP,<br>
<br>
+      // SjLj exception handling dispatch.<br>
+      EH_SJLJ_SETUP_DISPATCH,<br>
+<br>
       /// Tail call return. See X86TargetLowering::LowerCall for<br>
       /// the list of operands.<br>
       TC_RETURN,<br>
@@ -1093,6 +1096,7 @@ namespace llvm {<br>
     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;<br>
     SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;<br>
     SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;<br>
+    SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;<br>
     SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;<br>
     SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) const;<br>
     SDValue LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) const;<br>
@@ -1148,6 +1152,9 @@ namespace llvm {<br>
<br>
     bool needsCmpXchgNb(Type *MemType) const;<br>
<br>
+    void SetupEntryBlockForSjLj(MachineInstr *MI, MachineBasicBlock *MBB,<br>
+                                MachineBasicBlock *DispatchBB, int FI) const;<br>
+<br>
     // Utility function to emit the low-level va_arg code for X86-64.<br>
     MachineBasicBlock *EmitVAARG64WithCustomInserter(<br>
                        MachineInstr *MI,<br>
@@ -1188,6 +1195,9 @@ namespace llvm {<br>
     MachineBasicBlock *emitFMA3Instr(MachineInstr *MI,<br>
                                      MachineBasicBlock *MBB) const;<br>
<br>
+    MachineBasicBlock *EmitSjLjDispatchBlock(MachineInstr *MI,<br>
+                                             MachineBasicBlock *MBB) const;<br>
+<br>
     /// Emit nodes that will be selected as "test Op0,Op0", or something<br>
     /// equivalent, for use with the given x86 condition code.<br>
     SDValue EmitTest(SDValue Op0, unsigned X86CC, SDLoc dl,<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon May 30 20:48:07 2016<br>
@@ -232,6 +232,9 @@ def X86eh_sjlj_setjmp  : SDNode<"X86ISD:<br>
 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",<br>
                                 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,<br>
                                 [SDNPHasChain, SDNPSideEffect]>;<br>
+def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",<br>
+                                       SDTypeProfile<0, 0, []>,<br>
+                                       [SDNPHasChain, SDNPSideEffect]>;<br>
<br>
 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,<br>
                         [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;<br>
@@ -1086,6 +1089,10 @@ def LEAVE64  : I<0xC9, RawFrm,<br>
 //  Miscellaneous Instructions.<br>
 //<br>
<br>
+let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in<br>
+  def Int_eh_sjlj_setup_dispatch<br>
+    : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;<br>
+<br>
 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {<br>
 let mayLoad = 1, SchedRW = [WriteLoad] in {<br>
 def POP16r  : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],<br>
<br>
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=271244&r1=271243&r2=271244&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=271244&r1=271243&r2=271244&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon May 30 20:48:07 2016<br>
@@ -2388,6 +2388,7 @@ Instruction *InstCombiner::visitExtractV<br>
 static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo) {<br>
   switch (Personality) {<br>
   case EHPersonality::GNU_C:<br>
+  case EHPersonality::GNU_C_SjLj:<br>
   case EHPersonality::Rust:<br>
     // The GCC C EH and Rust personality only exists to support cleanups, so<br>
     // it's not clear what the semantics of catch clauses are.<br>
@@ -2399,6 +2400,7 @@ static bool isCatchAll(EHPersonality Per<br>
     // match foreign exceptions (or didn't, before gcc-4.7).<br>
     return false;<br>
   case EHPersonality::GNU_CXX:<br>
+  case EHPersonality::GNU_CXX_SjLj:<br>
   case EHPersonality::GNU_ObjC:<br>
   case EHPersonality::MSVC_X86SEH:<br>
   case EHPersonality::MSVC_Win64SEH:<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/sjlj-eh.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sjlj-eh.ll?rev=271244&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sjlj-eh.ll?rev=271244&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/sjlj-eh.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/sjlj-eh.ll Mon May 30 20:48:07 2016<br>
@@ -0,0 +1,72 @@<br>
+; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -filetype asm -o - %s | FileCheck %s<br>
+<br>
+declare void @_Z20function_that_throwsv()<br>
+declare i32 @__gxx_personality_sj0(...)<br>
+declare i8* @__cxa_begin_catch(i8*)<br>
+declare void @__cxa_end_catch()<br>
+<br>
+define void @_Z8functionv() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {<br>
+entry:<br>
+  invoke void @_Z20function_that_throwsv()<br>
+          to label %try.cont unwind label %lpad<br>
+<br>
+lpad:<br>
+  %0 = landingpad { i8*, i32 }<br>
+          catch i8* null<br>
+  %1 = extractvalue { i8*, i32 } %0, 0<br>
+  %2 = tail call i8* @__cxa_begin_catch(i8* %1)<br>
+  tail call void @__cxa_end_catch()<br>
+  br label %try.cont<br>
+<br>
+try.cont:<br>
+  ret void<br>
+}<br>
+<br>
+;     struct _Unwind_FunctionContext {<br>
+; +00   struct _Unwind_FunctionContext *prev;   -64(%ebp)<br>
+; +04   uintptr_t __callsite;                   -60(%ebp)<br>
+; +08   uintptr_t __buffer[4];                  -44(%ebp)<br>
+; +28   __personality_routine __personality;    -40(%ebp)<br>
+; +32   uintptr_t __lsda;                       -36(%ebp)<br>
+; +36   void *__jbuf[];                         -32(%ebp)<br>
+;     };<br>
+<br>
+<br>
+; CHECK-LABEL: __Z8functionv:<br>
+;     struct _Unwind_FunctionContext UFC;<br>
+;<br>
+;     UFC.__personality = __gxx_personality_sj0<br>
+; CHECK: movl $___gxx_personality_sj0, -40(%ebp)<br>
+;     UFC.__lsda = $LSDA<br>
+; CHECK: movl $[[LSDA:GCC_except_table[0-9]+]], -36(%ebp)<br>
+;     UFC.__jbuf[0] = $EBP<br>
+; CHECK: movl %ebp, -32(%ebp)<br>
+;     UFC.__jbuf[2] = $ESP<br>
+; CHECK: movl %esp, -24(%ebp)<br>
+;     UFC.__jbuf[1] = $EIP<br>
+; CHECK: movl $[[RESUME:LBB[0-9]+_[0-9]+]], -28(%ebp)<br>
+;     UFC.__callsite = 1<br>
+; CHECK: movl $1, -60(%ebp)<br>
+;     _Unwind_SjLj_Register(&UFC);<br>
+; CHECK: leal -64(%ebp), %eax<br>
+; CHECK: pushl %eax<br>
+; CHECK: calll __Unwind_SjLj_Register<br>
+; CHECK: addl $4, %esp<br>
+;     function_that_throws();<br>
+; CHECK: calll __Z20function_that_throwsv<br>
+;     _Unwind_SjLj_Unregister(&UFC);<br>
+; CHECK: leal -64(%ebp), %eax<br>
+; CHECK: calll __Unwind_SjLj_Unregister<br>
+;<br>
+; CHECK: [[RESUME]]:<br>
+; CHECK: leal -64(%ebp), %esi<br>
+;     assert(UFC.__callsite <= 1);<br>
+; CHECK: movl -60(%ebp), %eax<br>
+; CHECK: cmpl $1, %eax<br>
+; CHECK: jbe [[CONT:LBB[0-9]+_[0-9]+]]<br>
+; CHECK: ud2<br>
+; CHECK: [[CONT]]:<br>
+;     *Handlers[--UFC.__callsite]<br>
+; CHECK: subl $1, %eax<br>
+; CHECK: jmpl *LJTI<br>
+<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>