Skip to content

Commit 9334779

Browse files
committed
[Stats] Reduce layering violations in FrontendStatsTracer.
1 parent d39dc43 commit 9334779

File tree

7 files changed

+196
-109
lines changed

7 files changed

+196
-109
lines changed

include/swift/Basic/Statistic.h

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#ifndef SWIFT_BASIC_STATISTIC_H
1414
#define SWIFT_BASIC_STATISTIC_H
1515

16-
#include "llvm/ADT/PointerUnion.h"
1716
#include "llvm/ADT/SmallString.h"
1817
#include "llvm/ADT/Statistic.h"
1918
#include "swift/AST/Identifier.h"
@@ -86,19 +85,29 @@ class UnifiedStatsReporter {
8685
int dummyInstanceVariableToGetConstructorToParse;
8786
};
8887

89-
typedef llvm::PointerUnion4<const Decl*,
90-
const clang::Decl*,
91-
const Expr*,
92-
const SILFunction*> TraceEntity;
88+
// To trace an entity, you have to provide a TraceFormatter for it. This is a
89+
// separate type since we do not have retroactive conformances in C++, and it
90+
// is a type that takes void* arguments since we do not have existentials
91+
// separate from objects in C++. Pity us.
92+
struct TraceFormatter {
93+
virtual void traceName(const void *Entity, raw_ostream &OS) const = 0;
94+
virtual void traceLoc(const void *Entity,
95+
SourceManager *SourceMgr,
96+
clang::SourceManager *ClangSourceMgr,
97+
raw_ostream &OS) const = 0;
98+
virtual ~TraceFormatter();
99+
};
93100

94101
struct FrontendStatsTracer
95102
{
96103
UnifiedStatsReporter *Reporter;
97104
llvm::TimeRecord SavedTime;
98105
StringRef EventName;
99-
TraceEntity Entity;
106+
const void *Entity;
107+
const TraceFormatter *Formatter;
100108
FrontendStatsTracer(StringRef EventName,
101-
TraceEntity Entity,
109+
const void *Entity,
110+
const TraceFormatter *Formatter,
102111
UnifiedStatsReporter *Reporter);
103112
FrontendStatsTracer();
104113
FrontendStatsTracer(FrontendStatsTracer&& other);
@@ -117,7 +126,8 @@ class UnifiedStatsReporter {
117126
StringRef CounterName;
118127
size_t CounterDelta;
119128
size_t CounterValue;
120-
TraceEntity Entity;
129+
const void *Entity;
130+
const TraceFormatter *Formatter;
121131
};
122132

123133
private:
@@ -162,9 +172,10 @@ class UnifiedStatsReporter {
162172
AlwaysOnFrontendCounters &getFrontendCounters();
163173
AlwaysOnFrontendRecursiveSharedTimers &getFrontendRecursiveSharedTimers();
164174
void noteCurrentProcessExitStatus(int);
165-
// We provide 4 explicit overloads here, rather than a single function that
166-
// takes a TraceEntity, to save all of our clients from having to include all
167-
// 4 headers that define these 4 forward-declared types.
175+
// We declare 4 explicit overloads here, but the _definitions_ live in the
176+
// upper-level files (in libswiftAST or libswiftSIL) that provide the types
177+
// being traced. If you want to trace those types, it's assumed you're linking
178+
// with the object files that define the tracer.
168179
FrontendStatsTracer getStatsTracer(StringRef EventName, const Decl *D);
169180
FrontendStatsTracer getStatsTracer(StringRef EventName, const clang::Decl*D);
170181
FrontendStatsTracer getStatsTracer(StringRef EventName, const Expr *E);

lib/AST/Decl.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5658,3 +5658,37 @@ void Decl::setClangNode(ClangNode Node) {
56585658
}
56595659
*(ptr - 1) = Node.getOpaqueValue();
56605660
}
5661+
5662+
// See swift/Basic/Statistic.h for declaration: this enables tracing Decls, is
5663+
// defined here to avoid too much layering violation / circular linkage
5664+
// dependency.
5665+
5666+
struct DeclTraceFormatter : public UnifiedStatsReporter::TraceFormatter {
5667+
void traceName(const void *Entity, raw_ostream &OS) const {
5668+
if (!Entity)
5669+
return;
5670+
const Decl *D = static_cast<const Decl *>(Entity);
5671+
if (auto const *VD = dyn_cast<const ValueDecl>(D)) {
5672+
VD->getFullName().print(OS, false);
5673+
}
5674+
}
5675+
void traceLoc(const void *Entity, SourceManager *SM,
5676+
clang::SourceManager *CSM, raw_ostream &OS) const {
5677+
if (!Entity)
5678+
return;
5679+
const Decl *D = static_cast<const Decl *>(Entity);
5680+
D->getSourceRange().print(OS, *SM, false);
5681+
}
5682+
};
5683+
5684+
static DeclTraceFormatter TF;
5685+
5686+
UnifiedStatsReporter::FrontendStatsTracer
5687+
UnifiedStatsReporter::getStatsTracer(StringRef EventName, const Decl *D) {
5688+
if (LastTracedFrontendCounters)
5689+
// Return live tracer object.
5690+
return FrontendStatsTracer(EventName, D, &TF, this);
5691+
else
5692+
// Return inert tracer object.
5693+
return FrontendStatsTracer();
5694+
}

lib/AST/Expr.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "swift/AST/Expr.h"
18+
#include "swift/Basic/Statistic.h"
1819
#include "swift/Basic/Unicode.h"
1920
#include "swift/AST/ASTContext.h"
2021
#include "swift/AST/ASTVisitor.h"
@@ -2276,3 +2277,32 @@ void KeyPathExpr::Component::setSubscriptIndexHashableConformances(
22762277
llvm_unreachable("no hashable conformances for this kind");
22772278
}
22782279
}
2280+
2281+
// See swift/Basic/Statistic.h for declaration: this enables tracing Decls, is
2282+
// defined here to avoid too much layering violation / circular linkage
2283+
// dependency.
2284+
2285+
struct ExprTraceFormatter : public UnifiedStatsReporter::TraceFormatter {
2286+
void traceName(const void *Entity, raw_ostream &OS) const {
2287+
// Exprs don't have names.
2288+
}
2289+
void traceLoc(const void *Entity, SourceManager *SM,
2290+
clang::SourceManager *CSM, raw_ostream &OS) const {
2291+
if (!Entity)
2292+
return;
2293+
const Expr *D = static_cast<const Expr *>(Entity);
2294+
D->getSourceRange().print(OS, *SM, false);
2295+
}
2296+
};
2297+
2298+
static ExprTraceFormatter TF;
2299+
2300+
UnifiedStatsReporter::FrontendStatsTracer
2301+
UnifiedStatsReporter::getStatsTracer(StringRef EventName, const Expr *E) {
2302+
if (LastTracedFrontendCounters)
2303+
// Return live tracer object.
2304+
return FrontendStatsTracer(EventName, E, &TF, this);
2305+
else
2306+
// Return inert tracer object.
2307+
return FrontendStatsTracer();
2308+
}

lib/Basic/Statistic.cpp

Lines changed: 16 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -260,19 +260,23 @@ UnifiedStatsReporter::printAlwaysOnStatsAndTimers(raw_ostream &OS) {
260260

261261
UnifiedStatsReporter::FrontendStatsTracer::FrontendStatsTracer(
262262
StringRef EventName,
263-
TraceEntity Entity,
263+
const void *Entity,
264+
const TraceFormatter *Formatter,
264265
UnifiedStatsReporter *Reporter)
265266
: Reporter(Reporter),
266267
SavedTime(llvm::TimeRecord::getCurrentTime()),
267268
EventName(EventName),
268-
Entity(Entity)
269+
Entity(Entity),
270+
Formatter(Formatter)
269271
{
270272
if (Reporter)
271273
Reporter->saveAnyFrontendStatsEvents(*this, true);
272274
}
273275

274276
UnifiedStatsReporter::FrontendStatsTracer::FrontendStatsTracer()
275-
: Reporter(nullptr)
277+
: Reporter(nullptr),
278+
Entity(nullptr),
279+
Formatter(nullptr)
276280
{
277281
}
278282

@@ -284,6 +288,7 @@ UnifiedStatsReporter::FrontendStatsTracer::operator=(
284288
SavedTime = other.SavedTime;
285289
EventName = other.EventName;
286290
Entity = other.Entity;
291+
Formatter = other.Formatter;
287292
other.Reporter = nullptr;
288293
return *this;
289294
}
@@ -293,7 +298,8 @@ UnifiedStatsReporter::FrontendStatsTracer::FrontendStatsTracer(
293298
: Reporter(other.Reporter),
294299
SavedTime(other.SavedTime),
295300
EventName(other.EventName),
296-
Entity(other.Entity)
301+
Entity(other.Entity),
302+
Formatter(other.Formatter)
297303
{
298304
other.Reporter = nullptr;
299305
}
@@ -304,47 +310,6 @@ UnifiedStatsReporter::FrontendStatsTracer::~FrontendStatsTracer()
304310
Reporter->saveAnyFrontendStatsEvents(*this, false);
305311
}
306312

307-
UnifiedStatsReporter::FrontendStatsTracer
308-
UnifiedStatsReporter::getStatsTracer(StringRef EventName,
309-
const Decl *D)
310-
{
311-
if (LastTracedFrontendCounters)
312-
// Return live tracer object.
313-
return FrontendStatsTracer(EventName, D, this);
314-
else
315-
// Return inert tracer object.
316-
return FrontendStatsTracer();
317-
}
318-
319-
UnifiedStatsReporter::FrontendStatsTracer
320-
UnifiedStatsReporter::getStatsTracer(StringRef EventName,
321-
const Expr *E) {
322-
if (LastTracedFrontendCounters)
323-
return FrontendStatsTracer(EventName, E, this);
324-
else
325-
return FrontendStatsTracer();
326-
}
327-
328-
UnifiedStatsReporter::FrontendStatsTracer
329-
UnifiedStatsReporter::getStatsTracer(StringRef EventName,
330-
const clang::Decl *D)
331-
{
332-
if (LastTracedFrontendCounters)
333-
return FrontendStatsTracer(EventName, D, this);
334-
else
335-
return FrontendStatsTracer();
336-
}
337-
338-
UnifiedStatsReporter::FrontendStatsTracer
339-
UnifiedStatsReporter::getStatsTracer(StringRef EventName,
340-
const SILFunction *F)
341-
{
342-
if (LastTracedFrontendCounters)
343-
return FrontendStatsTracer(EventName, F, this);
344-
else
345-
return FrontendStatsTracer();
346-
}
347-
348313
void
349314
UnifiedStatsReporter::saveAnyFrontendStatsEvents(
350315
FrontendStatsTracer const& T,
@@ -366,7 +331,7 @@ UnifiedStatsReporter::saveAnyFrontendStatsEvents(
366331
LastTracedFrontendCounters->NAME = C.NAME; \
367332
FrontendStatsEvents.emplace_back(FrontendStatsEvent { \
368333
NowUS, LiveUS, IsEntry, T.EventName, name, \
369-
delta, total, T.Entity}); \
334+
delta, total, T.Entity, T.Formatter}); \
370335
} \
371336
} while (0);
372337
#include "swift/Basic/Statistics.def"
@@ -382,56 +347,7 @@ UnifiedStatsReporter::AlwaysOnFrontendRecursiveSharedTimers::
382347
dummyInstanceVariableToGetConstructorToParse(0) {
383348
}
384349

385-
static inline void
386-
printTraceEntityName(raw_ostream &OS,
387-
UnifiedStatsReporter::TraceEntity E) {
388-
if (auto const *CD = E.dyn_cast<const clang::Decl*>()) {
389-
if (auto const *ND = dyn_cast<const clang::NamedDecl>(CD)) {
390-
ND->printName(OS);
391-
}
392-
} else if (auto const *D = E.dyn_cast<const Decl*>()) {
393-
if (auto const *VD = dyn_cast<const ValueDecl>(D)) {
394-
VD->getFullName().print(OS, false);
395-
}
396-
} else if (auto const *X = E.dyn_cast<const Expr*>()) {
397-
// Exprs don't have names
398-
} else if (auto const *F = E.dyn_cast<const SILFunction*>()) {
399-
OS << F->getName();
400-
}
401-
}
402-
403-
static inline void
404-
printClangShortLoc(raw_ostream &OS,
405-
clang::SourceManager *CSM,
406-
clang::SourceLocation L) {
407-
if (!L.isValid() || !L.isFileID())
408-
return;
409-
auto PLoc = CSM->getPresumedLoc(L);
410-
OS << llvm::sys::path::filename(PLoc.getFilename())
411-
<< ':' << PLoc.getLine()
412-
<< ':' << PLoc.getColumn();
413-
}
414-
415-
static inline void
416-
printTraceEntityLoc(raw_ostream &OS,
417-
SourceManager *SM,
418-
clang::SourceManager *CSM,
419-
UnifiedStatsReporter::TraceEntity E) {
420-
if (auto const *CD = E.dyn_cast<const clang::Decl*>()) {
421-
if (CSM) {
422-
auto Range = CD->getSourceRange();
423-
printClangShortLoc(OS, CSM, Range.getBegin());
424-
OS << '-';
425-
printClangShortLoc(OS, CSM, Range.getEnd());
426-
}
427-
} else if (auto const *D = E.dyn_cast<const Decl*>()) {
428-
D->getSourceRange().print(OS, *SM, false);
429-
} else if (auto const *X = E.dyn_cast<const Expr*>()) {
430-
X->getSourceRange().print(OS, *SM, false);
431-
} else if (auto const *F = E.dyn_cast<const SILFunction*>()) {
432-
F->getLocation().getSourceRange().print(OS, *SM, false);
433-
}
434-
}
350+
UnifiedStatsReporter::TraceFormatter::~TraceFormatter() {}
435351

436352
UnifiedStatsReporter::~UnifiedStatsReporter()
437353
{
@@ -519,10 +435,12 @@ UnifiedStatsReporter::~UnifiedStatsReporter()
519435
<< E.CounterDelta << ','
520436
<< E.CounterValue << ',';
521437
tstream << '"';
522-
printTraceEntityName(tstream, E.Entity);
438+
if (E.Formatter)
439+
E.Formatter->traceName(E.Entity, tstream);
523440
tstream << '"' << ',';
524441
tstream << '"';
525-
printTraceEntityLoc(tstream, SourceMgr, ClangSourceMgr, E.Entity);
442+
if (E.Formatter)
443+
E.Formatter->traceLoc(E.Entity, SourceMgr, ClangSourceMgr, tstream);
526444
tstream << '"' << '\n';
527445
}
528446
}

lib/ClangImporter/ImportDecl.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8585,3 +8585,53 @@ ClangImporter::getEnumConstantName(const clang::EnumConstantDecl *enumConstant){
85858585
.getBaseIdentifier();
85868586
}
85878587

8588+
// See swift/Basic/Statistic.h for declaration: this enables tracing
8589+
// clang::Decls, is defined here to avoid too much layering violation / circular
8590+
// linkage dependency.
8591+
8592+
struct ClangDeclTraceFormatter : public UnifiedStatsReporter::TraceFormatter {
8593+
void traceName(const void *Entity, raw_ostream &OS) const {
8594+
if (!Entity)
8595+
return;
8596+
const clang::Decl *CD = static_cast<const clang::Decl *>(Entity);
8597+
if (auto const *ND = dyn_cast<const clang::NamedDecl>(CD)) {
8598+
ND->printName(OS);
8599+
}
8600+
}
8601+
8602+
static inline void printClangShortLoc(raw_ostream &OS,
8603+
clang::SourceManager *CSM,
8604+
clang::SourceLocation L) {
8605+
if (!L.isValid() || !L.isFileID())
8606+
return;
8607+
auto PLoc = CSM->getPresumedLoc(L);
8608+
OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' << PLoc.getLine()
8609+
<< ':' << PLoc.getColumn();
8610+
}
8611+
8612+
void traceLoc(const void *Entity, SourceManager *SM,
8613+
clang::SourceManager *CSM, raw_ostream &OS) const {
8614+
if (!Entity)
8615+
return;
8616+
if (CSM) {
8617+
const clang::Decl *CD = static_cast<const clang::Decl *>(Entity);
8618+
auto Range = CD->getSourceRange();
8619+
printClangShortLoc(OS, CSM, Range.getBegin());
8620+
OS << '-';
8621+
printClangShortLoc(OS, CSM, Range.getEnd());
8622+
}
8623+
}
8624+
};
8625+
8626+
static ClangDeclTraceFormatter TF;
8627+
8628+
UnifiedStatsReporter::FrontendStatsTracer
8629+
UnifiedStatsReporter::getStatsTracer(StringRef EventName,
8630+
const clang::Decl *D) {
8631+
if (LastTracedFrontendCounters)
8632+
// Return live tracer object.
8633+
return FrontendStatsTracer(EventName, D, &TF, this);
8634+
else
8635+
// Return inert tracer object.
8636+
return FrontendStatsTracer();
8637+
}

0 commit comments

Comments
 (0)