[llvm] d804b33 - [llvm-readelf] - Split GNUStyle<ELFT>::printHashHistogram. NFC.
Georgii Rymar via llvm-commits
llvm-commits at lists.llvm.org
Wed May 27 03:59:33 PDT 2020
Author: Georgii Rymar
Date: 2020-05-27T13:59:20+03:00
New Revision: d804b334ed0f1c88b90ab028541582e35ba3c172
URL: https://github.com/llvm/llvm-project/commit/d804b334ed0f1c88b90ab028541582e35ba3c172
DIFF: https://github.com/llvm/llvm-project/commit/d804b334ed0f1c88b90ab028541582e35ba3c172.diff
LOG: [llvm-readelf] - Split GNUStyle<ELFT>::printHashHistogram. NFC.
As was mentioned in review comments for D80204,
`printHashHistogram` has 2 lambdas that are probably too large
and deserves splitting into member functions.
This patch does it.
Differential revision: https://reviews.llvm.org/D80546
Added:
Modified:
llvm/tools/llvm-readobj/ELFDumper.cpp
llvm/tools/llvm-readobj/ObjDumper.h
llvm/tools/llvm-readobj/llvm-readobj.cpp
Removed:
################################################################################
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index c9d45061320d..83132869cc2c 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -230,7 +230,7 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
void printStackMap() const override;
- void printHashHistogram() override;
+ void printHashHistograms() override;
void printCGProfile() override;
void printAddrsig() override;
@@ -742,7 +742,7 @@ template <typename ELFT> class DumpStyle {
const Elf_Shdr *Sec) = 0;
virtual void printVersionDependencySection(const ELFFile<ELFT> *Obj,
const Elf_Shdr *Sec) = 0;
- virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
+ virtual void printHashHistograms(const ELFFile<ELFT> *Obj) = 0;
virtual void printCGProfile(const ELFFile<ELFT> *Obj) = 0;
virtual void printAddrsig(const ELFFile<ELFT> *Obj) = 0;
virtual void printNotes(const ELFFile<ELFT> *Obj) = 0;
@@ -811,7 +811,7 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
const Elf_Shdr *Sec) override;
void printVersionDependencySection(const ELFFile<ELFT> *Obj,
const Elf_Shdr *Sec) override;
- void printHashHistogram(const ELFFile<ELFT> *Obj) override;
+ void printHashHistograms(const ELFFile<ELFT> *Obj) override;
void printCGProfile(const ELFFile<ELFT> *Obj) override;
void printAddrsig(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
@@ -823,6 +823,9 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
void printMipsABIFlags(const ELFObjectFile<ELFT> *Obj) override;
private:
+ void printHashHistogram(const Elf_Hash &HashTable);
+ void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable);
+
struct Field {
std::string Str;
unsigned Column;
@@ -932,7 +935,7 @@ template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
const Elf_Shdr *Sec) override;
void printVersionDependencySection(const ELFFile<ELFT> *Obj,
const Elf_Shdr *Sec) override;
- void printHashHistogram(const ELFFile<ELFT> *Obj) override;
+ void printHashHistograms(const ELFFile<ELFT> *Obj) override;
void printCGProfile(const ELFFile<ELFT> *Obj) override;
void printAddrsig(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
@@ -2287,8 +2290,8 @@ template <class ELFT> void ELFDumper<ELFT>::printHashSymbols() {
ELFDumperStyle->printHashSymbols(ObjF->getELFFile());
}
-template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() {
- ELFDumperStyle->printHashHistogram(ObjF->getELFFile());
+template <class ELFT> void ELFDumper<ELFT>::printHashHistograms() {
+ ELFDumperStyle->printHashHistograms(ObjF->getELFFile());
}
template <class ELFT> void ELFDumper<ELFT>::printCGProfile() {
@@ -4556,124 +4559,125 @@ void GNUStyle<ELFT>::printVersionDependencySection(const ELFFile<ELFT> *Obj,
OS << '\n';
}
-// Hash histogram shows statistics of how efficient the hash was for the
-// dynamic symbol table. The table shows number of hash buckets for
diff erent
-// lengths of chains as absolute number and percentage of the total buckets.
-// Additionally cumulative coverage of symbols for each set of buckets.
template <class ELFT>
-void GNUStyle<ELFT>::printHashHistogram(const ELFFile<ELFT> *Obj) {
- auto PrintHashHist = [&](const Elf_Hash &HashTable) {
- size_t NBucket = HashTable.nbucket;
- size_t NChain = HashTable.nchain;
- ArrayRef<Elf_Word> Buckets = HashTable.buckets();
- ArrayRef<Elf_Word> Chains = HashTable.chains();
- size_t TotalSyms = 0;
- // If hash table is correct, we have at least chains with 0 length
- size_t MaxChain = 1;
- size_t CumulativeNonZero = 0;
-
- if (NChain == 0 || NBucket == 0)
- return;
+void GNUStyle<ELFT>::printHashHistogram(const Elf_Hash &HashTable) {
+ size_t NBucket = HashTable.nbucket;
+ size_t NChain = HashTable.nchain;
+ ArrayRef<Elf_Word> Buckets = HashTable.buckets();
+ ArrayRef<Elf_Word> Chains = HashTable.chains();
+ size_t TotalSyms = 0;
+ // If hash table is correct, we have at least chains with 0 length
+ size_t MaxChain = 1;
+ size_t CumulativeNonZero = 0;
+
+ if (NChain == 0 || NBucket == 0)
+ return;
- std::vector<size_t> ChainLen(NBucket, 0);
- // Go over all buckets and and note chain lengths of each bucket (total
- // unique chain lengths).
- for (size_t B = 0; B < NBucket; B++) {
- std::vector<bool> Visited(NChain);
- for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) {
- if (C == ELF::STN_UNDEF)
- break;
- if (Visited[C]) {
- reportWarning(
- createError(".hash section is invalid: bucket " + Twine(C) +
- ": a cycle was detected in the linked chain"),
- this->FileName);
- break;
- }
- Visited[C] = true;
- if (MaxChain <= ++ChainLen[B])
- MaxChain++;
+ std::vector<size_t> ChainLen(NBucket, 0);
+ // Go over all buckets and and note chain lengths of each bucket (total
+ // unique chain lengths).
+ for (size_t B = 0; B < NBucket; B++) {
+ std::vector<bool> Visited(NChain);
+ for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) {
+ if (C == ELF::STN_UNDEF)
+ break;
+ if (Visited[C]) {
+ reportWarning(createError(".hash section is invalid: bucket " +
+ Twine(C) +
+ ": a cycle was detected in the linked chain"),
+ this->FileName);
+ break;
}
- TotalSyms += ChainLen[B];
- }
-
- if (!TotalSyms)
- return;
-
- std::vector<size_t> Count(MaxChain, 0);
- // Count how long is the chain for each bucket
- for (size_t B = 0; B < NBucket; B++)
- ++Count[ChainLen[B]];
- // Print Number of buckets with each chain lengths and their cumulative
- // coverage of the symbols
- OS << "Histogram for bucket list length (total of " << NBucket
- << " buckets)\n"
- << " Length Number % of total Coverage\n";
- for (size_t I = 0; I < MaxChain; I++) {
- CumulativeNonZero += Count[I] * I;
- OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I],
- (Count[I] * 100.0) / NBucket,
- (CumulativeNonZero * 100.0) / TotalSyms);
+ Visited[C] = true;
+ if (MaxChain <= ++ChainLen[B])
+ MaxChain++;
}
- };
+ TotalSyms += ChainLen[B];
+ }
- auto PrintGnuHashHist = [&](const Elf_GnuHash &GnuHashTable) {
- size_t NBucket = GnuHashTable.nbuckets;
- ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets();
- unsigned NumSyms = this->dumper()->dynamic_symbols().size();
- if (!NumSyms)
- return;
- ArrayRef<Elf_Word> Chains = GnuHashTable.values(NumSyms);
- size_t Symndx = GnuHashTable.symndx;
- size_t TotalSyms = 0;
- size_t MaxChain = 1;
- size_t CumulativeNonZero = 0;
+ if (!TotalSyms)
+ return;
- if (Chains.empty() || NBucket == 0)
- return;
+ std::vector<size_t> Count(MaxChain, 0);
+ // Count how long is the chain for each bucket
+ for (size_t B = 0; B < NBucket; B++)
+ ++Count[ChainLen[B]];
+ // Print Number of buckets with each chain lengths and their cumulative
+ // coverage of the symbols
+ OS << "Histogram for bucket list length (total of " << NBucket
+ << " buckets)\n"
+ << " Length Number % of total Coverage\n";
+ for (size_t I = 0; I < MaxChain; I++) {
+ CumulativeNonZero += Count[I] * I;
+ OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I],
+ (Count[I] * 100.0) / NBucket,
+ (CumulativeNonZero * 100.0) / TotalSyms);
+ }
+}
- std::vector<size_t> ChainLen(NBucket, 0);
+template <class ELFT>
+void GNUStyle<ELFT>::printGnuHashHistogram(const Elf_GnuHash &GnuHashTable) {
+ size_t NBucket = GnuHashTable.nbuckets;
+ ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets();
+ unsigned NumSyms = this->dumper()->dynamic_symbols().size();
+ if (!NumSyms)
+ return;
+ ArrayRef<Elf_Word> Chains = GnuHashTable.values(NumSyms);
+ size_t Symndx = GnuHashTable.symndx;
+ size_t TotalSyms = 0;
+ size_t MaxChain = 1;
+ size_t CumulativeNonZero = 0;
- for (size_t B = 0; B < NBucket; B++) {
- if (!Buckets[B])
- continue;
- size_t Len = 1;
- for (size_t C = Buckets[B] - Symndx;
- C < Chains.size() && (Chains[C] & 1) == 0; C++)
- if (MaxChain < ++Len)
- MaxChain++;
- ChainLen[B] = Len;
- TotalSyms += Len;
- }
- MaxChain++;
+ if (Chains.empty() || NBucket == 0)
+ return;
- if (!TotalSyms)
- return;
+ std::vector<size_t> ChainLen(NBucket, 0);
+ for (size_t B = 0; B < NBucket; B++) {
+ if (!Buckets[B])
+ continue;
+ size_t Len = 1;
+ for (size_t C = Buckets[B] - Symndx;
+ C < Chains.size() && (Chains[C] & 1) == 0; C++)
+ if (MaxChain < ++Len)
+ MaxChain++;
+ ChainLen[B] = Len;
+ TotalSyms += Len;
+ }
+ MaxChain++;
- std::vector<size_t> Count(MaxChain, 0);
- for (size_t B = 0; B < NBucket; B++)
- ++Count[ChainLen[B]];
- // Print Number of buckets with each chain lengths and their cumulative
- // coverage of the symbols
- OS << "Histogram for `.gnu.hash' bucket list length (total of " << NBucket
- << " buckets)\n"
- << " Length Number % of total Coverage\n";
- for (size_t I = 0; I < MaxChain; I++) {
- CumulativeNonZero += Count[I] * I;
- OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I],
- (Count[I] * 100.0) / NBucket,
- (CumulativeNonZero * 100.0) / TotalSyms);
- }
- };
+ if (!TotalSyms)
+ return;
+ std::vector<size_t> Count(MaxChain, 0);
+ for (size_t B = 0; B < NBucket; B++)
+ ++Count[ChainLen[B]];
+ // Print Number of buckets with each chain lengths and their cumulative
+ // coverage of the symbols
+ OS << "Histogram for `.gnu.hash' bucket list length (total of " << NBucket
+ << " buckets)\n"
+ << " Length Number % of total Coverage\n";
+ for (size_t I = 0; I < MaxChain; I++) {
+ CumulativeNonZero += Count[I] * I;
+ OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I],
+ (Count[I] * 100.0) / NBucket,
+ (CumulativeNonZero * 100.0) / TotalSyms);
+ }
+}
+
+// Hash histogram shows statistics of how efficient the hash was for the
+// dynamic symbol table. The table shows the number of hash buckets for
+//
diff erent lengths of chains as an absolute number and percentage of the total
+// buckets, and the cumulative coverage of symbols for each set of buckets.
+template <class ELFT>
+void GNUStyle<ELFT>::printHashHistograms(const ELFFile<ELFT> *Obj) {
// Print histogram for the .hash section.
if (const Elf_Hash *HashTable = this->dumper()->getHashTable())
if (checkHashTable(Obj, HashTable, this->FileName))
- PrintHashHist(*HashTable);
+ printHashHistogram(*HashTable);
// Print histogram for the .gnu.hash section.
if (const Elf_GnuHash *GnuHashTable = this->dumper()->getGnuHashTable())
- PrintGnuHashHist(*GnuHashTable);
+ printGnuHashHistogram(*GnuHashTable);
}
template <class ELFT>
@@ -6417,7 +6421,7 @@ void LLVMStyle<ELFT>::printVersionDependencySection(const ELFFile<ELFT> *Obj,
}
template <class ELFT>
-void LLVMStyle<ELFT>::printHashHistogram(const ELFFile<ELFT> *Obj) {
+void LLVMStyle<ELFT>::printHashHistograms(const ELFFile<ELFT> *Obj) {
W.startLine() << "Hash Histogram not implemented!\n";
}
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index a0f69edc9071..57477606d6e8 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -64,7 +64,7 @@ class ObjDumper {
virtual void printLoadName() {}
virtual void printVersionInfo() {}
virtual void printGroupSections() {}
- virtual void printHashHistogram() {}
+ virtual void printHashHistograms() {}
virtual void printCGProfile() {}
virtual void printAddrsig() {}
virtual void printNotes() {}
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 85409389eccd..ab2b320c1f82 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -502,7 +502,7 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer,
if (opts::SectionGroups)
Dumper->printGroupSections();
if (opts::HashHistogram)
- Dumper->printHashHistogram();
+ Dumper->printHashHistograms();
if (opts::CGProfile)
Dumper->printCGProfile();
if (opts::Addrsig)
More information about the llvm-commits
mailing list