[llvm] r242185 - [CodeGen] Force emission of personality directive if explicitly specified

Keno Fischer kfischer at college.harvard.edu
Tue Jul 14 12:22:51 PDT 2015


Author: kfischer
Date: Tue Jul 14 14:22:51 2015
New Revision: 242185

URL: http://llvm.org/viewvc/llvm-project?rev=242185&view=rev
Log:
[CodeGen] Force emission of personality directive if explicitly specified

Summary:
Before this change, personality directives were not emitted
if there was no invoke left in the function (of course until
recently this also meant that we couldn't know what
the personality actually was). This patch forces personality directives
to still be emitted, unless it is known to be a noop in the absence of
invokes, or the user explicitly specified `nounwind` (and not
`uwtable`) on the function.

Reviewers: majnemer, rnk

Subscribers: rnk, llvm-commits

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

Added:
    llvm/trunk/test/CodeGen/X86/eh-nolandingpads.ll
Modified:
    llvm/trunk/include/llvm/Analysis/LibCallSemantics.h
    llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
    llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp

Modified: llvm/trunk/include/llvm/Analysis/LibCallSemantics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LibCallSemantics.h?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LibCallSemantics.h (original)
+++ llvm/trunk/include/llvm/Analysis/LibCallSemantics.h Tue Jul 14 14:22:51 2015
@@ -206,6 +206,18 @@ class InvokeInst;
     llvm_unreachable("invalid enum");
   }
 
+  /// \brief Return true if this personality may be safely removed if there
+  /// are no invoke instructions remaining in the current function.
+  inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
+    switch (Pers) {
+    case EHPersonality::Unknown:
+      return false;
+    // All known personalities currently have this behavior
+    default: return true;
+    }
+    llvm_unreachable("invalid enum");
+  }
+
   bool canSimplifyInvokeNoUnwind(const Function *F);
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Tue Jul 14 14:22:51 2015
@@ -320,6 +320,7 @@ public:
   /// information.
   void addPersonality(MachineBasicBlock *LandingPad,
                       const Function *Personality);
+  void addPersonality(const Function *Personality);
 
   void addWinEHState(MachineBasicBlock *LandingPad, int State);
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/ARMException.cpp Tue Jul 14 14:22:51 2015
@@ -69,24 +69,32 @@ void ARMException::beginFunction(const M
 ///
 void ARMException::endFunction(const MachineFunction *MF) {
   ARMTargetStreamer &ATS = getTargetStreamer();
+  const Function *F = MF->getFunction();
+  const Function *Per = nullptr;
+  if (F->hasPersonalityFn())
+    Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+  assert(!MMI->getPersonality() || Per == MMI->getPersonality());
+  bool forceEmitPersonality =
+    F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+    F->needsUnwindTableEntry();
+  bool shouldEmitPersonality = forceEmitPersonality ||
+    !MMI->getLandingPads().empty();
   if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
-      MMI->getLandingPads().empty())
+      !shouldEmitPersonality)
     ATS.emitCantUnwind();
-  else {
-    if (!MMI->getLandingPads().empty()) {
-      // Emit references to personality.
-      if (const Function *Personality = MMI->getPersonality()) {
-        MCSymbol *PerSym = Asm->getSymbol(Personality);
-        Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
-        ATS.emitPersonality(PerSym);
-      }
+  else if (shouldEmitPersonality) {
+    // Emit references to personality.
+    if (Per) {
+      MCSymbol *PerSym = Asm->getSymbol(Per);
+      Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
+      ATS.emitPersonality(PerSym);
+    }
 
-      // Emit .handlerdata directive.
-      ATS.emitHandlerData();
+    // Emit .handlerdata directive.
+    ATS.emitHandlerData();
 
-      // Emit actual exception table
-      emitExceptionTable();
-    }
+    // Emit actual exception table
+    emitExceptionTable();
   }
 
   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp Tue Jul 14 14:22:51 2015
@@ -89,6 +89,7 @@ void DwarfCFIException::endModule() {
 
 void DwarfCFIException::beginFunction(const MachineFunction *MF) {
   shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
+  const Function *F = MF->getFunction();
 
   // If any landing pads survive, we need an EH table.
   bool hasLandingPads = !MMI->getLandingPads().empty();
@@ -104,10 +105,24 @@ void DwarfCFIException::beginFunction(co
 
   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
   unsigned PerEncoding = TLOF.getPersonalityEncoding();
-  const Function *Per = MMI->getPersonality();
-
-  shouldEmitPersonality = hasLandingPads &&
-    PerEncoding != dwarf::DW_EH_PE_omit && Per;
+  const Function *Per = nullptr;
+  if (F->hasPersonalityFn())
+    Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+  assert(!MMI->getPersonality() || Per == MMI->getPersonality());
+
+  // Emit a personality function even when there are no landing pads
+  bool forceEmitPersonality =
+      // ...if a personality function is explicitly specified
+      F->hasPersonalityFn() &&
+      // ... and it's not known to be a noop in the absence of invokes
+      !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+      // ... and we're not explicitly asked not to emit it
+      F->needsUnwindTableEntry();
+
+  shouldEmitPersonality =
+      (forceEmitPersonality ||
+       (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
+      Per;
 
   unsigned LSDAEncoding = TLOF.getLSDAEncoding();
   shouldEmitLSDA = shouldEmitPersonality &&
@@ -123,6 +138,11 @@ void DwarfCFIException::beginFunction(co
   if (!shouldEmitPersonality)
     return;
 
+  // If we are forced to emit this personality, make sure to record
+  // it because it might not appear in any landingpad
+  if (forceEmitPersonality)
+    MMI->addPersonality(Per);
+
   const MCSymbol *Sym =
       TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
   Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/EHStreamer.cpp Tue Jul 14 14:22:51 2015
@@ -309,7 +309,7 @@ computeCallSiteTable(SmallVectorImpl<Cal
   // If some instruction between the previous try-range and the end of the
   // function may throw, create a call-site entry with no landing pad for the
   // region following the try-range.
-  if (SawPotentiallyThrowing && !IsSJLJ) {
+  if (SawPotentiallyThrowing && !IsSJLJ && LastLabel != nullptr) {
     CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 };
     CallSites.push_back(Site);
   }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Tue Jul 14 14:22:51 2015
@@ -74,8 +74,12 @@ void WinException::beginFunction(const M
   if (F->hasPersonalityFn())
     Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
 
-  shouldEmitPersonality = hasLandingPads &&
-    PerEncoding != dwarf::DW_EH_PE_omit && Per;
+  bool forceEmitPersonality =
+    F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+    F->needsUnwindTableEntry();
+
+  shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
+    PerEncoding != dwarf::DW_EH_PE_omit && Per);
 
   unsigned LSDAEncoding = TLOF.getLSDAEncoding();
   shouldEmitLSDA = shouldEmitPersonality &&

Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=242185&r1=242184&r2=242185&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Tue Jul 14 14:22:51 2015
@@ -320,7 +320,10 @@ void MachineModuleInfo::addPersonality(M
                                        const Function *Personality) {
   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
   LP.Personality = Personality;
+  addPersonality(Personality);
+}
 
+void MachineModuleInfo::addPersonality(const Function *Personality) {
   for (unsigned i = 0; i < Personalities.size(); ++i)
     if (Personalities[i] == Personality)
       return;

Added: llvm/trunk/test/CodeGen/X86/eh-nolandingpads.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/eh-nolandingpads.ll?rev=242185&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/eh-nolandingpads.ll (added)
+++ llvm/trunk/test/CodeGen/X86/eh-nolandingpads.ll Tue Jul 14 14:22:51 2015
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s
+; Test that we emit functions with explicitly specified personality,
+; even if no landing pads are left.
+
+declare i32 @__my_personality_v0(...)
+declare void @might_throw()
+
+define i32 @foo() personality i32 (...)* @__my_personality_v0 {
+; CHECK: .cfi_personality 3, __my_personality_v0
+    call void @might_throw()
+    ret i32 0
+}





More information about the llvm-commits mailing list