Merge pull request #12077 from graydon/doc-typo
diff --git a/include/swift/Basic/Statistic.h b/include/swift/Basic/Statistic.h
index ae1382a..3ee26e2 100644
--- a/include/swift/Basic/Statistic.h
+++ b/include/swift/Basic/Statistic.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
+#include "swift/Basic/SourceLoc.h"
#include "swift/Basic/Timer.h"
#define SWIFT_FUNC_STAT \
@@ -53,100 +54,66 @@
public:
struct AlwaysOnDriverCounters
{
- size_t NumDriverJobsRun;
- size_t NumDriverJobsSkipped;
-
- size_t DriverDepCascadingTopLevel;
- size_t DriverDepCascadingDynamic;
- size_t DriverDepCascadingNominal;
- size_t DriverDepCascadingMember;
- size_t DriverDepCascadingExternal;
-
- size_t DriverDepTopLevel;
- size_t DriverDepDynamic;
- size_t DriverDepNominal;
- size_t DriverDepMember;
- size_t DriverDepExternal;
-
- size_t ChildrenMaxRSS;
+#define DRIVER_STATISTIC(ID) size_t ID;
+#include "Statistics.def"
+#undef DRIVER_STATISTIC
};
struct AlwaysOnFrontendCounters
{
- size_t NumSourceBuffers;
- size_t NumSourceLines;
- size_t NumSourceLinesPerSecond;
- size_t NumLinkLibraries;
- size_t NumLoadedModules;
- size_t NumImportedExternalDefinitions;
- size_t NumTotalClangImportedEntities;
- size_t NumASTBytesAllocated;
- size_t NumDependencies;
- size_t NumReferencedTopLevelNames;
- size_t NumReferencedDynamicNames;
- size_t NumReferencedMemberNames;
- size_t NumDecls;
- size_t NumLocalTypeDecls;
- size_t NumObjCMethods;
- size_t NumInfixOperators;
- size_t NumPostfixOperators;
- size_t NumPrefixOperators;
- size_t NumPrecedenceGroups;
- size_t NumUsedConformances;
+#define FRONTEND_STATISTIC(NAME, ID) size_t ID;
+#include "Statistics.def"
+#undef FRONTEND_STATISTIC
+ };
- size_t NumConformancesDeserialized;
- size_t NumConstraintScopes;
- size_t NumDeclsDeserialized;
- size_t NumDeclsValidated;
- size_t NumFunctionsTypechecked;
- size_t NumGenericSignatureBuilders;
- size_t NumLazyGenericEnvironments;
- size_t NumLazyGenericEnvironmentsLoaded;
- size_t NumLazyIterableDeclContexts;
- size_t NominalTypeLookupDirectCount;
- size_t NumTypesDeserialized;
- size_t NumTypesValidated;
- size_t NumUnloadedLazyIterableDeclContexts;
+ struct FrontendStatsTracer
+ {
+ UnifiedStatsReporter *Reporter;
+ llvm::TimeRecord SavedTime;
+ StringRef Name;
+ SourceRange Range;
+ FrontendStatsTracer(StringRef Name,
+ SourceRange const &Range,
+ UnifiedStatsReporter *Reporter);
+ FrontendStatsTracer();
+ FrontendStatsTracer(FrontendStatsTracer&& other);
+ FrontendStatsTracer& operator=(FrontendStatsTracer&&);
+ ~FrontendStatsTracer();
+ FrontendStatsTracer(const FrontendStatsTracer&) = delete;
+ FrontendStatsTracer& operator=(const FrontendStatsTracer&) = delete;
+ };
- size_t NumSILGenFunctions;
- size_t NumSILGenVtables;
- size_t NumSILGenWitnessTables;
- size_t NumSILGenDefaultWitnessTables;
- size_t NumSILGenGlobalVariables;
-
- size_t NumSILOptFunctions;
- size_t NumSILOptVtables;
- size_t NumSILOptWitnessTables;
- size_t NumSILOptDefaultWitnessTables;
- size_t NumSILOptGlobalVariables;
-
- size_t NumIRGlobals;
- size_t NumIRFunctions;
- size_t NumIRAliases;
- size_t NumIRIFuncs;
- size_t NumIRNamedMetaData;
- size_t NumIRValueSymbols;
- size_t NumIRComdatSymbols;
- size_t NumIRBasicBlocks;
- size_t NumIRInsts;
-
- size_t NumLLVMBytesOutput;
+ struct FrontendStatsEvent
+ {
+ uint64_t TimeUSec;
+ uint64_t LiveUSec;
+ bool IsEntry;
+ StringRef EventName;
+ StringRef CounterName;
+ size_t CounterDelta;
+ size_t CounterValue;
+ SourceRange SourceRange;
};
private:
- SmallString<128> Filename;
+ SmallString<128> StatsFilename;
+ SmallString<128> TraceFilename;
llvm::TimeRecord StartedTime;
std::unique_ptr<llvm::NamedRegionTimer> Timer;
-
+ SourceManager *SourceMgr;
std::unique_ptr<AlwaysOnDriverCounters> DriverCounters;
std::unique_ptr<AlwaysOnFrontendCounters> FrontendCounters;
+ std::unique_ptr<AlwaysOnFrontendCounters> LastTracedFrontendCounters;
+ std::vector<FrontendStatsEvent> FrontendStatsEvents;
void publishAlwaysOnStatsToLLVM();
void printAlwaysOnStatsAndTimers(llvm::raw_ostream &OS);
UnifiedStatsReporter(StringRef ProgramName,
StringRef AuxName,
- StringRef Directory);
+ StringRef Directory,
+ SourceManager *SM,
+ bool TraceEvents);
public:
UnifiedStatsReporter(StringRef ProgramName,
StringRef ModuleName,
@@ -154,11 +121,17 @@
StringRef TripleName,
StringRef OutputType,
StringRef OptType,
- StringRef Directory);
+ StringRef Directory,
+ SourceManager *SM=nullptr,
+ bool TraceEvents=false);
~UnifiedStatsReporter();
AlwaysOnDriverCounters &getDriverCounters();
AlwaysOnFrontendCounters &getFrontendCounters();
+ FrontendStatsTracer getStatsTracer(StringRef N,
+ SourceRange const &R);
+ void saveAnyFrontendStatsEvents(FrontendStatsTracer const& T,
+ bool IsEntry);
};
}
diff --git a/include/swift/Basic/Statistics.def b/include/swift/Basic/Statistics.def
new file mode 100644
index 0000000..343d761
--- /dev/null
+++ b/include/swift/Basic/Statistics.def
@@ -0,0 +1,103 @@
+//===--- Statistics.def - Statistics Macro Metaprogramming Database -*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the database of always-available statistic counters.
+//
+// DRIVER_STATISTIC(Id)
+// - Id is an identifier suitable for use in C++
+//
+// FRONTEND_STATISTIC(Subsystem, Id)
+// - Subsystem is a token to be stringified as a name prefix
+// - Id is an identifier suitable for use in C++
+//===----------------------------------------------------------------------===//
+
+/// Driver statistics are collected for driver processes
+#ifdef DRIVER_STATISTIC
+DRIVER_STATISTIC(NumDriverJobsRun)
+DRIVER_STATISTIC(NumDriverJobsSkipped)
+
+DRIVER_STATISTIC(DriverDepCascadingTopLevel)
+DRIVER_STATISTIC(DriverDepCascadingDynamic)
+DRIVER_STATISTIC(DriverDepCascadingNominal)
+DRIVER_STATISTIC(DriverDepCascadingMember)
+DRIVER_STATISTIC(DriverDepCascadingExternal)
+
+DRIVER_STATISTIC(DriverDepTopLevel)
+DRIVER_STATISTIC(DriverDepDynamic)
+DRIVER_STATISTIC(DriverDepNominal)
+DRIVER_STATISTIC(DriverDepMember)
+DRIVER_STATISTIC(DriverDepExternal)
+
+DRIVER_STATISTIC(ChildrenMaxRSS)
+#endif
+
+/// Driver statistics are collected for frontend processes
+#ifdef FRONTEND_STATISTIC
+FRONTEND_STATISTIC(AST, NumSourceBuffers)
+FRONTEND_STATISTIC(AST, NumSourceLines)
+FRONTEND_STATISTIC(AST, NumSourceLinesPerSecond)
+FRONTEND_STATISTIC(AST, NumLinkLibraries)
+FRONTEND_STATISTIC(AST, NumLoadedModules)
+FRONTEND_STATISTIC(AST, NumImportedExternalDefinitions)
+FRONTEND_STATISTIC(AST, NumTotalClangImportedEntities)
+FRONTEND_STATISTIC(AST, NumASTBytesAllocated)
+FRONTEND_STATISTIC(AST, NumDependencies)
+FRONTEND_STATISTIC(AST, NumReferencedTopLevelNames)
+FRONTEND_STATISTIC(AST, NumReferencedDynamicNames)
+FRONTEND_STATISTIC(AST, NumReferencedMemberNames)
+FRONTEND_STATISTIC(AST, NumDecls)
+FRONTEND_STATISTIC(AST, NumLocalTypeDecls)
+FRONTEND_STATISTIC(AST, NumObjCMethods)
+FRONTEND_STATISTIC(AST, NumInfixOperators)
+FRONTEND_STATISTIC(AST, NumPostfixOperators)
+FRONTEND_STATISTIC(AST, NumPrefixOperators)
+FRONTEND_STATISTIC(AST, NumPrecedenceGroups)
+FRONTEND_STATISTIC(AST, NumUsedConformances)
+
+FRONTEND_STATISTIC(Sema, NumConformancesDeserialized)
+FRONTEND_STATISTIC(Sema, NumConstraintScopes)
+FRONTEND_STATISTIC(Sema, NumDeclsDeserialized)
+FRONTEND_STATISTIC(Sema, NumDeclsValidated)
+FRONTEND_STATISTIC(Sema, NumFunctionsTypechecked)
+FRONTEND_STATISTIC(Sema, NumGenericSignatureBuilders)
+FRONTEND_STATISTIC(Sema, NumLazyGenericEnvironments)
+FRONTEND_STATISTIC(Sema, NumLazyGenericEnvironmentsLoaded)
+FRONTEND_STATISTIC(Sema, NumLazyIterableDeclContexts)
+FRONTEND_STATISTIC(Sema, NominalTypeLookupDirectCount)
+FRONTEND_STATISTIC(Sema, NumTypesDeserialized)
+FRONTEND_STATISTIC(Sema, NumTypesValidated)
+FRONTEND_STATISTIC(Sema, NumUnloadedLazyIterableDeclContexts)
+
+FRONTEND_STATISTIC(SILModule, NumSILGenFunctions)
+FRONTEND_STATISTIC(SILModule, NumSILGenVtables)
+FRONTEND_STATISTIC(SILModule, NumSILGenWitnessTables)
+FRONTEND_STATISTIC(SILModule, NumSILGenDefaultWitnessTables)
+FRONTEND_STATISTIC(SILModule, NumSILGenGlobalVariables)
+
+FRONTEND_STATISTIC(SILModule, NumSILOptFunctions)
+FRONTEND_STATISTIC(SILModule, NumSILOptVtables)
+FRONTEND_STATISTIC(SILModule, NumSILOptWitnessTables)
+FRONTEND_STATISTIC(SILModule, NumSILOptDefaultWitnessTables)
+FRONTEND_STATISTIC(SILModule, NumSILOptGlobalVariables)
+
+FRONTEND_STATISTIC(IRModule, NumIRGlobals)
+FRONTEND_STATISTIC(IRModule, NumIRFunctions)
+FRONTEND_STATISTIC(IRModule, NumIRAliases)
+FRONTEND_STATISTIC(IRModule, NumIRIFuncs)
+FRONTEND_STATISTIC(IRModule, NumIRNamedMetaData)
+FRONTEND_STATISTIC(IRModule, NumIRValueSymbols)
+FRONTEND_STATISTIC(IRModule, NumIRComdatSymbols)
+FRONTEND_STATISTIC(IRModule, NumIRBasicBlocks)
+FRONTEND_STATISTIC(IRModule, NumIRInsts)
+
+FRONTEND_STATISTIC(LLVM, NumLLVMBytesOutput)
+#endif
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index b370360..32d68b0 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -222,6 +222,9 @@
/// The path to which we should output statistics files.
std::string StatsOutputDir;
+ /// Trace changes to stats to files in StatsOutputDir.
+ bool TraceStats = false;
+
/// Indicates whether function body parsing should be delayed
/// until the end of all files.
bool DelayedFunctionBodyParsing = false;
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 40de10c..33d80e9 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -194,6 +194,9 @@
def stats_output_dir: Separate<["-"], "stats-output-dir">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Directory to write unified compilation-statistics files to">;
+def trace_stats_events: Flag<["-"], "trace-stats-events">,
+ Flags<[FrontendOption, HelpHidden]>,
+ HelpText<"Trace changes to stats in -stats-output-dir">;
def emit_dependencies : Flag<["-"], "emit-dependencies">,
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
diff --git a/lib/Basic/Statistic.cpp b/lib/Basic/Statistic.cpp
index 225f893..6165702 100644
--- a/lib/Basic/Statistic.cpp
+++ b/lib/Basic/Statistic.cpp
@@ -42,20 +42,34 @@
}
static std::string
-makeFileName(StringRef ProgramName,
- StringRef AuxName) {
+makeFileName(StringRef Prefix,
+ StringRef ProgramName,
+ StringRef AuxName,
+ StringRef Suffix) {
std::string tmp;
raw_string_ostream stream(tmp);
auto now = std::chrono::system_clock::now();
- stream << "stats"
+ stream << Prefix
<< "-" << now.time_since_epoch().count()
<< "-" << ProgramName
<< "-" << AuxName
<< "-" << Process::GetRandomNumber()
- << ".json";
+ << "." << Suffix;
return stream.str();
}
+static std::string
+makeStatsFileName(StringRef ProgramName,
+ StringRef AuxName) {
+ return makeFileName("stats", ProgramName, AuxName, "json");
+}
+
+static std::string
+makeTraceFileName(StringRef ProgramName,
+ StringRef AuxName) {
+ return makeFileName("trace", ProgramName, AuxName, "csv");
+}
+
// LLVM's statistics-reporting machinery is sensitive to filenames containing
// YAML-quote-requiring characters, which occur surprisingly often in the wild;
// we only need a recognizable and likely-unique name for a target here, not an
@@ -108,29 +122,39 @@
StringRef TripleName,
StringRef OutputType,
StringRef OptType,
- StringRef Directory)
+ StringRef Directory,
+ SourceManager *SM,
+ bool TraceEvents)
: UnifiedStatsReporter(ProgramName,
auxName(ModuleName,
InputName,
TripleName,
OutputType,
OptType),
- Directory)
+ Directory,
+ SM, TraceEvents)
{
}
UnifiedStatsReporter::UnifiedStatsReporter(StringRef ProgramName,
StringRef AuxName,
- StringRef Directory)
- : Filename(Directory),
+ StringRef Directory,
+ SourceManager *SM,
+ bool TraceEvents)
+ : StatsFilename(Directory),
+ TraceFilename(Directory),
StartedTime(llvm::TimeRecord::getCurrentTime()),
Timer(make_unique<NamedRegionTimer>(AuxName,
"Building Target",
- ProgramName, "Running Program"))
+ ProgramName, "Running Program")),
+ SourceMgr(SM)
{
- path::append(Filename, makeFileName(ProgramName, AuxName));
+ path::append(StatsFilename, makeStatsFileName(ProgramName, AuxName));
+ path::append(TraceFilename, makeTraceFileName(ProgramName, AuxName));
EnableStatistics(/*PrintOnExit=*/false);
SharedTimer::enableCompilationTimers();
+ if (TraceEvents)
+ LastTracedFrontendCounters = make_unique<AlwaysOnFrontendCounters>();
}
UnifiedStatsReporter::AlwaysOnDriverCounters &
@@ -149,102 +173,30 @@
return *FrontendCounters;
}
-#define PUBLISH_STAT(C,TY,NAME) \
- do { \
- static Statistic Stat = {TY, #NAME, #NAME, {0}, false}; \
- Stat += (C).NAME; \
- } while (0)
-
void
UnifiedStatsReporter::publishAlwaysOnStatsToLLVM() {
if (FrontendCounters) {
auto &C = getFrontendCounters();
-
- PUBLISH_STAT(C, "AST", NumSourceBuffers);
- PUBLISH_STAT(C, "AST", NumSourceLines);
- PUBLISH_STAT(C, "AST", NumSourceLinesPerSecond);
- PUBLISH_STAT(C, "AST", NumLinkLibraries);
- PUBLISH_STAT(C, "AST", NumLoadedModules);
- PUBLISH_STAT(C, "AST", NumImportedExternalDefinitions);
- PUBLISH_STAT(C, "AST", NumTotalClangImportedEntities);
- PUBLISH_STAT(C, "AST", NumASTBytesAllocated);
- PUBLISH_STAT(C, "AST", NumDependencies);
- PUBLISH_STAT(C, "AST", NumReferencedTopLevelNames);
- PUBLISH_STAT(C, "AST", NumReferencedDynamicNames);
- PUBLISH_STAT(C, "AST", NumReferencedMemberNames);
- PUBLISH_STAT(C, "AST", NumDecls);
- PUBLISH_STAT(C, "AST", NumLocalTypeDecls);
- PUBLISH_STAT(C, "AST", NumObjCMethods);
- PUBLISH_STAT(C, "AST", NumInfixOperators);
- PUBLISH_STAT(C, "AST", NumPostfixOperators);
- PUBLISH_STAT(C, "AST", NumPrefixOperators);
- PUBLISH_STAT(C, "AST", NumPrecedenceGroups);
- PUBLISH_STAT(C, "AST", NumUsedConformances);
-
- PUBLISH_STAT(C, "Sema", NumConformancesDeserialized);
- PUBLISH_STAT(C, "Sema", NumConstraintScopes);
- PUBLISH_STAT(C, "Sema", NumDeclsDeserialized);
- PUBLISH_STAT(C, "Sema", NumDeclsValidated);
- PUBLISH_STAT(C, "Sema", NumFunctionsTypechecked);
- PUBLISH_STAT(C, "Sema", NumGenericSignatureBuilders);
- PUBLISH_STAT(C, "Sema", NumLazyGenericEnvironments);
- PUBLISH_STAT(C, "Sema", NumLazyGenericEnvironmentsLoaded);
- PUBLISH_STAT(C, "Sema", NumLazyIterableDeclContexts);
- PUBLISH_STAT(C, "Sema", NominalTypeLookupDirectCount);
- PUBLISH_STAT(C, "Sema", NumTypesDeserialized);
- PUBLISH_STAT(C, "Sema", NumTypesValidated);
- PUBLISH_STAT(C, "Sema", NumUnloadedLazyIterableDeclContexts);
-
- PUBLISH_STAT(C, "SILModule", NumSILGenFunctions);
- PUBLISH_STAT(C, "SILModule", NumSILGenVtables);
- PUBLISH_STAT(C, "SILModule", NumSILGenWitnessTables);
- PUBLISH_STAT(C, "SILModule", NumSILGenDefaultWitnessTables);
- PUBLISH_STAT(C, "SILModule", NumSILGenGlobalVariables);
-
- PUBLISH_STAT(C, "SILModule", NumSILOptFunctions);
- PUBLISH_STAT(C, "SILModule", NumSILOptVtables);
- PUBLISH_STAT(C, "SILModule", NumSILOptWitnessTables);
- PUBLISH_STAT(C, "SILModule", NumSILOptDefaultWitnessTables);
- PUBLISH_STAT(C, "SILModule", NumSILOptGlobalVariables);
-
- PUBLISH_STAT(C, "IRModule", NumIRGlobals);
- PUBLISH_STAT(C, "IRModule", NumIRFunctions);
- PUBLISH_STAT(C, "IRModule", NumIRAliases);
- PUBLISH_STAT(C, "IRModule", NumIRIFuncs);
- PUBLISH_STAT(C, "IRModule", NumIRNamedMetaData);
- PUBLISH_STAT(C, "IRModule", NumIRValueSymbols);
- PUBLISH_STAT(C, "IRModule", NumIRComdatSymbols);
- PUBLISH_STAT(C, "IRModule", NumIRBasicBlocks);
- PUBLISH_STAT(C, "IRModule", NumIRInsts);
-
- PUBLISH_STAT(C, "LLVM", NumLLVMBytesOutput);
+#define FRONTEND_STATISTIC(TY, NAME) \
+ do { \
+ static Statistic Stat = {#TY, #NAME, #NAME, {0}, false}; \
+ Stat += (C).NAME; \
+ } while (0);
+#include "swift/Basic/Statistics.def"
+#undef FRONTEND_STATISTIC
}
if (DriverCounters) {
auto &C = getDriverCounters();
- PUBLISH_STAT(C, "Driver", NumDriverJobsRun);
- PUBLISH_STAT(C, "Driver", NumDriverJobsSkipped);
-
- PUBLISH_STAT(C, "Driver", DriverDepCascadingTopLevel);
- PUBLISH_STAT(C, "Driver", DriverDepCascadingDynamic);
- PUBLISH_STAT(C, "Driver", DriverDepCascadingNominal);
- PUBLISH_STAT(C, "Driver", DriverDepCascadingMember);
- PUBLISH_STAT(C, "Driver", DriverDepCascadingExternal);
-
- PUBLISH_STAT(C, "Driver", DriverDepTopLevel);
- PUBLISH_STAT(C, "Driver", DriverDepDynamic);
- PUBLISH_STAT(C, "Driver", DriverDepNominal);
- PUBLISH_STAT(C, "Driver", DriverDepMember);
- PUBLISH_STAT(C, "Driver", DriverDepExternal);
- PUBLISH_STAT(C, "Driver", ChildrenMaxRSS);
+#define DRIVER_STATISTIC(NAME) \
+ do { \
+ static Statistic Stat = {"Driver", #NAME, #NAME, {0}, false}; \
+ Stat += (C).NAME; \
+ } while (0);
+#include "swift/Basic/Statistics.def"
+#undef DRIVER_STATISTIC
}
}
-#define PRINT_STAT(OS,DELIM,C,TY,NAME) \
- do { \
- OS << DELIM << "\t\"" TY "." #NAME "\": " << C.NAME; \
- delim = ",\n"; \
- } while (0)
-
void
UnifiedStatsReporter::printAlwaysOnStatsAndTimers(raw_ostream &OS) {
// Adapted from llvm::PrintStatisticsJSON
@@ -252,83 +204,23 @@
const char *delim = "";
if (FrontendCounters) {
auto &C = getFrontendCounters();
-
- PRINT_STAT(OS, delim, C, "AST", NumSourceBuffers);
- PRINT_STAT(OS, delim, C, "AST", NumSourceLines);
- PRINT_STAT(OS, delim, C, "AST", NumSourceLinesPerSecond);
- PRINT_STAT(OS, delim, C, "AST", NumLinkLibraries);
- PRINT_STAT(OS, delim, C, "AST", NumLoadedModules);
- PRINT_STAT(OS, delim, C, "AST", NumImportedExternalDefinitions);
- PRINT_STAT(OS, delim, C, "AST", NumTotalClangImportedEntities);
- PRINT_STAT(OS, delim, C, "AST", NumASTBytesAllocated);
- PRINT_STAT(OS, delim, C, "AST", NumDependencies);
- PRINT_STAT(OS, delim, C, "AST", NumReferencedTopLevelNames);
- PRINT_STAT(OS, delim, C, "AST", NumReferencedDynamicNames);
- PRINT_STAT(OS, delim, C, "AST", NumReferencedMemberNames);
- PRINT_STAT(OS, delim, C, "AST", NumDecls);
- PRINT_STAT(OS, delim, C, "AST", NumLocalTypeDecls);
- PRINT_STAT(OS, delim, C, "AST", NumObjCMethods);
- PRINT_STAT(OS, delim, C, "AST", NumInfixOperators);
- PRINT_STAT(OS, delim, C, "AST", NumPostfixOperators);
- PRINT_STAT(OS, delim, C, "AST", NumPrefixOperators);
- PRINT_STAT(OS, delim, C, "AST", NumPrecedenceGroups);
- PRINT_STAT(OS, delim, C, "AST", NumUsedConformances);
-
- PRINT_STAT(OS, delim, C, "Sema", NumConformancesDeserialized);
- PRINT_STAT(OS, delim, C, "Sema", NumConstraintScopes);
- PRINT_STAT(OS, delim, C, "Sema", NumDeclsDeserialized);
- PRINT_STAT(OS, delim, C, "Sema", NumDeclsValidated);
- PRINT_STAT(OS, delim, C, "Sema", NumFunctionsTypechecked);
- PRINT_STAT(OS, delim, C, "Sema", NumGenericSignatureBuilders);
- PRINT_STAT(OS, delim, C, "Sema", NumLazyGenericEnvironments);
- PRINT_STAT(OS, delim, C, "Sema", NumLazyGenericEnvironmentsLoaded);
- PRINT_STAT(OS, delim, C, "Sema", NumLazyIterableDeclContexts);
- PRINT_STAT(OS, delim, C, "Sema", NominalTypeLookupDirectCount);
- PRINT_STAT(OS, delim, C, "Sema", NumTypesDeserialized);
- PRINT_STAT(OS, delim, C, "Sema", NumTypesValidated);
- PRINT_STAT(OS, delim, C, "Sema", NumUnloadedLazyIterableDeclContexts);
-
- PRINT_STAT(OS, delim, C, "SILModule", NumSILGenFunctions);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILGenVtables);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILGenWitnessTables);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILGenDefaultWitnessTables);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILGenGlobalVariables);
-
- PRINT_STAT(OS, delim, C, "SILModule", NumSILOptFunctions);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILOptVtables);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILOptWitnessTables);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILOptDefaultWitnessTables);
- PRINT_STAT(OS, delim, C, "SILModule", NumSILOptGlobalVariables);
-
- PRINT_STAT(OS, delim, C, "IRModule", NumIRGlobals);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRFunctions);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRAliases);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRIFuncs);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRNamedMetaData);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRValueSymbols);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRComdatSymbols);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRBasicBlocks);
- PRINT_STAT(OS, delim, C, "IRModule", NumIRInsts);
-
- PRINT_STAT(OS, delim, C, "LLVM", NumLLVMBytesOutput);
+#define FRONTEND_STATISTIC(TY, NAME) \
+ do { \
+ OS << delim << "\t\"" #TY "." #NAME "\": " << C.NAME; \
+ delim = ",\n"; \
+ } while (0);
+#include "swift/Basic/Statistics.def"
+#undef FRONTEND_STATISTIC
}
if (DriverCounters) {
auto &C = getDriverCounters();
- PRINT_STAT(OS, delim, C, "Driver", NumDriverJobsRun);
- PRINT_STAT(OS, delim, C, "Driver", NumDriverJobsSkipped);
-
- PRINT_STAT(OS, delim, C, "Driver", DriverDepCascadingTopLevel);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepCascadingDynamic);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepCascadingNominal);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepCascadingMember);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepCascadingExternal);
-
- PRINT_STAT(OS, delim, C, "Driver", DriverDepTopLevel);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepDynamic);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepNominal);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepMember);
- PRINT_STAT(OS, delim, C, "Driver", DriverDepExternal);
- PRINT_STAT(OS, delim, C, "Driver", ChildrenMaxRSS);
+#define DRIVER_STATISTIC(NAME) \
+ do { \
+ OS << delim << "\t\"Driver." #NAME "\": " << C.NAME; \
+ delim = ",\n"; \
+ } while (0);
+#include "swift/Basic/Statistics.def"
+#undef DRIVER_STATISTIC
}
// Print timers.
TimerGroup::printAllJSONValues(OS, delim);
@@ -336,6 +228,91 @@
OS.flush();
}
+UnifiedStatsReporter::FrontendStatsTracer::FrontendStatsTracer(
+ StringRef Name,
+ SourceRange const &Range,
+ UnifiedStatsReporter *Reporter)
+ : Reporter(Reporter),
+ SavedTime(llvm::TimeRecord::getCurrentTime()),
+ Name(Name),
+ Range(Range)
+{
+ if (Reporter)
+ Reporter->saveAnyFrontendStatsEvents(*this, true);
+}
+
+UnifiedStatsReporter::FrontendStatsTracer::FrontendStatsTracer()
+ : Reporter(nullptr)
+{
+}
+
+UnifiedStatsReporter::FrontendStatsTracer&
+UnifiedStatsReporter::FrontendStatsTracer::operator=(
+ FrontendStatsTracer&& other)
+{
+ Reporter = other.Reporter;
+ SavedTime = other.SavedTime;
+ Name = other.Name;
+ Range = other.Range;
+ other.Reporter = nullptr;
+ return *this;
+}
+
+UnifiedStatsReporter::FrontendStatsTracer::FrontendStatsTracer(
+ FrontendStatsTracer&& other)
+ : Reporter(other.Reporter),
+ SavedTime(other.SavedTime),
+ Name(other.Name),
+ Range(other.Range)
+{
+ other.Reporter = nullptr;
+}
+
+UnifiedStatsReporter::FrontendStatsTracer::~FrontendStatsTracer()
+{
+ if (Reporter)
+ Reporter->saveAnyFrontendStatsEvents(*this, false);
+}
+
+UnifiedStatsReporter::FrontendStatsTracer
+UnifiedStatsReporter::getStatsTracer(StringRef N,
+ SourceRange const &R)
+{
+ if (LastTracedFrontendCounters)
+ // Return live tracer object.
+ return FrontendStatsTracer(N, R, this);
+ else
+ // Return inert tracer object.
+ return FrontendStatsTracer();
+}
+
+void
+UnifiedStatsReporter::saveAnyFrontendStatsEvents(
+ FrontendStatsTracer const& T,
+ bool IsEntry)
+{
+ if (!LastTracedFrontendCounters)
+ return;
+ auto Now = llvm::TimeRecord::getCurrentTime();
+ auto StartUS = uint64_t(1000000.0 * T.SavedTime.getProcessTime());
+ auto NowUS = uint64_t(1000000.0 * Now.getProcessTime());
+ auto LiveUS = IsEntry ? 0 : NowUS - StartUS;
+ auto &C = getFrontendCounters();
+#define FRONTEND_STATISTIC(TY, NAME) \
+ do { \
+ auto delta = C.NAME - LastTracedFrontendCounters->NAME; \
+ static char const *name = #TY "." #NAME; \
+ if (delta != 0) { \
+ LastTracedFrontendCounters->NAME = C.NAME; \
+ FrontendStatsEvents.emplace_back(FrontendStatsEvent { \
+ NowUS, LiveUS, IsEntry, T.Name, name, \
+ delta, C.NAME, T.Range}); \
+ } \
+ } while (0);
+#include "swift/Basic/Statistics.def"
+#undef FRONTEND_STATISTIC
+}
+
UnifiedStatsReporter::~UnifiedStatsReporter()
{
// NB: Timer needs to be Optional<> because it needs to be destructed early;
@@ -364,7 +341,7 @@
}
std::error_code EC;
- raw_fd_ostream ostream(Filename, EC, fs::F_Append | fs::F_Text);
+ raw_fd_ostream ostream(StatsFilename, EC, fs::F_Append | fs::F_Text);
if (EC)
return;
@@ -387,6 +364,27 @@
#else
printAlwaysOnStatsAndTimers(ostream);
#endif
+
+ if (LastTracedFrontendCounters && SourceMgr) {
+ std::error_code EC;
+ raw_fd_ostream tstream(TraceFilename, EC, fs::F_Append | fs::F_Text);
+ if (EC)
+ return;
+ tstream << "Time,Live,IsEntry,EventName,CounterName,"
+ << "CounterDelta,CounterValue,SourceRange\n";
+ for (auto const &E : FrontendStatsEvents) {
+ tstream << E.TimeUSec << ','
+ << E.LiveUSec << ','
+ << (E.IsEntry ? "\"entry\"," : "\"exit\",")
+ << '"' << E.EventName << '"' << ','
+ << '"' << E.CounterName << '"' << ','
+ << E.CounterDelta << ','
+ << E.CounterValue << ',';
+ tstream << '"';
+ E.SourceRange.print(tstream, *SourceMgr, false);
+ tstream << '"' << '\n';
+ }
+ }
}
} // namespace swift
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 626df74..f0e03d0 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -151,6 +151,7 @@
inputArgs.AddLastArg(arguments, options::OPT_swift_version);
inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ);
inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
+ inputArgs.AddLastArg(arguments, options::OPT_trace_stats_events);
inputArgs.AddLastArg(arguments,
options::OPT_solver_shrink_unsolved_threshold);
inputArgs.AddLastArg(arguments, options::OPT_O_Group);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 0a12441..92ba309 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -194,6 +194,9 @@
Opts.DebugTimeCompilation |= Args.hasArg(OPT_debug_time_compilation);
if (const Arg *A = Args.getLastArg(OPT_stats_output_dir)) {
Opts.StatsOutputDir = A->getValue();
+ if (Args.getLastArg(OPT_trace_stats_events)) {
+ Opts.TraceStats = true;
+ }
}
if (const Arg *A = Args.getLastArg(OPT_validate_tbd_against_ir_EQ)) {
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index 0a0cfbb..3998777 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -1360,13 +1360,17 @@
StringRef OutFile = FEOpts.getSingleOutputFilename();
StringRef OutputType = llvm::sys::path::extension(OutFile);
std::string TripleName = LangOpts.Target.normalize();
+ auto &SM = Instance->getSourceMgr();
+ auto Trace = Invocation.getFrontendOptions().TraceStats;
StatsReporter = llvm::make_unique<UnifiedStatsReporter>("swift-frontend",
FEOpts.ModuleName,
InputName,
TripleName,
OutputType,
OptType,
- StatsOutputDir);
+ StatsOutputDir,
+ &SM,
+ Trace);
}
const DiagnosticOptions &diagOpts = Invocation.getDiagnosticOptions();
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 8365663..a9db914 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3937,6 +3937,10 @@
: TC(TC), IsFirstPass(IsFirstPass), IsSecondPass(IsSecondPass) {}
void visit(Decl *decl) {
+ UnifiedStatsReporter::FrontendStatsTracer Tracer;
+ if (TC.Context.Stats)
+ Tracer = TC.Context.Stats->getStatsTracer("type-checking",
+ decl->getSourceRange());
PrettyStackTraceDecl StackTrace("type-checking", decl);
DeclVisitor<DeclChecker>::visit(decl);