[lld] dcf6494 - LLD already has a mechanism for caching creation of DWARCContext:

Alexey Lapshin via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 6 10:17:28 PST 2020


Author: Alexey Lapshin
Date: 2020-03-06T21:17:07+03:00
New Revision: dcf6494abed7550fc84d6b59b33efc634a95c1fe

URL: https://github.com/llvm/llvm-project/commit/dcf6494abed7550fc84d6b59b33efc634a95c1fe
DIFF: https://github.com/llvm/llvm-project/commit/dcf6494abed7550fc84d6b59b33efc634a95c1fe.diff

LOG: LLD already has a mechanism for caching creation of DWARCContext:

llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });

Though it is not used in all places.

I need that patch for implementing "Remove obsolete debug info" feature
(D74169). But this caching mechanism is useful by itself, and I think it
would be good to use it without connection to "Remove obsolete debug info"
feature. So this patch changes inplace creation of DWARFContext with
its cached version.

Depends on D74308

Reviewed By: ruiu

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

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp
    lld/ELF/InputFiles.h
    lld/ELF/SyntheticSections.cpp
    lld/include/lld/Common/DWARF.h
    lld/test/ELF/gdb-index-invalid-ranges.s
    lld/test/ELF/gdb-index-parse-fail.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index f419b7b571d4..1d8a20aa1388 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -264,9 +264,17 @@ std::string InputFile::getSrcMsg(const Symbol &sym, InputSectionBase &sec,
   }
 }
 
-template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
-  dwarf = make<DWARFCache>(std::make_unique<DWARFContext>(
-      std::make_unique<LLDDwarfObj<ELFT>>(this)));
+template <class ELFT> DWARFCache *ObjFile<ELFT>::getDwarf() {
+  llvm::call_once(initDwarf, [this]() {
+    dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>(
+        std::make_unique<LLDDwarfObj<ELFT>>(this), "",
+        [&](Error err) { warn(getName() + ": " + toString(std::move(err))); },
+        [&](Error warning) {
+          warn(getName() + ": " + toString(std::move(warning)));
+        }));
+  });
+
+  return dwarf.get();
 }
 
 // Returns the pair of file name and line number describing location of data
@@ -274,9 +282,7 @@ template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
 template <class ELFT>
 Optional<std::pair<std::string, unsigned>>
 ObjFile<ELFT>::getVariableLoc(StringRef name) {
-  llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });
-
-  return dwarf->getVariableLoc(name);
+  return getDwarf()->getVariableLoc(name);
 }
 
 // Returns source line information for a given offset
@@ -284,8 +290,6 @@ ObjFile<ELFT>::getVariableLoc(StringRef name) {
 template <class ELFT>
 Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
                                                   uint64_t offset) {
-  llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });
-
   // Detect SectionIndex for specified section.
   uint64_t sectionIndex = object::SectionedAddress::UndefSection;
   ArrayRef<InputSectionBase *> sections = s->file->getSections();
@@ -296,7 +300,7 @@ Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
     }
   }
 
-  return dwarf->getDILineInfo(offset, sectionIndex);
+  return getDwarf()->getDILineInfo(offset, sectionIndex);
 }
 
 ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) {

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 792781054dbc..d08c533e047b 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -250,11 +250,14 @@ template <class ELFT> class ObjFile : public ELFFileBase {
   // SHT_LLVM_CALL_GRAPH_PROFILE table
   ArrayRef<Elf_CGProfile> cgProfile;
 
+  // Get cached DWARF information.
+  DWARFCache *getDwarf();
+
 private:
   void initializeSections(bool ignoreComdats);
   void initializeSymbols();
   void initializeJustSymbols();
-  void initializeDwarf();
+
   InputSectionBase *getRelocTarget(const Elf_Shdr &sec);
   InputSectionBase *createInputSection(const Elf_Shdr &sec);
   StringRef getSectionName(const Elf_Shdr &sec);
@@ -282,8 +285,8 @@ template <class ELFT> class ObjFile : public ELFFileBase {
   // reporting. Linker may find reasonable number of errors in a
   // single object file, so we cache debugging information in order to
   // parse it only once for each object file we link.
-  DWARFCache *dwarf;
-  llvm::once_flag initDwarfLine;
+  std::unique_ptr<DWARFCache> dwarf;
+  llvm::once_flag initDwarf;
 };
 
 // LazyObjFile is analogous to ArchiveFile in the sense that

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 3fd8cd7b745e..c69becb1aee6 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -22,6 +22,7 @@
 #include "Symbols.h"
 #include "Target.h"
 #include "Writer.h"
+#include "lld/Common/DWARF.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
 #include "lld/Common/Strings.h"
@@ -2821,14 +2822,14 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
   std::vector<std::vector<NameAttrEntry>> nameAttrs(sections.size());
 
   parallelForEachN(0, sections.size(), [&](size_t i) {
-    ObjFile<ELFT> *file = sections[i]->getFile<ELFT>();
-    DWARFContext dwarf(std::make_unique<LLDDwarfObj<ELFT>>(file));
+    DWARFContext *dwarf =
+        sections[i]->getFile<ELFT>()->getDwarf()->getContext();
 
     chunks[i].sec = sections[i];
-    chunks[i].compilationUnits = readCuList(dwarf);
-    chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]);
+    chunks[i].compilationUnits = readCuList(*dwarf);
+    chunks[i].addressAreas = readAddressAreas(*dwarf, sections[i]);
     nameAttrs[i] = readPubNamesAndTypes<ELFT>(
-        static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj()),
+        static_cast<const LLDDwarfObj<ELFT> &>(dwarf->getDWARFObj()),
         chunks[i].compilationUnits);
   });
 

diff  --git a/lld/include/lld/Common/DWARF.h b/lld/include/lld/Common/DWARF.h
index f0d3d2fbda77..b77985a6919d 100644
--- a/lld/include/lld/Common/DWARF.h
+++ b/lld/include/lld/Common/DWARF.h
@@ -31,6 +31,8 @@ class DWARFCache {
   llvm::Optional<std::pair<std::string, unsigned>>
   getVariableLoc(StringRef name);
 
+  llvm::DWARFContext *getContext() { return dwarf.get(); }
+
 private:
   std::unique_ptr<llvm::DWARFContext> dwarf;
   std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables;

diff  --git a/lld/test/ELF/gdb-index-invalid-ranges.s b/lld/test/ELF/gdb-index-invalid-ranges.s
index 93e612e62ed4..408e5e5e3894 100644
--- a/lld/test/ELF/gdb-index-invalid-ranges.s
+++ b/lld/test/ELF/gdb-index-invalid-ranges.s
@@ -5,8 +5,8 @@
 # RUN: llvm-ar rc %t.a %t.o
 # RUN: ld.lld --gdb-index -e main %t2.o %t.a -o /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE %s
 
-# CHECK: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
-# ARCHIVE: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
+# CHECK: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.o:{{(\(\.debug_info\):)?}} decoding address ranges: invalid range list entry at offset 0x10
+# ARCHIVE: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):{{(\(\.debug_info\):)?}} decoding address ranges: invalid range list entry at offset 0x10
 
 .section .text.foo1,"ax", at progbits
 .globl f1

diff  --git a/lld/test/ELF/gdb-index-parse-fail.s b/lld/test/ELF/gdb-index-parse-fail.s
index 2e814a4031b7..95332fad8305 100644
--- a/lld/test/ELF/gdb-index-parse-fail.s
+++ b/lld/test/ELF/gdb-index-parse-fail.s
@@ -2,7 +2,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
 # RUN: ld.lld --gdb-index %t1.o -o /dev/null 2>&1 | FileCheck %s
 
-# CHECK: warning: {{.*}}:(.debug_info): invalid reference to or invalid content in .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix
+# CHECK: warning: {{.*}}:{{(\(\.debug_info\):)?}} invalid reference to or invalid content in .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix
 
 .section .debug_abbrev,"", at progbits
   .byte  1                           # Abbreviation Code


        


More information about the llvm-commits mailing list