Skip to content

Commit 4f902d2

Browse files
authored
[llvm-dwarfdump] Make --verify for .debug_names multithreaded. (llvm#127281)
This PR makes verification of .debug_names acceleration table multithreaded. In local testing it improves verification of clang .debug_names from four minutes to under a minute. This PR relies on a current mechanism of extracting DIEs into a vector. Future improvements can include creating API to extract one DIE at a time, or grouping Entires into buckets by CUs and extracting before parallel step. Single Thread 4:12.37 real, 246.88 user, 3.54 sys, 0 amem,10232004 mmem Multi Thread 0:49.40 real, 612.84 user, 515.73 sys, 0 amem, 11226292 mmem
1 parent 7d3dfc8 commit 4f902d2

File tree

5 files changed

+261
-168
lines changed

5 files changed

+261
-168
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
770770
}
771771

772772
public:
773+
using size_type = size_t;
773774
using iterator_category = std::input_iterator_tag;
774775
using value_type = NameTableEntry;
775776
using difference_type = uint32_t;
@@ -793,6 +794,16 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
793794
next();
794795
return I;
795796
}
797+
/// Accesses entry at specific index (1-based internally, 0-based
798+
/// externally). For example how this is used in parallelForEach.
799+
reference operator[](size_type idx) {
800+
return CurrentIndex->getNameTableEntry(idx + 1);
801+
}
802+
/// Computes difference between iterators (used in parallelForEach).
803+
difference_type operator-(const NameIterator &other) const {
804+
assert(CurrentIndex == other.CurrentIndex);
805+
return this->CurrentName - other.CurrentName;
806+
}
796807

797808
friend bool operator==(const NameIterator &A, const NameIterator &B) {
798809
return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;

llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
1010
#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
1111

12+
#include "llvm/ADT/StringMap.h"
1213
#include "llvm/DebugInfo/DIContext.h"
1314
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
1415
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
1516
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
1617
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
1718
#include <cstdint>
1819
#include <map>
20+
#include <mutex>
1921
#include <set>
2022

2123
namespace llvm {
@@ -37,7 +39,9 @@ struct AggregationData {
3739

3840
class OutputCategoryAggregator {
3941
private:
42+
std::mutex WriteMutex;
4043
std::map<std::string, AggregationData, std::less<>> Aggregation;
44+
uint64_t NumErrors = 0;
4145
bool IncludeDetail;
4246

4347
public:
@@ -52,6 +56,8 @@ class OutputCategoryAggregator {
5256
void EnumerateDetailedResultsFor(
5357
StringRef category,
5458
std::function<void(StringRef, unsigned)> handleCounts);
59+
/// Return the number of errors that have been reported.
60+
uint64_t GetNumErrors() const { return NumErrors; }
5561
};
5662

5763
/// A class that verifies DWARF debug information given a DWARF Context.
@@ -114,6 +120,7 @@ class DWARFVerifier {
114120
bool IsObjectFile;
115121
bool IsMachOObject;
116122
using ReferenceMap = std::map<uint64_t, std::set<uint64_t>>;
123+
std::mutex AccessMutex;
117124

118125
raw_ostream &error() const;
119126
raw_ostream &warn() const;
@@ -274,21 +281,23 @@ class DWARFVerifier {
274281
/// \param SectionName the name of the table we're verifying
275282
///
276283
/// \returns The number of errors occurred during verification
277-
unsigned verifyAppleAccelTable(const DWARFSection *AccelSection,
278-
DataExtractor *StrData,
279-
const char *SectionName);
280-
281-
unsigned verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
282-
unsigned verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
283-
const DataExtractor &StrData);
284-
unsigned verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
285-
unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
286-
const DWARFDebugNames::Abbrev &Abbr,
287-
DWARFDebugNames::AttributeEncoding AttrEnc);
288-
unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
289-
const DWARFDebugNames::NameTableEntry &NTE);
290-
unsigned verifyNameIndexCompleteness(const DWARFDie &Die,
291-
const DWARFDebugNames::NameIndex &NI);
284+
void verifyAppleAccelTable(const DWARFSection *AccelSection,
285+
DataExtractor *StrData, const char *SectionName);
286+
287+
void verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
288+
void verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
289+
const DataExtractor &StrData);
290+
void verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
291+
void verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
292+
const DWARFDebugNames::Abbrev &Abbr,
293+
DWARFDebugNames::AttributeEncoding AttrEnc);
294+
void verifyNameIndexEntries(
295+
const DWARFDebugNames::NameIndex &NI,
296+
const DWARFDebugNames::NameTableEntry &NTE,
297+
const DenseMap<uint64_t, DWARFUnit *> &CUOffsetsToDUMap);
298+
void verifyNameIndexCompleteness(
299+
const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI,
300+
const StringMap<DenseSet<uint64_t>> &NamesToDieOffsets);
292301

293302
/// Verify that the DWARF v5 accelerator table is valid.
294303
///
@@ -307,8 +316,8 @@ class DWARFVerifier {
307316
/// \param StrData string section
308317
///
309318
/// \returns The number of errors occurred during verification
310-
unsigned verifyDebugNames(const DWARFSection &AccelSection,
311-
const DataExtractor &StrData);
319+
void verifyDebugNames(const DWARFSection &AccelSection,
320+
const DataExtractor &StrData);
312321

313322
public:
314323
DWARFVerifier(raw_ostream &S, DWARFContext &D,

0 commit comments

Comments
 (0)