Index: include/llvm/CodeGen/MachineModuleInfo.h =================================================================== --- include/llvm/CodeGen/MachineModuleInfo.h +++ include/llvm/CodeGen/MachineModuleInfo.h @@ -46,6 +46,13 @@ namespace llvm { +/// Different personality functions used by a function. +enum class EHPersonality { + None, /// No exception handling + Itanium, /// An Itanium C++ EH personality like __gxx_personality_seh0 + Win64SEH, /// __C_specific_handler +}; + //===----------------------------------------------------------------------===// // Forward declarations. class Constant; @@ -169,6 +176,10 @@ /// details. bool UsesMorestackAddr; + EHPersonality PersonalityTypeCache; + + EHPersonality getPersonalityTypeSlow(); + public: static char ID; // Pass identification, replacement for typeid @@ -413,6 +424,13 @@ /// of one is required to emit exception handling info. const Function *getPersonality() const; + /// Classify the personality function amongst known EH styles. + EHPersonality getPersonalityType() { + if (PersonalityTypeCache != EHPersonality::None) + return PersonalityTypeCache; + return getPersonalityTypeSlow(); + } + /// setVariableDbgInfo - Collect information used to emit debugging /// information of a variable. void setVariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot, Index: include/llvm/MC/MCAsmInfo.h =================================================================== --- include/llvm/MC/MCAsmInfo.h +++ include/llvm/MC/MCAsmInfo.h @@ -42,12 +42,11 @@ } enum class ExceptionHandling { - None, /// No exception support - DwarfCFI, /// DWARF-like instruction based exceptions - SjLj, /// setjmp/longjmp based exceptions - ARM, /// ARM EHABI - ItaniumWinEH, /// Itanium EH built on Windows unwind info (.pdata and .xdata) - MSVC, /// MSVC compatible exception handling + None, /// No exception support + DwarfCFI, /// DWARF-like instruction based exceptions + SjLj, /// setjmp/longjmp based exceptions + ARM, /// ARM EHABI + WinEH, /// Windows Exception Handling }; namespace LCOMM { @@ -489,19 +488,15 @@ } ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; } WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; } - - /// Return true if the exception handling type uses the language-specific data - /// area (LSDA) format specified by the Itanium C++ ABI. - bool usesItaniumLSDAForExceptions() const { + bool isExceptionHandlingDwarf() const { return (ExceptionsType == ExceptionHandling::DwarfCFI || ExceptionsType == ExceptionHandling::ARM || - // This Windows EH type uses the Itanium LSDA encoding. - ExceptionsType == ExceptionHandling::ItaniumWinEH); + // Windows handler data still uses DWARF LSDA encoding. + ExceptionsType == ExceptionHandling::WinEH); } bool usesWindowsCFI() const { - return ExceptionsType == ExceptionHandling::ItaniumWinEH || - ExceptionsType == ExceptionHandling::MSVC; + return ExceptionsType == ExceptionHandling::WinEH; } bool doesDwarfUseRelocationsAcrossSections() const { Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -254,8 +254,7 @@ case ExceptionHandling::ARM: ES = new ARMException(this); break; - case ExceptionHandling::ItaniumWinEH: - case ExceptionHandling::MSVC: + case ExceptionHandling::WinEH: switch (MAI->getWinEHEncodingType()) { default: llvm_unreachable("unsupported unwinding information encoding"); case WinEH::EncodingType::Itanium: Index: lib/CodeGen/AsmPrinter/DwarfCFIException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -51,7 +51,7 @@ if (moveTypeModule == AsmPrinter::CFI_M_Debug) Asm->OutStreamer.EmitCFISections(false, true); - if (!Asm->MAI->usesItaniumLSDAForExceptions()) + if (!Asm->MAI->isExceptionHandlingDwarf()) return; const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); Index: lib/CodeGen/AsmPrinter/EHStreamer.cpp =================================================================== --- lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -253,7 +253,7 @@ // instruction between the previous try-range and this one may throw, // create a call-site entry with no landing pad for the region between the // try-ranges. - if (SawPotentiallyThrowing && !IsSJLJ) { + if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { CallSiteEntry Site = { LastLabel, BeginLabel, nullptr, 0 }; CallSites.push_back(Site); PreviousIsInvoke = false; Index: lib/CodeGen/AsmPrinter/Win64Exception.cpp =================================================================== --- lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -105,8 +105,8 @@ // Emit the tables appropriate to the personality function in use. If we // don't recognize the personality, assume it uses an Itanium-style LSDA. - const Function *Per = MMI->getPersonality(); - if (Per->getName() == "__C_specific_handler") + EHPersonality Per = MMI->getPersonalityType(); + if (Per == EHPersonality::Win64) emitCSpecificHandlerTable(); else emitExceptionTable(); Index: lib/CodeGen/MachineModuleInfo.cpp =================================================================== --- lib/CodeGen/MachineModuleInfo.cpp +++ lib/CodeGen/MachineModuleInfo.cpp @@ -276,6 +276,7 @@ DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false; // Always emit some info, by default "no personality" info. Personalities.push_back(nullptr); + PersonalityTypeCache = EHPersonality::None; AddrLabelSymbols = nullptr; TheModule = nullptr; @@ -554,7 +555,21 @@ /// getPersonality - Return the personality function for the current function. const Function *MachineModuleInfo::getPersonality() const { - return !LandingPads.empty() ? LandingPads[0].Personality : nullptr; + for (const LandingPadInfo &LPI : LandingPads) + if (LPI.Personality) + return LPI.Personality; + return nullptr; +} + +EHPersonality MachineModuleInfo::getPersonalityTypeSlow() { + const Function *Per = getPersonality(); + if (!Per) + PersonalityTypeCache = EHPersonality::None; + else if (Per->getName() == "__C_specific_handler") + PersonalityTypeCache = EHPersonality::Win64SEH; + else // Assume everything else is Itanium. + PersonalityTypeCache = EHPersonality::Itanium; + return PersonalityTypeCache; } /// getPersonalityIndex - Return unique index for current personality Index: lib/CodeGen/Passes.cpp =================================================================== --- lib/CodeGen/Passes.cpp +++ lib/CodeGen/Passes.cpp @@ -448,8 +448,7 @@ // FALLTHROUGH case ExceptionHandling::DwarfCFI: case ExceptionHandling::ARM: - case ExceptionHandling::ItaniumWinEH: - case ExceptionHandling::MSVC: // FIXME: Needs preparation. + case ExceptionHandling::WinEH: addPass(createDwarfEHPass(TM)); break; case ExceptionHandling::None: Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -922,8 +922,13 @@ BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II) .addSym(Label); - if (TM.getMCAsmInfo()->getExceptionHandlingType() == - ExceptionHandling::MSVC) { + // If this is an MSVC-style personality function, we need to split the landing + // pad into several BBs. + const BasicBlock *LLVMBB = MBB->getBasicBlock(); + const LandingPadInst *LPadInst = LLVMBB->getLandingPadInst(); + MF->getMMI().addPersonality( + MBB, cast(LPadInst->getPersonalityFn()->stripPointerCasts())); + if (MF->getMMI().getPersonalityType() == EHPersonality::Win64SEH) { // Make virtual registers and a series of labels that fill in values for the // clauses. auto &RI = MF->getRegInfo(); @@ -935,8 +940,6 @@ // Emit separate machine basic blocks with separate labels for each clause // before the main landing pad block. - const BasicBlock *LLVMBB = MBB->getBasicBlock(); - const LandingPadInst *LPadInst = LLVMBB->getLandingPadInst(); MachineInstrBuilder SelectorPHI = BuildMI( *MBB, MBB->begin(), SDB->getCurDebugLoc(), TII->get(TargetOpcode::PHI), FuncInfo->ExceptionSelectorVirtReg); Index: lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp +++ lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp @@ -132,9 +132,7 @@ PrivateLabelPrefix = ".L"; PointerSize = 8; WinEHEncodingType = WinEH::EncodingType::Itanium; - - // Use MSVC-compatible EH data. - ExceptionsType = ExceptionHandling::MSVC; + ExceptionsType = ExceptionHandling::WinEH; } AssemblerDialect = AsmWriterFlavor; @@ -155,7 +153,7 @@ PrivateLabelPrefix = ".L"; PointerSize = 8; WinEHEncodingType = WinEH::EncodingType::Itanium; - ExceptionsType = ExceptionHandling::ItaniumWinEH; + ExceptionsType = ExceptionHandling::WinEH; } else { ExceptionsType = ExceptionHandling::DwarfCFI; }