[llvm] r324393 - [DWARFv5] Emit .debug_line_str (in a non-DWO file).

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 6 12:29:21 PST 2018


Author: probinson
Date: Tue Feb  6 12:29:21 2018
New Revision: 324393

URL: http://llvm.org/viewvc/llvm-project?rev=324393&view=rev
Log:
[DWARFv5] Emit .debug_line_str (in a non-DWO file).

This should enable the linker to do string-pooling of path names.

Differential Revision: https://reviews.llvm.org/D42707

Modified:
    llvm/trunk/include/llvm/MC/MCDwarf.h
    llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
    llvm/trunk/include/llvm/MC/StringTableBuilder.h
    llvm/trunk/lib/MC/MCDwarf.cpp
    llvm/trunk/lib/MC/MCObjectFileInfo.cpp
    llvm/trunk/lib/MC/StringTableBuilder.cpp
    llvm/trunk/test/MC/ELF/debug-md5.s

Modified: llvm/trunk/include/llvm/MC/MCDwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDwarf.h (original)
+++ llvm/trunk/include/llvm/MC/MCDwarf.h Tue Feb  6 12:29:21 2018
@@ -32,6 +32,7 @@ namespace llvm {
 template <typename T> class ArrayRef;
 class MCAsmBackend;
 class MCContext;
+class MCDwarfLineStr;
 class MCObjectStreamer;
 class MCStreamer;
 class MCSymbol;
@@ -214,15 +215,18 @@ struct MCDwarfLineTableHeader {
 
   unsigned getFile(StringRef &Directory, StringRef &FileName,
                    MD5::MD5Result *Checksum, unsigned FileNumber = 0);
-  std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS,
-                                         MCDwarfLineTableParams Params) const;
   std::pair<MCSymbol *, MCSymbol *>
   Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
-       ArrayRef<char> SpecialOpcodeLengths) const;
+       Optional<MCDwarfLineStr> &LineStr) const;
+  std::pair<MCSymbol *, MCSymbol *>
+  Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
+       ArrayRef<char> SpecialOpcodeLengths,
+       Optional<MCDwarfLineStr> &LineStr) const;
 
 private:
   void emitV2FileDirTables(MCStreamer *MCOS) const;
-  void emitV5FileDirTables(MCStreamer *MCOS) const;
+  void emitV5FileDirTables(MCStreamer *MCOS,
+                           Optional<MCDwarfLineStr> &LineStr) const;
 };
 
 class MCDwarfDwoLineTable {
@@ -250,7 +254,8 @@ public:
   static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params);
 
   // This emits the Dwarf file and the line tables for a given Compile Unit.
-  void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params) const;
+  void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params,
+              Optional<MCDwarfLineStr> &LineStr) const;
 
   unsigned getFile(StringRef &Directory, StringRef &FileName,
                    MD5::MD5Result *Checksum, unsigned FileNumber = 0);

Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Tue Feb  6 12:29:21 2018
@@ -79,6 +79,7 @@ protected:
   MCSection *DwarfAbbrevSection;
   MCSection *DwarfInfoSection;
   MCSection *DwarfLineSection;
+  MCSection *DwarfLineStrSection;
   MCSection *DwarfFrameSection;
   MCSection *DwarfPubTypesSection;
   const MCSection *DwarfDebugInlineSection;
@@ -234,6 +235,7 @@ public:
   MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
   MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
   MCSection *getDwarfLineSection() const { return DwarfLineSection; }
+  MCSection *getDwarfLineStrSection() const { return DwarfLineStrSection; }
   MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
   MCSection *getDwarfPubNamesSection() const { return DwarfPubNamesSection; }
   MCSection *getDwarfPubTypesSection() const { return DwarfPubTypesSection; }

Modified: llvm/trunk/include/llvm/MC/StringTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/StringTableBuilder.h?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/StringTableBuilder.h (original)
+++ llvm/trunk/include/llvm/MC/StringTableBuilder.h Tue Feb  6 12:29:21 2018
@@ -23,7 +23,7 @@ class raw_ostream;
 /// \brief Utility for building string tables with deduplicated suffixes.
 class StringTableBuilder {
 public:
-  enum Kind { ELF, WinCOFF, MachO, RAW };
+  enum Kind { ELF, WinCOFF, MachO, RAW, DWARF };
 
 private:
   DenseMap<CachedHashStringRef, size_t> StringIndexMap;

Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Feb  6 12:29:21 2018
@@ -28,6 +28,7 @@
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/EndianStream.h"
@@ -45,6 +46,29 @@
 
 using namespace llvm;
 
+/// Manage the .debug_line_str section contents, if we use it.
+class llvm::MCDwarfLineStr {
+  MCSymbol *LineStrLabel = nullptr;
+  StringTableBuilder LineStrings{StringTableBuilder::DWARF};
+  bool UseRelocs = false;
+
+public:
+  /// Construct an instance that can emit .debug_line_str (for use in a normal
+  /// v5 line table).
+  explicit MCDwarfLineStr(MCContext &Ctx) {
+    UseRelocs = Ctx.getAsmInfo()->doesDwarfUseRelocationsAcrossSections();
+    if (UseRelocs)
+      LineStrLabel =
+          Ctx.getObjectFileInfo()->getDwarfLineStrSection()->getBeginSymbol();
+  }
+
+  /// Emit a reference to the string.
+  void emitRef(MCStreamer *MCOS, StringRef Path);
+
+  /// Emit the .debug_line_str section if appropriate.
+  void emitSection(MCStreamer *MCOS);
+};
+
 static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
   unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
   if (MinInsnLength == 1)
@@ -108,6 +132,18 @@ static inline const MCExpr *MakeStartMin
 }
 
 //
+// This helper routine returns an expression of Start + IntVal .
+//
+static inline const MCExpr *
+makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
+  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+  const MCExpr *LHS = MCSymbolRefExpr::create(&Start, Variant, Ctx);
+  const MCExpr *RHS = MCConstantExpr::create(IntVal, Ctx);
+  const MCExpr *Res = MCBinaryExpr::create(MCBinaryExpr::Add, LHS, RHS, Ctx);
+  return Res;
+}
+
+//
 // This emits the Dwarf line table for the specified section from the entries
 // in the LineSection.
 //
@@ -205,22 +241,31 @@ void MCDwarfLineTable::Emit(MCObjectStre
   if (LineTables.empty())
     return;
 
+  // In a v5 non-split line table, put the strings in a separate section.
+  Optional<MCDwarfLineStr> LineStr;
+  if (context.getDwarfVersion() >= 5)
+    LineStr = MCDwarfLineStr(context);
+
   // Switch to the section where the table will be emitted into.
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
 
   // Handle the rest of the Compile Units.
   for (const auto &CUIDTablePair : LineTables)
-    CUIDTablePair.second.EmitCU(MCOS, Params);
+    CUIDTablePair.second.EmitCU(MCOS, Params, LineStr);
+
+  if (LineStr)
+    LineStr->emitSection(MCOS);
 }
 
 void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS,
                                MCDwarfLineTableParams Params) const {
-  MCOS.EmitLabel(Header.Emit(&MCOS, Params, None).second);
+  Optional<MCDwarfLineStr> NoLineStr(None);
+  MCOS.EmitLabel(Header.Emit(&MCOS, Params, None, NoLineStr).second);
 }
 
 std::pair<MCSymbol *, MCSymbol *>
-MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
-                             MCDwarfLineTableParams Params) const {
+MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
+                             Optional<MCDwarfLineStr> &LineStr) const {
   static const char StandardOpcodeLengths[] = {
       0, // length of DW_LNS_copy
       1, // length of DW_LNS_advance_pc
@@ -237,8 +282,10 @@ MCDwarfLineTableHeader::Emit(MCStreamer
   };
   assert(array_lengthof(StandardOpcodeLengths) >=
          (Params.DWARF2LineOpcodeBase - 1U));
-  return Emit(MCOS, Params, makeArrayRef(StandardOpcodeLengths,
-                                         Params.DWARF2LineOpcodeBase - 1));
+  return Emit(
+      MCOS, Params,
+      makeArrayRef(StandardOpcodeLengths, Params.DWARF2LineOpcodeBase - 1),
+      LineStr);
 }
 
 static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
@@ -257,6 +304,28 @@ static void emitAbsValue(MCStreamer &OS,
   OS.EmitValue(ABS, Size);
 }
 
+void MCDwarfLineStr::emitSection(MCStreamer *MCOS) {
+  // Switch to the .debug_line_str section.
+  MCOS->SwitchSection(
+      MCOS->getContext().getObjectFileInfo()->getDwarfLineStrSection());
+  // Emit the strings without perturbing the offsets we used.
+  LineStrings.finalizeInOrder();
+  SmallString<0> Data;
+  Data.resize(LineStrings.getSize());
+  LineStrings.write((uint8_t *)Data.data());
+  MCOS->EmitBinaryData(Data.str());
+}
+
+void MCDwarfLineStr::emitRef(MCStreamer *MCOS, StringRef Path) {
+  int RefSize = 4; // FIXME: Support DWARF-64
+  size_t Offset = LineStrings.add(Path);
+  if (UseRelocs) {
+    MCContext &Ctx = MCOS->getContext();
+    MCOS->EmitValue(makeStartPlusIntExpr(Ctx, *LineStrLabel, Offset), RefSize);
+  } else
+    MCOS->EmitIntValue(Offset, RefSize);
+}
+
 void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
   // First the directory table.
   for (auto &Dir : MCDwarfDirs) {
@@ -277,18 +346,29 @@ void MCDwarfLineTableHeader::emitV2FileD
   MCOS->EmitIntValue(0, 1); // Terminate the file list.
 }
 
-void MCDwarfLineTableHeader::emitV5FileDirTables(MCStreamer *MCOS) const {
-  // The directory format, which is just inline null-terminated strings.
+void MCDwarfLineTableHeader::emitV5FileDirTables(
+    MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr) const {
+  // The directory format, which is just a list of the directory paths.  In a
+  // non-split object, these are references to .debug_line_str; in a split
+  // object, they are inline strings.
   MCOS->EmitIntValue(1, 1);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
-  MCOS->EmitULEB128IntValue(dwarf::DW_FORM_string);
-  // Then the list of directory paths.  CompilationDir comes first.
+  MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
+                                    : dwarf::DW_FORM_string);
   MCOS->EmitULEB128IntValue(MCDwarfDirs.size() + 1);
-  MCOS->EmitBytes(CompilationDir);
-  MCOS->EmitBytes(StringRef("\0", 1));
-  for (auto &Dir : MCDwarfDirs) {
-    MCOS->EmitBytes(Dir);                // The DirectoryName, and...
-    MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
+  if (LineStr) {
+    // Record path strings, emit references here.
+    LineStr->emitRef(MCOS, CompilationDir);
+    for (auto &Dir : MCDwarfDirs)
+      LineStr->emitRef(MCOS, Dir);
+  } else {
+    // The list of directory paths.  CompilationDir comes first.
+    MCOS->EmitBytes(CompilationDir);
+    MCOS->EmitBytes(StringRef("\0", 1));
+    for (auto &Dir : MCDwarfDirs) {
+      MCOS->EmitBytes(Dir);                // The DirectoryName, and...
+      MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
+    }
   }
 
   // The file format, which is the inline null-terminated filename and a
@@ -296,7 +376,8 @@ void MCDwarfLineTableHeader::emitV5FileD
   // in the v5 table.  Emit MD5 checksums if we have them.
   MCOS->EmitIntValue(HasMD5 ? 3 : 2, 1);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
-  MCOS->EmitULEB128IntValue(dwarf::DW_FORM_string);
+  MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
+                                    : dwarf::DW_FORM_string);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index);
   MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata);
   if (HasMD5) {
@@ -307,8 +388,12 @@ void MCDwarfLineTableHeader::emitV5FileD
   MCOS->EmitULEB128IntValue(MCDwarfFiles.size() - 1);
   for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) {
     assert(!MCDwarfFiles[i].Name.empty());
-    MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and...
-    MCOS->EmitBytes(StringRef("\0", 1));   // its null terminator.
+    if (LineStr)
+      LineStr->emitRef(MCOS, MCDwarfFiles[i].Name);
+    else {
+      MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and...
+      MCOS->EmitBytes(StringRef("\0", 1));   // its null terminator.
+    }
     MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number.
     if (HasMD5) {
       MD5::MD5Result *Cksum = MCDwarfFiles[i].Checksum;
@@ -321,7 +406,8 @@ void MCDwarfLineTableHeader::emitV5FileD
 
 std::pair<MCSymbol *, MCSymbol *>
 MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
-                             ArrayRef<char> StandardOpcodeLengths) const {
+                             ArrayRef<char> StandardOpcodeLengths,
+                             Optional<MCDwarfLineStr> &LineStr) const {
   MCContext &context = MCOS->getContext();
 
   // Create a symbol at the beginning of the line table.
@@ -386,7 +472,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer
   // Put out the directory and file tables.  The formats vary depending on
   // the version.
   if (LineTableVersion >= 5)
-    emitV5FileDirTables(MCOS);
+    emitV5FileDirTables(MCOS, LineStr);
   else
     emitV2FileDirTables(MCOS);
 
@@ -398,8 +484,9 @@ MCDwarfLineTableHeader::Emit(MCStreamer
 }
 
 void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS,
-                              MCDwarfLineTableParams Params) const {
-  MCSymbol *LineEndSym = Header.Emit(MCOS, Params).second;
+                              MCDwarfLineTableParams Params,
+                              Optional<MCDwarfLineStr> &LineStr) const {
+  MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
 
   // Put out the line tables.
   for (const auto &LineSec : MCLineSections.getMCLineEntries())

Modified: llvm/trunk/lib/MC/MCObjectFileInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectFileInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp Tue Feb  6 12:29:21 2018
@@ -228,6 +228,9 @@ void MCObjectFileInfo::initMachOMCObject
   DwarfLineSection =
       Ctx->getMachOSection("__DWARF", "__debug_line", MachO::S_ATTR_DEBUG,
                            SectionKind::getMetadata(), "section_line");
+  DwarfLineStrSection =
+      Ctx->getMachOSection("__DWARF", "__debug_line_str", MachO::S_ATTR_DEBUG,
+                           SectionKind::getMetadata(), "section_line_str");
   DwarfFrameSection =
       Ctx->getMachOSection("__DWARF", "__debug_frame", MachO::S_ATTR_DEBUG,
                            SectionKind::getMetadata());
@@ -527,6 +530,9 @@ void MCObjectFileInfo::initELFMCObjectFi
       Ctx->getELFSection(".debug_abbrev", DebugSecType, 0);
   DwarfInfoSection = Ctx->getELFSection(".debug_info", DebugSecType, 0);
   DwarfLineSection = Ctx->getELFSection(".debug_line", DebugSecType, 0);
+  DwarfLineStrSection =
+      Ctx->getELFSection(".debug_line_str", DebugSecType,
+                         ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
   DwarfFrameSection = Ctx->getELFSection(".debug_frame", DebugSecType, 0);
   DwarfPubNamesSection =
       Ctx->getELFSection(".debug_pubnames", DebugSecType, 0);
@@ -677,7 +683,11 @@ void MCObjectFileInfo::initCOFFMCObjectF
       COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
           COFF::IMAGE_SCN_MEM_READ,
       SectionKind::getMetadata(), "section_line");
-
+  DwarfLineStrSection = Ctx->getCOFFSection(
+      ".debug_line_str",
+      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+          COFF::IMAGE_SCN_MEM_READ,
+      SectionKind::getMetadata(), "section_line_str");
   DwarfFrameSection = Ctx->getCOFFSection(
       ".debug_frame",
       COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -842,6 +852,8 @@ void MCObjectFileInfo::initWasmMCObjectF
 
   // TODO: Set the section types and flags.
   DwarfLineSection = Ctx->getWasmSection(".debug_line", SectionKind::getMetadata());
+  DwarfLineStrSection =
+      Ctx->getWasmSection(".debug_line_str", SectionKind::getMetadata());
   DwarfStrSection = Ctx->getWasmSection(".debug_str", SectionKind::getMetadata());
   DwarfLocSection = Ctx->getWasmSection(".debug_loc", SectionKind::getMetadata());
   DwarfAbbrevSection = Ctx->getWasmSection(".debug_abbrev", SectionKind::getMetadata(), "section_abbrev");

Modified: llvm/trunk/lib/MC/StringTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/StringTableBuilder.cpp?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/lib/MC/StringTableBuilder.cpp (original)
+++ llvm/trunk/lib/MC/StringTableBuilder.cpp Tue Feb  6 12:29:21 2018
@@ -31,6 +31,7 @@ void StringTableBuilder::initSize() {
   // correct.
   switch (K) {
   case RAW:
+  case DWARF:
     Size = 0;
     break;
   case MachO:
@@ -116,6 +117,7 @@ tailcall:
 }
 
 void StringTableBuilder::finalize() {
+  assert(K != DWARF);
   finalizeStringTable(/*Optimize=*/true);
 }
 

Modified: llvm/trunk/test/MC/ELF/debug-md5.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/debug-md5.s?rev=324393&r1=324392&r2=324393&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/debug-md5.s (original)
+++ llvm/trunk/test/MC/ELF/debug-md5.s Tue Feb  6 12:29:21 2018
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple x86_64-unknown-unknown -dwarf-version 5 -filetype=obj %s -o -| llvm-dwarfdump --debug-line - | FileCheck %s
+// RUN: llvm-mc -triple x86_64-unknown-unknown -dwarf-version 5 -filetype=obj %s -o - | llvm-dwarfdump --debug-line --debug-line-str -v - | FileCheck %s
 
         .file 1 "dir1/foo"   md5 "00112233445566778899aabbccddeeff"
         .file 2 "dir2" "bar" md5 "ffeeddccbbaa99887766554433221100"
@@ -9,10 +9,17 @@
 
 # CHECK: debug_line[0x00000000]
 # CHECK: version: 5
-# CHECK: include_directories[ 0] = ""
-# CHECK: include_directories[ 1] = "dir1"
-# CHECK: include_directories[ 2] = "dir2"
+# CHECK: include_directories[ 0] = .debug_line_str[0x00000000] = ""
+# CHECK: include_directories[ 1] = .debug_line_str[0x00000001] = "dir1"
+# CHECK: include_directories[ 2] = .debug_line_str[0x00000006] = "dir2"
 # CHECK-NOT: include_directories
 # CHECK: Dir MD5 Checksum File Name
-# CHECK: file_names[ 1] 1 00112233445566778899aabbccddeeff "foo"
-# CHECK: file_names[ 2] 2 ffeeddccbbaa99887766554433221100 "bar"
+# CHECK: file_names[ 1] 1 00112233445566778899aabbccddeeff .debug_line_str[0x0000000b] = "foo"
+# CHECK: file_names[ 2] 2 ffeeddccbbaa99887766554433221100 .debug_line_str[0x0000000f] = "bar"
+
+# CHECK: .debug_line_str contents:
+# CHECK-NEXT: 0x00000000: ""
+# CHECK-NEXT: 0x00000001: "dir1"
+# CHECK-NEXT: 0x00000006: "dir2"
+# CHECK-NEXT: 0x0000000b: "foo"
+# CHECK-NEXT: 0x0000000f: "bar"




More information about the llvm-commits mailing list