[llvm-branch-commits] [llvm-branch] r195822 - Merging r195148:

Bill Wendling isanbard at gmail.com
Tue Nov 26 22:44:18 PST 2013


Author: void
Date: Wed Nov 27 00:44:18 2013
New Revision: 195822

URL: http://llvm.org/viewvc/llvm-project?rev=195822&view=rev
Log:
Merging r195148:
------------------------------------------------------------------------
r195148 | rafael | 2013-11-19 11:52:52 -0800 (Tue, 19 Nov 2013) | 15 lines

Support multiple COFF sections with the same name but different COMDAT.

This is the first step to fix pr17918.

It extends the .section directive a bit, inspired by what the ELF one looks
like. The problem with using linkonce is that given

.section foo
.linkonce....

.section foo
.linkonce

we would already have switched sections when getting to .linkonce. The cleanest
solution seems to be to add the comdat information in the .section itself.
------------------------------------------------------------------------

Added:
    llvm/branches/release_34/test/MC/COFF/section-comdat.s
      - copied unchanged from r195148, llvm/trunk/test/MC/COFF/section-comdat.s
Modified:
    llvm/branches/release_34/   (props changed)
    llvm/branches/release_34/docs/Extensions.rst
    llvm/branches/release_34/include/llvm/MC/MCContext.h
    llvm/branches/release_34/include/llvm/MC/MCSectionCOFF.h
    llvm/branches/release_34/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/branches/release_34/lib/MC/MCContext.cpp
    llvm/branches/release_34/lib/MC/MCParser/COFFAsmParser.cpp
    llvm/branches/release_34/lib/MC/WinCOFFStreamer.cpp

Propchange: llvm/branches/release_34/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Nov 27 00:44:18 2013
@@ -1,3 +1,3 @@
 /llvm/branches/Apple/Pertwee:110850,110961
 /llvm/branches/type-system-rewrite:133420-134817
-/llvm/trunk:155241,195092-195094,195100,195102-195103,195118,195129,195136,195138,195152,195156-195157,195161-195162,195193,195272,195317-195318,195327,195330,195333,195339,195343,195355,195364,195379,195397-195399,195408,195421,195423-195424,195432,195439,195444,195455-195456,195469,195476-195477,195479,195491-195493,195514,195528,195547,195567,195591,195599,195632,195635-195636,195670,195679,195682,195684,195713,195716,195769,195773,195779,195791
+/llvm/trunk:155241,195092-195094,195100,195102-195103,195118,195129,195136,195138,195148,195152,195156-195157,195161-195162,195193,195272,195317-195318,195327,195330,195333,195339,195343,195355,195364,195379,195397-195399,195408,195421,195423-195424,195432,195439,195444,195455-195456,195469,195476-195477,195479,195491-195493,195514,195528,195547,195567,195591,195599,195632,195635-195636,195670,195679,195682,195684,195713,195716,195769,195773,195779,195791

Modified: llvm/branches/release_34/docs/Extensions.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/docs/Extensions.rst?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/docs/Extensions.rst (original)
+++ llvm/branches/release_34/docs/Extensions.rst Wed Nov 27 00:44:18 2013
@@ -105,3 +105,41 @@ Supported COMDAT types:
   .section .xdata$foo
   .linkonce associative .text$foo
     ...
+
+``.section`` Directive
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+MC supports passing the information in ``.linkonce`` at the end of
+``.section``. For example,  these two codes are equivalent
+
+.. code-block:: gas
+
+  .section secName, "dr", discard, "Symbol1"
+  .globl Symbol1
+  Symbol1:
+  .long 1
+
+.. code-block:: gas
+
+  .section secName, "dr"
+  .linkonce discard
+  .globl Symbol1
+  Symbol1:
+  .long 1
+
+Note that in the combined form the COMDAT symbol is explict. This
+extension exits to support multiple sections with the same name in
+different comdats:
+
+
+.. code-block:: gas
+
+  .section secName, "dr", discard, "Symbol1"
+  .globl Symbol1
+  Symbol1:
+  .long 1
+
+  .section secName, "dr", discard, "Symbol2"
+  .globl Symbol2
+  Symbol2:
+  .long 1

Modified: llvm/branches/release_34/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/include/llvm/MC/MCContext.h?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/include/llvm/MC/MCContext.h (original)
+++ llvm/branches/release_34/include/llvm/MC/MCContext.h Wed Nov 27 00:44:18 2013
@@ -258,9 +258,15 @@ namespace llvm {
 
     const MCSectionCOFF *getCOFFSection(StringRef Section,
                                         unsigned Characteristics,
-                                        SectionKind Kind, int Selection = 0,
+                                        SectionKind Kind,
+                                        StringRef COMDATSymName,
+                                        int Selection,
                                         const MCSectionCOFF *Assoc = 0);
 
+    const MCSectionCOFF *getCOFFSection(StringRef Section,
+                                        unsigned Characteristics,
+                                        SectionKind Kind);
+
     const MCSectionCOFF *getCOFFSection(StringRef Section);
 
     /// @}

Modified: llvm/branches/release_34/include/llvm/MC/MCSectionCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/include/llvm/MC/MCSectionCOFF.h?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/include/llvm/MC/MCSectionCOFF.h (original)
+++ llvm/branches/release_34/include/llvm/MC/MCSectionCOFF.h Wed Nov 27 00:44:18 2013
@@ -19,6 +19,7 @@
 #include "llvm/Support/COFF.h"
 
 namespace llvm {
+class MCSymbol;
 
 /// MCSectionCOFF - This represents a section on Windows
   class MCSectionCOFF : public MCSection {
@@ -32,6 +33,11 @@ namespace llvm {
     /// drawn from the enums below.
     mutable unsigned Characteristics;
 
+    /// The COMDAT symbol of this section. Only valid if this is a COMDAT
+    /// section. Two COMDAT sections are merged if they have the same
+    /// COMDAT symbol.
+    const MCSymbol *COMDATSymbol;
+
     /// Selection - This is the Selection field for the section symbol, if
     /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
     mutable int Selection;
@@ -44,9 +50,11 @@ namespace llvm {
   private:
     friend class MCContext;
     MCSectionCOFF(StringRef Section, unsigned Characteristics,
-                  int Selection, const MCSectionCOFF *Assoc, SectionKind K)
-      : MCSection(SV_COFF, K), SectionName(Section),
-        Characteristics(Characteristics), Selection(Selection), Assoc(Assoc) {
+                  const MCSymbol *COMDATSymbol, int Selection,
+                  const MCSectionCOFF *Assoc, SectionKind K)
+        : MCSection(SV_COFF, K), SectionName(Section),
+          Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
+          Selection(Selection), Assoc(Assoc) {
       assert ((Characteristics & 0x00F00000) == 0 &&
         "alignment must not be set upon section creation");
       assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==

Modified: llvm/branches/release_34/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/branches/release_34/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Wed Nov 27 00:44:18 2013
@@ -733,6 +733,7 @@ getExplicitSectionGlobal(const GlobalVal
   return getContext().getCOFFSection(Name,
                                      Characteristics,
                                      Kind,
+                                     "",
                                      Selection);
 }
 
@@ -768,7 +769,7 @@ SelectSectionForGlobal(const GlobalValue
     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
 
     return getContext().getCOFFSection(Name.str(), Characteristics,
-                                       Kind, COFF::IMAGE_COMDAT_SELECT_ANY);
+                                       Kind, "", COFF::IMAGE_COMDAT_SELECT_ANY);
   }
 
   if (Kind.isText())

Modified: llvm/branches/release_34/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/lib/MC/MCContext.cpp?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/lib/MC/MCContext.cpp (original)
+++ llvm/branches/release_34/lib/MC/MCContext.cpp Wed Nov 27 00:44:18 2013
@@ -34,8 +34,7 @@ typedef std::pair<std::string, std::stri
 
 typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
 typedef std::map<SectionGroupPair, const MCSectionELF *> ELFUniqueMapTy;
-typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
-
+typedef std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniqueMapTy;
 
 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
                      const MCObjectFileInfo *mofi, const SourceMgr *mgr,
@@ -280,32 +279,51 @@ const MCSectionELF *MCContext::CreateELF
   return Result;
 }
 
-const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
-                                               unsigned Characteristics,
-                                               SectionKind Kind, int Selection,
-                                               const MCSectionCOFF *Assoc) {
+const MCSectionCOFF *
+MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
+                          SectionKind Kind, StringRef COMDATSymName,
+                          int Selection, const MCSectionCOFF *Assoc) {
   if (COFFUniquingMap == 0)
     COFFUniquingMap = new COFFUniqueMapTy();
   COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
 
   // Do the lookup, if we have a hit, return it.
-  StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
-  if (Entry.getValue()) return Entry.getValue();
 
-  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
-                                                    Characteristics,
-                                                    Selection, Assoc, Kind);
+  SectionGroupPair P(Section, COMDATSymName);
+  std::pair<COFFUniqueMapTy::iterator, bool> Entry =
+      Map.insert(std::make_pair(P, (MCSectionCOFF *)0));
+  COFFUniqueMapTy::iterator Iter = Entry.first;
+  if (!Entry.second)
+    return Iter->second;
+
+  const MCSymbol *COMDATSymbol = NULL;
+  if (!COMDATSymName.empty())
+    COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
+
+  MCSectionCOFF *Result =
+      new (*this) MCSectionCOFF(Iter->first.first, Characteristics,
+                                COMDATSymbol, Selection, Assoc, Kind);
 
-  Entry.setValue(Result);
+  Iter->second = Result;
   return Result;
 }
 
+const MCSectionCOFF *
+MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
+                          SectionKind Kind) {
+  return getCOFFSection(Section, Characteristics, Kind, "", 0);
+}
+
 const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
   if (COFFUniquingMap == 0)
     COFFUniquingMap = new COFFUniqueMapTy();
   COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
 
-  return Map.lookup(Section);
+  SectionGroupPair P(Section, "");
+  COFFUniqueMapTy::iterator Iter = Map.find(P);
+  if (Iter == Map.end())
+    return 0;
+  return Iter->second;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/branches/release_34/lib/MC/MCParser/COFFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/lib/MC/MCParser/COFFAsmParser.cpp?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/lib/MC/MCParser/COFFAsmParser.cpp (original)
+++ llvm/branches/release_34/lib/MC/MCParser/COFFAsmParser.cpp Wed Nov 27 00:44:18 2013
@@ -35,6 +35,10 @@ class COFFAsmParser : public MCAsmParser
                           unsigned Characteristics,
                           SectionKind Kind);
 
+  bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
+                          SectionKind Kind, StringRef COMDATSymName,
+                          COFF::COMDATType Type, const MCSectionCOFF *Assoc);
+
   bool ParseSectionName(StringRef &SectionName);
   bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags);
 
@@ -111,6 +115,8 @@ class COFFAsmParser : public MCAsmParser
   bool ParseDirectiveType(StringRef, SMLoc);
   bool ParseDirectiveEndef(StringRef, SMLoc);
   bool ParseDirectiveSecRel32(StringRef, SMLoc);
+  bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
+                               const MCSectionCOFF *&Assoc);
   bool ParseDirectiveLinkOnce(StringRef, SMLoc);
 
   // Win64 EH directives.
@@ -284,12 +290,22 @@ bool COFFAsmParser::ParseDirectiveSymbol
 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
                                        unsigned Characteristics,
                                        SectionKind Kind) {
+  return ParseSectionSwitch(Section, Characteristics, Kind, "",
+                            COFF::IMAGE_COMDAT_SELECT_ANY, 0);
+}
+
+bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
+                                       unsigned Characteristics,
+                                       SectionKind Kind,
+                                       StringRef COMDATSymName,
+                                       COFF::COMDATType Type,
+                                       const MCSectionCOFF *Assoc) {
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in section switching directive");
   Lex();
 
   getStreamer().SwitchSection(getContext().getCOFFSection(
-                                Section, Characteristics, Kind));
+      Section, Characteristics, Kind, COMDATSymName, Type, Assoc));
 
   return false;
 }
@@ -303,7 +319,7 @@ bool COFFAsmParser::ParseSectionName(Str
   return false;
 }
 
-// .section name [, "flags"]
+// .section name [, "flags"] [, identifier [ identifier ], identifier]
 //
 // Supported flags:
 //   a: Ignored.
@@ -340,11 +356,30 @@ bool COFFAsmParser::ParseDirectiveSectio
       return true;
   }
 
+  COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
+  const MCSectionCOFF *Assoc = 0;
+  StringRef COMDATSymName;
+  if (getLexer().is(AsmToken::Comma)) {
+    Lex();
+
+    Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
+
+    if (parseCOMDATTypeAndAssoc(Type, Assoc))
+      return true;
+
+    if (getLexer().isNot(AsmToken::Comma))
+      return TokError("expected comma in directive");
+    Lex();
+
+    if (getParser().parseIdentifier(COMDATSymName))
+      return TokError("expected identifier in directive");
+  }
+
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
   SectionKind Kind = computeSectionKind(Flags);
-  ParseSectionSwitch(SectionName, Flags, Kind);
+  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type, Assoc);
   return false;
 }
 
@@ -409,37 +444,29 @@ bool COFFAsmParser::ParseDirectiveSecRel
   return false;
 }
 
-/// ParseDirectiveLinkOnce
-///  ::= .linkonce [ identifier [ identifier ] ]
-bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
-  COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
-
-  if (getLexer().is(AsmToken::Identifier)) {
-    StringRef TypeId = getTok().getIdentifier();
-
-    Type = StringSwitch<COFF::COMDATType>(TypeId)
-      .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
-      .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
-      .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
-      .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
-      .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
-      .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
-      .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
-      .Default((COFF::COMDATType)0);
+/// ::= [ identifier [ identifier ] ]
+bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
+                                            const MCSectionCOFF *&Assoc) {
+  StringRef TypeId = getTok().getIdentifier();
+
+  Type = StringSwitch<COFF::COMDATType>(TypeId)
+    .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
+    .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
+    .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
+    .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
+    .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+    .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
+    .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
+    .Default((COFF::COMDATType)0);
 
-    if (Type == 0)
-      return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
+  if (Type == 0)
+    return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
 
-    Lex();
-  }
-  
-  const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
-                                       getStreamer().getCurrentSection().first);
+  Lex();
 
-  const MCSectionCOFF *Assoc = 0;
   if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
-    StringRef AssocName;
     SMLoc Loc = getTok().getLoc();
+    StringRef AssocName;
     if (ParseSectionName(AssocName))
       return TokError("expected associated section name");
 
@@ -447,14 +474,33 @@ bool COFFAsmParser::ParseDirectiveLinkOn
                                         getContext().getCOFFSection(AssocName));
     if (!Assoc)
       return Error(Loc, "cannot associate unknown section '" + AssocName + "'");
-    if (Assoc == Current)
-      return Error(Loc, "cannot associate a section with itself");
     if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT))
       return Error(Loc, "associated section must be a COMDAT section");
     if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
       return Error(Loc, "associated section cannot be itself associative");
   }
 
+  return false;
+}
+
+/// ParseDirectiveLinkOnce
+///  ::= .linkonce [ identifier [ identifier ] ]
+bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
+  COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
+  const MCSectionCOFF *Assoc = 0;
+  if (getLexer().is(AsmToken::Identifier))
+    if (parseCOMDATTypeAndAssoc(Type, Assoc))
+      return true;
+
+  const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
+                                       getStreamer().getCurrentSection().first);
+
+
+  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+    if (Assoc == Current)
+      return Error(Loc, "cannot associate a section with itself");
+  }
+
   if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
     return Error(Loc, Twine("section '") + Current->getSectionName() +
                                                        "' is already linkonce");

Modified: llvm/branches/release_34/lib/MC/WinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_34/lib/MC/WinCOFFStreamer.cpp?rev=195822&r1=195821&r2=195822&view=diff
==============================================================================
--- llvm/branches/release_34/lib/MC/WinCOFFStreamer.cpp (original)
+++ llvm/branches/release_34/lib/MC/WinCOFFStreamer.cpp Wed Nov 27 00:44:18 2013
@@ -151,7 +151,8 @@ void WinCOFFStreamer::AddCommonSymbol(MC
   int Selection = COFF::IMAGE_COMDAT_SELECT_LARGEST;
 
   const MCSection *Section = MCStreamer::getContext().getCOFFSection(
-    SectionName, Characteristics, SectionKind::getBSS(), Selection);
+      SectionName, Characteristics, SectionKind::getBSS(), Symbol->getName(),
+      Selection);
 
   MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section);
 





More information about the llvm-branch-commits mailing list