Refactor how passes get a symbol at the end of a section.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 23 Mar 2015 21:22:04 +0000 (21:22 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 23 Mar 2015 21:22:04 +0000 (21:22 +0000)
There is now a canonical symbol at the end of a section that different
passes can request.

This also allows us to assert that we don't switch back to a section whose
end symbol has already been printed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233026 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCSection.h
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/MC/MCDwarf.cpp
lib/MC/MCSection.cpp
lib/MC/MCStreamer.cpp
test/DebugInfo/X86/dwarf-aranges.ll
test/DebugInfo/X86/multiple-aranges.ll

index 1e8e4f13225be2b5645432eff8d9f99c3ca08c1d..ab8968ef2baf0a4e6918b6d2a25f253fb38bccb0 100644 (file)
@@ -20,6 +20,7 @@
 
 namespace llvm {
 class MCAsmInfo;
+class MCContext;
 class MCExpr;
 class MCSymbol;
 class raw_ostream;
@@ -35,10 +36,11 @@ private:
   void operator=(const MCSection &) = delete;
 
   MCSymbol *Begin;
+  mutable MCSymbol *End;
 
 protected:
   MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
-      : Begin(Begin), Variant(V), Kind(K) {}
+      : Begin(Begin), End(nullptr), Variant(V), Kind(K) {}
   SectionVariant Variant;
   SectionKind Kind;
 
@@ -50,6 +52,8 @@ public:
   SectionVariant getVariant() const { return Variant; }
 
   MCSymbol *getBeginSymbol() const { return Begin; }
+  MCSymbol *getEndSymbol(MCContext &Ctx) const;
+  bool hasEnded() const;
 
   virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
                                     const MCExpr *Subsection) const = 0;
index 3b3e13518cad524665a91ed5b98e1ff2ba46e2bf..df7610b1d043060f744ab726e814d272f21064a8 100644 (file)
@@ -366,6 +366,8 @@ public:
   /// Create the default sections and set the initial one.
   virtual void InitSections(bool NoExecStack);
 
+  MCSymbol *endSection(const MCSection *Section);
+
   /// AssignSection - Sets the symbol's section.
   ///
   /// Each emitted symbol will be tracked in the ordering table,
index bc9a67640fbf5c74392a260898b088b8aac9ffad..e9ebd97dab03be076a8fcf285f582e59e522d3b8 100644 (file)
@@ -1664,15 +1664,8 @@ void DwarfDebug::emitDebugARanges() {
     const MCSection *Section = I.first;
     MCSymbol *Sym = nullptr;
 
-    if (Section) {
-      // We can't call MCSection::getLabelEndName, as it's only safe to do so
-      // if we know the section name up-front. For user-created sections, the
-      // resulting label may not be valid to use as a label. (section names can
-      // use a greater set of characters on some systems)
-      Sym = Asm->createTempSymbol("debug_end");
-      Asm->OutStreamer.SwitchSection(Section);
-      Asm->OutStreamer.EmitLabel(Sym);
-    }
+    if (Section)
+      Sym = Asm->OutStreamer.endSection(Section);
 
     // Insert a final terminator.
     SectionMap[Section].push_back(SymbolCU(nullptr, Sym));
index 91b277cee5ca882ac73e3ad536a3f55869de49a7..24cdaeff49454b456847f0a3597a595a21b1fb98 100644 (file)
@@ -179,23 +179,14 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section,
   }
 
   // Emit a DW_LNE_end_sequence for the end of the section.
-  // Using the pointer Section create a temporary label at the end of the
-  // section and use that and the LastLabel to compute the address delta
-  // and use INT64_MAX as the line delta which is the signal that this is
-  // actually a DW_LNE_end_sequence.
-
-  // Switch to the section to be able to create a symbol at its end.
-  // TODO: keep track of the last subsection so that this symbol appears in the
-  // correct place.
-  MCOS->SwitchSection(Section);
+  // Use the section end label to compute the address delta and use INT64_MAX
+  // as the line delta which is the signal that this is actually a
+  // DW_LNE_end_sequence.
+  MCSymbol *SectionEnd = MCOS->endSection(Section);
 
+  // Switch back the dwarf line section, in case endSection had to switch the
+  // section.
   MCContext &Ctx = MCOS->getContext();
-  // Create a symbol at the end of the section.
-  MCSymbol *SectionEnd = Ctx.CreateTempSymbol();
-  // Set the value of the symbol, as we are at the end of the section.
-  MCOS->EmitLabel(SectionEnd);
-
-  // Switch back the dwarf line section.
   MCOS->SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
 
   const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
index ccf4a7dddf736a2a1fe55ad30203ee7239847f87..7889f837b11f1ba255ec5ea9002e2f744416e295 100644 (file)
@@ -10,6 +10,7 @@
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
@@ -17,6 +18,14 @@ using namespace llvm;
 // MCSection
 //===----------------------------------------------------------------------===//
 
+MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) const {
+  if (!End)
+    End = Ctx.createTempSymbol("sec_end", true);
+  return End;
+}
+
+bool MCSection::hasEnded() const { return End && End->isInSection(); }
+
 MCSection::~MCSection() {
 }
 
index 63b0bf2c80f81cafc0edb826255c32cb3026c4cf..27d0355bb1175882fa552e186cbe964ad6deb465 100644 (file)
@@ -670,9 +670,22 @@ void MCStreamer::SwitchSection(const MCSection *Section,
   SectionStack.back().second = curSection;
   if (MCSectionSubPair(Section, Subsection) != curSection) {
     SectionStack.back().first = MCSectionSubPair(Section, Subsection);
+    assert(!Section->hasEnded() && "Section already ended");
     ChangeSection(Section, Subsection);
     MCSymbol *Sym = Section->getBeginSymbol();
     if (Sym && !Sym->isInSection())
       EmitLabel(Sym);
   }
 }
+
+MCSymbol *MCStreamer::endSection(const MCSection *Section) {
+  // TODO: keep track of the last subsection so that this symbol appears in the
+  // correct place.
+  MCSymbol *Sym = Section->getEndSymbol(Context);
+  if (Sym->isInSection())
+    return Sym;
+
+  SwitchSection(Section);
+  EmitLabel(Sym);
+  return Sym;
+}
index 701da1fce64566026a0c4a3a60c17a7e39e56a1d..0e658a2663771a3e35c2b49a5f88f06e82cc80c8 100644 (file)
 
 ; <data section> - it should have made one span covering all vars in this CU.
 ; CHECK-NEXT: .quad some_data
-; CHECK-NEXT: .quad .Ldebug_end0-some_data
+; CHECK-NEXT: .quad .Lsec_end0-some_data
 
 ; <other sections> - it should have made one span covering all vars in this CU.
 ; CHECK-NEXT: .quad some_other
-; CHECK-NEXT: .quad .Ldebug_end1-some_other
+; CHECK-NEXT: .quad .Lsec_end1-some_other
 
 ; <common symbols> - it should have made one span for each symbol.
 ; CHECK-NEXT: .quad some_bss
@@ -23,7 +23,7 @@
 
 ; <text section> - it should have made one span covering all functions in this CU.
 ; CHECK-NEXT: .quad .Lfunc_begin0
-; CHECK-NEXT: .quad .Ldebug_end2-.Lfunc_begin0
+; CHECK-NEXT: .quad .Lsec_end2-.Lfunc_begin0
 
 ; -- finish --
 ; CHECK-NEXT: # ARange terminator
index 99878a594a923c21b3b420e68635607385bbf5e9..a4a2946fc5f730a7c23785f270f9ec4cdfb7c447 100644 (file)
@@ -1,7 +1,6 @@
 ; RUN: llc -generate-arange-section < %s | FileCheck %s
 
-; CHECK: .Ldebug_end0:
-; CHECK-NEXT: .section .debug_aranges,"",@progbits
+; CHECK: .section .debug_aranges,"",@progbits
 
 ; First CU
 ; CHECK-NEXT: .long   44                      # Length of ARange Set
@@ -23,7 +22,7 @@
 ; CHECK-NEXT: .byte   0                       # Segment Size (in bytes)
 ; CHECK-NEXT: .zero   4,255
 ; CHECK-NEXT: .quad   rainbows
-; CHECK-NEXT: .quad   .Ldebug_end0-rainbows
+; CHECK-NEXT: .quad   .Lsec_end0-rainbows
 ; CHECK-NEXT: .quad   0                       # ARange terminator
 ; CHECK-NEXT: .quad   0