[llvm] r226920 - Classify functions by EH personality type rather than using the triple

Reid Kleckner reid at kleckner.net
Fri Jan 23 10:49:02 PST 2015


Author: rnk
Date: Fri Jan 23 12:49:01 2015
New Revision: 226920

URL: http://llvm.org/viewvc/llvm-project?rev=226920&view=rev
Log:
Classify functions by EH personality type rather than using the triple

This mostly reverts commit r222062 and replaces it with a new enum. At
some point this enum will grow at least for other MSVC EH personalities.

Also beefs up the way we were sniffing the personality function.
Previously we would emit the Itanium LSDA despite using
__C_specific_handler.

Reviewers: majnemer

Differential Revision: http://reviews.llvm.org/D6987

Added:
    llvm/trunk/test/CodeGen/X86/seh-finally.ll   (with props)
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
    llvm/trunk/include/llvm/MC/MCAsmInfo.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp
    llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
    llvm/trunk/lib/CodeGen/Passes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Fri Jan 23 12:49:01 2015
@@ -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, /// x86_64 SEH, uses __C_specific_handler
+};
+
 //===----------------------------------------------------------------------===//
 // Forward declarations.
 class Constant;
@@ -169,6 +176,10 @@ class MachineModuleInfo : public Immutab
   /// details.
   bool UsesMorestackAddr;
 
+  EHPersonality PersonalityTypeCache;
+
+  EHPersonality getPersonalityTypeSlow();
+
 public:
   static char ID; // Pass identification, replacement for typeid
 
@@ -413,6 +424,13 @@ public:
   /// 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,

Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Fri Jan 23 12:49:01 2015
@@ -42,12 +42,11 @@ enum class EncodingType {
 }
 
 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 {
@@ -490,18 +489,16 @@ public:
   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 {
+  /// Returns true if the exception handling method for the platform uses call
+  /// frame information to unwind.
+  bool usesCFIForEH() const {
     return (ExceptionsType == ExceptionHandling::DwarfCFI ||
             ExceptionsType == ExceptionHandling::ARM ||
-            // This Windows EH type uses the Itanium LSDA encoding.
-            ExceptionsType == ExceptionHandling::ItaniumWinEH);
+            ExceptionsType == ExceptionHandling::WinEH);
   }
 
   bool usesWindowsCFI() const {
-    return ExceptionsType == ExceptionHandling::ItaniumWinEH ||
-           ExceptionsType == ExceptionHandling::MSVC;
+    return ExceptionsType == ExceptionHandling::WinEH;
   }
 
   bool doesDwarfUseRelocationsAcrossSections() const {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Fri Jan 23 12:49:01 2015
@@ -254,8 +254,7 @@ bool AsmPrinter::doInitialization(Module
   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:

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp Fri Jan 23 12:49:01 2015
@@ -51,7 +51,8 @@ void DwarfCFIException::endModule() {
   if (moveTypeModule == AsmPrinter::CFI_M_Debug)
     Asm->OutStreamer.EmitCFISections(false, true);
 
-  if (!Asm->MAI->usesItaniumLSDAForExceptions())
+  // SjLj uses this pass and it doesn't need this info.
+  if (!Asm->MAI->usesCFIForEH())
     return;
 
   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp Fri Jan 23 12:49:01 2015
@@ -253,7 +253,7 @@ computeCallSiteTable(SmallVectorImpl<Cal
       // 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->usesCFIForEH()) {
         CallSiteEntry Site = { LastLabel, BeginLabel, nullptr, 0 };
         CallSites.push_back(Site);
         PreviousIsInvoke = false;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/Win64Exception.cpp Fri Jan 23 12:49:01 2015
@@ -105,8 +105,8 @@ void Win64Exception::endFunction(const M
 
     // 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 && Per->getName() == "__C_specific_handler")
+    EHPersonality Per = MMI->getPersonalityType();
+    if (Per == EHPersonality::Win64SEH)
       emitCSpecificHandlerTable();
     else
       emitExceptionTable();

Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Fri Jan 23 12:49:01 2015
@@ -276,6 +276,7 @@ bool MachineModuleInfo::doInitialization
   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 @@ try_next:;
 
 /// 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

Modified: llvm/trunk/lib/CodeGen/Passes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/Passes.cpp (original)
+++ llvm/trunk/lib/CodeGen/Passes.cpp Fri Jan 23 12:49:01 2015
@@ -447,8 +447,7 @@ void TargetPassConfig::addPassesToHandle
     // 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:

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jan 23 12:49:01 2015
@@ -924,8 +924,13 @@ void SelectionDAGISel::PrepareEHLandingP
   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<Function>(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();
@@ -937,8 +942,6 @@ void SelectionDAGISel::PrepareEHLandingP
 
     // 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);

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp?rev=226920&r1=226919&r2=226920&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp Fri Jan 23 12:49:01 2015
@@ -132,9 +132,7 @@ X86MCAsmInfoMicrosoft::X86MCAsmInfoMicro
     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 @@ X86MCAsmInfoGNUCOFF::X86MCAsmInfoGNUCOFF
     PrivateLabelPrefix = ".L";
     PointerSize = 8;
     WinEHEncodingType = WinEH::EncodingType::Itanium;
-    ExceptionsType = ExceptionHandling::ItaniumWinEH;
+    ExceptionsType = ExceptionHandling::WinEH;
   } else {
     ExceptionsType = ExceptionHandling::DwarfCFI;
   }

Added: llvm/trunk/test/CodeGen/X86/seh-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-finally.ll?rev=226920&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-finally.ll (added)
+++ llvm/trunk/test/CodeGen/X86/seh-finally.ll Fri Jan 23 12:49:01 2015
@@ -0,0 +1,45 @@
+; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
+
+ at str_recovered = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
+
+declare void @crash()
+
+define i32 @main() {
+entry:
+  invoke void @crash()
+          to label %invoke.cont unwind label %lpad
+
+invoke.cont:                                      ; preds = %entry
+  %call = call i32 @puts(i8* getelementptr inbounds ([10 x i8]* @str_recovered, i64 0, i64 0))
+  call void @abort()
+  ret i32 0
+
+lpad:                                             ; preds = %entry
+  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+          cleanup
+  %1 = extractvalue { i8*, i32 } %0, 0
+  %2 = extractvalue { i8*, i32 } %0, 1
+  %call2 = invoke i32 @puts(i8* getelementptr inbounds ([10 x i8]* @str_recovered, i64 0, i64 0))
+          to label %invoke.cont1 unwind label %terminate.lpad
+
+invoke.cont1:                                     ; preds = %lpad
+  resume { i8*, i32 } %0
+
+terminate.lpad:                                   ; preds = %lpad
+  %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+          catch i8* null
+  call void @abort()
+  unreachable
+}
+
+; CHECK: main:
+
+; FIXME: No handlers yet!
+; CHECK: .seh_handlerdata
+; CHECK-NEXT: .long 0
+
+declare i32 @__C_specific_handler(...)
+
+declare i32 @puts(i8*)
+
+declare void @abort()

Propchange: llvm/trunk/test/CodeGen/X86/seh-finally.ll
------------------------------------------------------------------------------
    svn:executable = *





More information about the llvm-commits mailing list