Skip to content

Commit 523d5f9

Browse files
author
Kevin Frei
committed
Output Aggregation/summarization for GSYMUtil
1 parent 99446df commit 523d5f9

File tree

10 files changed

+406
-239
lines changed

10 files changed

+406
-239
lines changed

llvm/include/llvm/DebugInfo/GSYM/DwarfTransformer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace gsym {
2222
struct CUInfo;
2323
struct FunctionInfo;
2424
class GsymCreator;
25+
class OutputAggregator;
2526

2627
/// A class that transforms the DWARF in a DWARFContext into GSYM information
2728
/// by populating the GsymCreator object that it is constructed with. This
@@ -52,9 +53,9 @@ class DwarfTransformer {
5253
///
5354
/// \returns An error indicating any fatal issues that happen when parsing
5455
/// the DWARF, or Error::success() if all goes well.
55-
llvm::Error convert(uint32_t NumThreads, raw_ostream *OS);
56+
llvm::Error convert(uint32_t NumThreads, OutputAggregator &OS);
5657

57-
llvm::Error verify(StringRef GsymPath, raw_ostream &OS);
58+
llvm::Error verify(StringRef GsymPath, OutputAggregator &OS);
5859

5960
private:
6061

@@ -79,7 +80,7 @@ class DwarfTransformer {
7980
/// information.
8081
///
8182
/// \param Die The DWARF debug info entry to parse.
82-
void handleDie(raw_ostream *Strm, CUInfo &CUI, DWARFDie Die);
83+
void handleDie(OutputAggregator &Strm, CUInfo &CUI, DWARFDie Die);
8384

8485
DWARFContext &DICtx;
8586
GsymCreator &Gsym;

llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
#define LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H
1111

1212
#include <functional>
13+
#include <map>
1314
#include <memory>
1415
#include <mutex>
16+
#include <string>
1517
#include <thread>
1618

1719
#include "llvm/ADT/AddressRanges.h"
@@ -28,6 +30,7 @@ namespace llvm {
2830

2931
namespace gsym {
3032
class FileWriter;
33+
class OutputAggregator;
3134

3235
/// GsymCreator is used to emit GSYM data to a stand alone file or section
3336
/// within a file.
@@ -360,7 +363,7 @@ class GsymCreator {
360363
/// function infos, and function infos that were merged or removed.
361364
/// \returns An error object that indicates success or failure of the
362365
/// finalize.
363-
llvm::Error finalize(llvm::raw_ostream &OS);
366+
llvm::Error finalize(OutputAggregator &OS);
364367

365368
/// Set the UUID value.
366369
///

llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313

1414
namespace llvm {
1515

16-
class raw_ostream;
17-
1816
namespace object {
1917
class ObjectFile;
2018
}
2119

2220
namespace gsym {
2321

2422
class GsymCreator;
23+
class OutputAggregator;
2524

2625
class ObjectFileTransformer {
2726
public:
@@ -40,8 +39,8 @@ class ObjectFileTransformer {
4039
///
4140
/// \returns An error indicating any fatal issues that happen when parsing
4241
/// the DWARF, or Error::success() if all goes well.
43-
static llvm::Error convert(const object::ObjectFile &Obj, raw_ostream *Log,
44-
GsymCreator &Gsym);
42+
static llvm::Error convert(const object::ObjectFile &Obj,
43+
OutputAggregator &Output, GsymCreator &Gsym);
4544
};
4645

4746
} // namespace gsym
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//===- DwarfTransformer.h ---------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H
10+
#define LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H
11+
12+
#include "llvm/ADT/StringRef.h"
13+
#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
14+
15+
#include <map>
16+
#include <string>
17+
18+
namespace llvm {
19+
20+
class raw_ostream;
21+
22+
namespace gsym {
23+
24+
class OutputAggregator {
25+
protected:
26+
// A std::map is preferable over an llvm::StringMap for presenting results
27+
// in a predictable order.
28+
std::map<std::string, unsigned> Aggregation;
29+
raw_ostream *Out;
30+
bool IncludeDetail;
31+
32+
public:
33+
OutputAggregator(raw_ostream *out, bool includeDetail = true)
34+
: Out(out), IncludeDetail(includeDetail) {}
35+
36+
// Do I want a "detail level" thing? I think so, actually...
37+
void ShowDetail(bool showDetail) { IncludeDetail = showDetail; }
38+
bool IsShowingDetail() const { return IncludeDetail; }
39+
40+
size_t GetNumCategories() const { return Aggregation.size(); }
41+
42+
void Report(StringRef s, std::function<void(raw_ostream &o)> detailCallback) {
43+
Aggregation[std::string(s)]++;
44+
if (IncludeDetail && Out != nullptr)
45+
detailCallback(*Out);
46+
}
47+
48+
void Report(StringRef s, std::function<void()> detailCallback) {
49+
Aggregation[std::string(s)]++;
50+
if (IncludeDetail)
51+
detailCallback();
52+
}
53+
54+
void EnumerateResults(
55+
std::function<void(StringRef, unsigned)> handleCounts) const {
56+
for (auto &&[name, count] : Aggregation) {
57+
handleCounts(name, count);
58+
}
59+
}
60+
61+
raw_ostream *GetOS() const { return Out; }
62+
63+
// You can just use the stream, and if it's null, nothing happens.
64+
// Don't do a lot of stuff like this, but it's convenient for silly stuff.
65+
// It doesn't work with things that have custom insertion operators, though.
66+
template <typename T> OutputAggregator &operator<<(T &&value) {
67+
if (Out != nullptr)
68+
*Out << value;
69+
return *this;
70+
}
71+
72+
// For multi-threaded usage, we can collect stuff in another aggregator,
73+
// then merge it in here
74+
void Merge(const OutputAggregator &other) {
75+
for (auto &&[name, count] : other.Aggregation) {
76+
auto it = Aggregation.find(name);
77+
if (it == Aggregation.end())
78+
Aggregation.emplace(name, count);
79+
else
80+
it->second += count;
81+
}
82+
}
83+
};
84+
85+
class StringAggregator : public OutputAggregator {
86+
private:
87+
std::string storage;
88+
raw_string_ostream StrStream;
89+
90+
public:
91+
StringAggregator(bool includeDetail = true)
92+
: OutputAggregator(&StrStream, includeDetail), StrStream(storage) {}
93+
friend OutputAggregator &operator<<(OutputAggregator &agg,
94+
StringAggregator &sa);
95+
};
96+
97+
inline OutputAggregator &operator<<(OutputAggregator &agg,
98+
StringAggregator &sa) {
99+
agg.Merge(sa);
100+
sa.StrStream.flush();
101+
return agg << sa.storage;
102+
}
103+
104+
} // namespace gsym
105+
} // namespace llvm
106+
107+
#endif // LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H

0 commit comments

Comments
 (0)