[llvm] r217176 - MC Win64: Put unwind info for COMDAT code into the same COMDAT group

Reid Kleckner reid at kleckner.net
Thu Sep 4 10:42:03 PDT 2014


Author: rnk
Date: Thu Sep  4 12:42:03 2014
New Revision: 217176

URL: http://llvm.org/viewvc/llvm-project?rev=217176&view=rev
Log:
MC Win64: Put unwind info for COMDAT code into the same COMDAT group

Summary:
This fixes a long standing issue where we would emit many little .text
sections and only one .pdata and .xdata section. Now we generate one
.pdata / .xdata pair per .text section and associate them correctly.

Fixes PR19667.

Reviewers: majnemer

Subscribers: llvm-commits

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

Added:
    llvm/trunk/test/MC/COFF/seh-linkonce.s
Modified:
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCWinEH.h
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCWin64EH.cpp
    llvm/trunk/lib/MC/MCWinEH.cpp

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Thu Sep  4 12:42:03 2014
@@ -284,6 +284,13 @@ namespace llvm {
 
     const MCSectionCOFF *getCOFFSection(StringRef Section);
 
+    /// Gets or creates a section equivalent to Sec that is associated with the
+    /// section containing KeySym. For example, to create a debug info section
+    /// associated with an inline function, pass the normal debug info section
+    /// as Sec and the function symbol as KeySym.
+    const MCSectionCOFF *getAssociativeCOFFSection(const MCSectionCOFF *Sec,
+                                                   const MCSymbol *KeySym);
+
     /// @}
 
     /// @name Dwarf Management

Modified: llvm/trunk/include/llvm/MC/MCWinEH.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCWinEH.h?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCWinEH.h (original)
+++ llvm/trunk/include/llvm/MC/MCWinEH.h Thu Sep  4 12:42:03 2014
@@ -65,9 +65,10 @@ struct FrameInfo {
 
 class UnwindEmitter {
 public:
-  static StringRef GetSectionSuffix(const MCSymbol *Function);
-  static const MCSection *GetPDataSection(StringRef Suffix, MCContext &Context);
-  static const MCSection *GetXDataSection(StringRef Suffix, MCContext &Context);
+  static const MCSection *getPDataSection(const MCSymbol *Function,
+                                          MCContext &Context);
+  static const MCSection *getXDataSection(const MCSymbol *Function,
+                                          MCContext &Context);
 
   virtual ~UnwindEmitter() { }
 

Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thu Sep  4 12:42:03 2014
@@ -967,29 +967,14 @@ emitModuleFlags(MCStreamer &Streamer,
   }
 }
 
-static const MCSection *getAssociativeCOFFSection(MCContext &Ctx,
-                                                  const MCSection *Sec,
-                                                  const MCSymbol *KeySym) {
-  // Return the normal section if we don't have to be associative.
-  if (!KeySym)
-    return Sec;
-
-  // Make an associative section with the same name and kind as the normal
-  // section.
-  const MCSectionCOFF *SecCOFF = cast<MCSectionCOFF>(Sec);
-  unsigned Characteristics =
-      SecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
-  return Ctx.getCOFFSection(SecCOFF->getSectionName(), Characteristics,
-                            SecCOFF->getKind(), KeySym->getName(),
-                            COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
-}
-
 const MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
     unsigned Priority, const MCSymbol *KeySym) const {
-  return getAssociativeCOFFSection(getContext(), StaticCtorSection, KeySym);
+  return getContext().getAssociativeCOFFSection(
+      cast<MCSectionCOFF>(StaticCtorSection), KeySym);
 }
 
 const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
     unsigned Priority, const MCSymbol *KeySym) const {
-  return getAssociativeCOFFSection(getContext(), StaticDtorSection, KeySym);
+  return getContext().getAssociativeCOFFSection(
+      cast<MCSectionCOFF>(StaticDtorSection), KeySym);
 }

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Sep  4 12:42:03 2014
@@ -1095,9 +1095,8 @@ void MCAsmStreamer::EmitWinEHHandlerData
   // We only do this so the section switch that terminates the handler
   // data block is visible.
   WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
-  StringRef Suffix = WinEH::UnwindEmitter::GetSectionSuffix(CurFrame->Function);
-  if (const MCSection *XData =
-          WinEH::UnwindEmitter::GetXDataSection(Suffix, getContext()))
+  if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
+          CurFrame->Function, getContext()))
     SwitchSectionNoChange(XData);
 
   OS << "\t.seh_handlerdata";

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Thu Sep  4 12:42:03 2014
@@ -317,6 +317,22 @@ const MCSectionCOFF *MCContext::getCOFFS
   return Iter->second;
 }
 
+const MCSectionCOFF *
+MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec,
+                                     const MCSymbol *KeySym) {
+  // Return the normal section if we don't have to be associative.
+  if (!KeySym)
+    return Sec;
+
+  // Make an associative section with the same name and kind as the normal
+  // section.
+  unsigned Characteristics =
+      Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
+  return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
+                        KeySym->getName(),
+                        COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+}
+
 //===----------------------------------------------------------------------===//
 // Dwarf Management
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/MC/MCWin64EH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWin64EH.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWin64EH.cpp (original)
+++ llvm/trunk/lib/MC/MCWin64EH.cpp Thu Sep  4 12:42:03 2014
@@ -225,7 +225,7 @@ void UnwindEmitter::Emit(MCStreamer &Str
   // Emit the unwind info structs first.
   for (const auto &CFI : Streamer.getWinFrameInfos()) {
     const MCSection *XData =
-        GetXDataSection(GetSectionSuffix(CFI->Function), Context);
+        getXDataSection(CFI->Function, Context);
     Streamer.SwitchSection(XData);
     EmitUnwindInfo(Streamer, CFI);
   }
@@ -233,7 +233,7 @@ void UnwindEmitter::Emit(MCStreamer &Str
   // Now emit RUNTIME_FUNCTION entries.
   for (const auto &CFI : Streamer.getWinFrameInfos()) {
     const MCSection *PData =
-        GetPDataSection(GetSectionSuffix(CFI->Function), Context);
+        getPDataSection(CFI->Function, Context);
     Streamer.SwitchSection(PData);
     EmitRuntimeFunction(Streamer, CFI);
   }
@@ -245,7 +245,7 @@ void UnwindEmitter::EmitUnwindInfo(MCStr
   // here and from Emit().
   MCContext &context = Streamer.getContext();
   const MCSection *xdataSect =
-    GetXDataSection(GetSectionSuffix(info->Function), context);
+    getXDataSection(info->Function, context);
   Streamer.SwitchSection(xdataSect);
 
   llvm::EmitUnwindInfo(Streamer, info);

Modified: llvm/trunk/lib/MC/MCWinEH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWinEH.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWinEH.cpp (original)
+++ llvm/trunk/lib/MC/MCWinEH.cpp Thu Sep  4 12:42:03 2014
@@ -17,27 +17,7 @@
 
 namespace llvm {
 namespace WinEH {
-const MCSection *UnwindEmitter::GetPDataSection(StringRef Suffix,
-                                                MCContext &Context) {
-  if (Suffix.empty())
-    return Context.getObjectFileInfo()->getPDataSection();
-  return Context.getCOFFSection((".pdata" + Suffix).str(),
-                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                                COFF::IMAGE_SCN_MEM_READ,
-                                SectionKind::getDataRel());
-}
-
-const MCSection *UnwindEmitter::GetXDataSection(StringRef Suffix,
-                                                MCContext &Context) {
-  if (Suffix.empty())
-    return Context.getObjectFileInfo()->getXDataSection();
-  return Context.getCOFFSection((".xdata" + Suffix).str(),
-                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                                COFF::IMAGE_SCN_MEM_READ,
-                                SectionKind::getDataRel());
-}
-
-StringRef UnwindEmitter::GetSectionSuffix(const MCSymbol *Function) {
+static StringRef getSectionSuffix(const MCSymbol *Function) {
   if (!Function || !Function->isInSection())
     return "";
 
@@ -59,6 +39,46 @@ StringRef UnwindEmitter::GetSectionSuffi
 
   return "";
 }
+
+static const MCSection *getUnwindInfoSection(
+    StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function,
+    MCContext &Context) {
+  // If Function is in a COMDAT, get or create an unwind info section in that
+  // COMDAT group.
+  if (Function && Function->isInSection()) {
+    const MCSectionCOFF *FunctionSection =
+        cast<MCSectionCOFF>(&Function->getSection());
+    if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
+      return Context.getAssociativeCOFFSection(
+          UnwindSec, FunctionSection->getCOMDATSymbol());
+    }
+  }
+
+  // If Function is in a section other than .text, create a new .pdata section.
+  // Otherwise use the plain .pdata section.
+  StringRef Suffix = getSectionSuffix(Function);
+  if (Suffix.empty())
+    return UnwindSec;
+  return Context.getCOFFSection((SecName + Suffix).str(),
+                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                                COFF::IMAGE_SCN_MEM_READ,
+                                SectionKind::getDataRel());
+}
+
+const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
+                                                MCContext &Context) {
+  const MCSectionCOFF *PData =
+      cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
+  return getUnwindInfoSection(".pdata", PData, Function, Context);
+}
+
+const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
+                                                MCContext &Context) {
+  const MCSectionCOFF *XData =
+      cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
+  return getUnwindInfoSection(".xdata", XData, Function, Context);
+}
+
 }
 }
 

Added: llvm/trunk/test/MC/COFF/seh-linkonce.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/seh-linkonce.s?rev=217176&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/seh-linkonce.s (added)
+++ llvm/trunk/test/MC/COFF/seh-linkonce.s Thu Sep  4 12:42:03 2014
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -sections -section-symbols | FileCheck %s
+
+        .text
+        .def     weak_func;
+        .scl    2;
+        .type   32;
+        .endef
+        .section        .text,"xr",discard,weak_func
+        .globl  weak_func
+        .align  16, 0x90
+weak_func:                              # @weak_func
+.Ltmp0:
+.seh_proc weak_func
+# BB#0:                                 # %entry
+        pushq   %rbp
+.Ltmp1:
+        .seh_pushreg 5
+        movq    %rsp, %rbp
+.Ltmp2:
+        .seh_setframe 5, 0
+.Ltmp3:
+        .seh_endprologue
+        xorl    %eax, %eax
+        popq    %rbp
+        retq
+.Leh_func_end0:
+.Ltmp4:
+        .seh_endproc
+
+// CHECK: Sections [
+// CHECK:   Section {
+// CHECK:     Name: .text
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: .data
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: .bss
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Number: [[TEXT_SECNUM:[0-9]+]]
+// CHECK:     Name: .text
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Number: [[XDATA_SECNUM:[0-9]+]]
+// CHECK:     Name: .xdata
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:     Symbols [
+// CHECK:       Symbol {
+// CHECK:         Name: .xdata
+// CHECK:         Section: .xdata ([[XDATA_SECNUM]])
+// CHECK:         StorageClass: Static (0x3)
+// CHECK:         AuxSymbolCount: 1
+// CHECK:         AuxSectionDef {
+// CHECK:           Selection: Associative (0x5)
+// CHECK:           AssocSection: .text ([[TEXT_SECNUM]])
+// CHECK:         }
+// CHECK:       }
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Number: [[PDATA_SECNUM:[0-9]+]]
+// CHECK:     Name: .pdata
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:     Symbols [
+// CHECK:       Symbol {
+// CHECK:         Name: .pdata
+// CHECK:         Section: .pdata ([[PDATA_SECNUM]])
+// CHECK:         StorageClass: Static (0x3)
+// CHECK:         AuxSymbolCount: 1
+// CHECK:         AuxSectionDef {
+// CHECK:           Selection: Associative (0x5)
+// CHECK:           AssocSection: .text ([[TEXT_SECNUM]])
+// CHECK:         }
+// CHECK:       }
+// CHECK:     ]
+// CHECK:   }
+// CHECK: ]





More information about the llvm-commits mailing list