Skip to content

Commit 0245c83

Browse files
committed
[Stats] Add -stats-output-dir, wire UnifiedStatsReporter into place.
1 parent a30f173 commit 0245c83

File tree

10 files changed

+137
-13
lines changed

10 files changed

+137
-13
lines changed

include/swift/Driver/Compilation.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Driver/Util.h"
2222
#include "swift/Basic/ArrayRefView.h"
2323
#include "swift/Basic/LLVM.h"
24+
#include "swift/Basic/Statistic.h"
2425
#include "llvm/ADT/DenseSet.h"
2526
#include "llvm/ADT/StringRef.h"
2627
#include "llvm/Support/Chrono.h"
@@ -134,6 +135,9 @@ class Compilation {
134135
/// execute.
135136
bool ShowDriverTimeCompilation;
136137

138+
/// When non-null, record various high-level counters to this.
139+
std::unique_ptr<UnifiedStatsReporter> Stats;
140+
137141
/// When true, dumps information about why files are being scheduled to be
138142
/// rebuilt.
139143
bool ShowIncrementalBuildDecisions = false;
@@ -156,7 +160,8 @@ class Compilation {
156160
bool EnableIncrementalBuild = false,
157161
bool SkipTaskExecution = false,
158162
bool SaveTemps = false,
159-
bool ShowDriverTimeCompilation = false);
163+
bool ShowDriverTimeCompilation = false,
164+
std::unique_ptr<UnifiedStatsReporter> Stats = nullptr);
160165
~Compilation();
161166

162167
ArrayRefView<std::unique_ptr<const Job>, const Job *, Compilation::unwrap>

include/swift/Driver/DependencyGraph.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ namespace llvm {
3333

3434
namespace swift {
3535

36+
class UnifiedStatsReporter;
37+
3638
/// The non-templated implementation of DependencyGraph.
3739
///
3840
/// \see DependencyGraph
@@ -65,12 +67,14 @@ class DependencyGraphImpl {
6567
class MarkTracerImpl {
6668
class Entry;
6769
llvm::DenseMap<const void *, SmallVector<Entry, 4>> Table;
70+
UnifiedStatsReporter *Stats;
6871

6972
friend class DependencyGraphImpl;
7073
protected:
71-
MarkTracerImpl();
74+
explicit MarkTracerImpl(UnifiedStatsReporter *Stats);
7275
~MarkTracerImpl();
73-
76+
void countStatsForNodeMarking(const OptionSet<DependencyKind> &Kind,
77+
bool Cascading) const;
7478
void printPath(raw_ostream &out, const void *item,
7579
llvm::function_ref<void(const void *)> printItem) const;
7680
};
@@ -223,7 +227,8 @@ class DependencyGraph : public DependencyGraphImpl {
223227
/// This is intended to be a debugging aid.
224228
class MarkTracer : public MarkTracerImpl {
225229
public:
226-
MarkTracer() = default;
230+
explicit MarkTracer(UnifiedStatsReporter *Stats)
231+
: MarkTracerImpl(Stats) {}
227232

228233
/// Dump the path that led to \p node.
229234
void printPath(raw_ostream &out, T node,

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ class FrontendOptions {
192192
/// \sa swift::SharedTimer
193193
bool DebugTimeCompilation = false;
194194

195+
/// The path to which we should output statistics files.
196+
std::string StatsOutputDir;
197+
195198
/// Indicates whether function body parsing should be delayed
196199
/// until the end of all files.
197200
bool DelayedFunctionBodyParsing = false;

include/swift/Option/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ def save_temps : Flag<["-"], "save-temps">,
191191
def driver_time_compilation : Flag<["-"], "driver-time-compilation">,
192192
Flags<[NoInteractiveOption,DoesNotAffectIncrementalBuild]>,
193193
HelpText<"Prints the total time it took to execute all compilation tasks">;
194+
def stats_output_dir: Separate<["-"], "stats-output-dir">,
195+
Flags<[FrontendOption, HelpHidden]>,
196+
HelpText<"Directory to write unified compilation-statistics files to">;
194197

195198
def emit_dependencies : Flag<["-"], "emit-dependencies">,
196199
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,

lib/Driver/Compilation.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "swift/AST/DiagnosticEngine.h"
1616
#include "swift/AST/DiagnosticsDriver.h"
1717
#include "swift/Basic/Program.h"
18+
#include "swift/Basic/Statistic.h"
1819
#include "swift/Basic/TaskQueue.h"
1920
#include "swift/Basic/Version.h"
2021
#include "swift/Basic/type_traits.h"
@@ -92,7 +93,8 @@ Compilation::Compilation(DiagnosticEngine &Diags, OutputLevel Level,
9293
bool EnableIncrementalBuild,
9394
bool SkipTaskExecution,
9495
bool SaveTemps,
95-
bool ShowDriverTimeCompilation)
96+
bool ShowDriverTimeCompilation,
97+
std::unique_ptr<UnifiedStatsReporter> StatsReporter)
9698
: Diags(Diags), Level(Level), RawInputArgs(std::move(InputArgs)),
9799
TranslatedArgs(std::move(TranslatedArgs)),
98100
InputFilesWithTypes(std::move(InputsWithTypes)), ArgsHash(ArgsHash),
@@ -101,7 +103,8 @@ Compilation::Compilation(DiagnosticEngine &Diags, OutputLevel Level,
101103
SkipTaskExecution(SkipTaskExecution),
102104
EnableIncrementalBuild(EnableIncrementalBuild),
103105
SaveTemps(SaveTemps),
104-
ShowDriverTimeCompilation(ShowDriverTimeCompilation) {
106+
ShowDriverTimeCompilation(ShowDriverTimeCompilation),
107+
Stats(std::move(StatsReporter)) {
105108
};
106109

107110
static bool writeFilelistIfNecessary(const Job *job, DiagnosticEngine &diags);
@@ -229,7 +232,13 @@ namespace driver {
229232
<< ": " << LogJob(Cmd) << "\n";
230233
}
231234
FinishedCommands.insert(Cmd);
232-
235+
if (Comp.Stats) {
236+
auto &D = Comp.Stats->getDriverCounters();
237+
if (Skipped)
238+
D.NumDriverJobsSkipped++;
239+
else
240+
D.NumDriverJobsRun++;
241+
}
233242
auto BlockedIter = BlockingCommands.find(Cmd);
234243
if (BlockedIter != BlockingCommands.end()) {
235244
auto AllBlocked = std::move(BlockedIter->second);
@@ -466,12 +475,14 @@ namespace driver {
466475
}
467476

468477
public:
469-
PerformJobsState(Compilation &Comp) : Comp(Comp) {
478+
PerformJobsState(Compilation &Comp)
479+
: Comp(Comp),
480+
ActualIncrementalTracer(Comp.Stats.get()) {
470481
if (Comp.SkipTaskExecution)
471482
TQ.reset(new DummyTaskQueue(Comp.NumberOfParallelCommands));
472483
else
473484
TQ.reset(new TaskQueue(Comp.NumberOfParallelCommands));
474-
if (Comp.ShowIncrementalBuildDecisions)
485+
if (Comp.ShowIncrementalBuildDecisions || Comp.Stats)
475486
IncrementalTracer = &ActualIncrementalTracer;
476487
}
477488

lib/Driver/DependencyGraph.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "swift/Basic/Statistic.h"
1314
#include "swift/Driver/DependencyGraph.h"
1415
#include "swift/Demangling/Demangle.h"
1516
#include "llvm/ADT/SmallString.h"
@@ -41,7 +42,8 @@ class DependencyGraphImpl::MarkTracerImpl::Entry {
4142
DependencyMaskTy KindMask;
4243
};
4344

44-
DependencyGraphImpl::MarkTracerImpl::MarkTracerImpl() = default;
45+
DependencyGraphImpl::MarkTracerImpl::MarkTracerImpl(UnifiedStatsReporter *Stats)
46+
: Stats(Stats) {}
4547
DependencyGraphImpl::MarkTracerImpl::~MarkTracerImpl() = default;
4648

4749
using LoadResult = DependencyGraphImpl::LoadResult;
@@ -350,6 +352,7 @@ DependencyGraphImpl::markTransitive(SmallVectorImpl<const void *> &visited,
350352

351353
MutableArrayRef<MarkTracerImpl::Entry> newReason;
352354
if (tracer) {
355+
tracer->countStatsForNodeMarking(intersectingKinds, isCascading);
353356
newReason = {scratchAlloc.Allocate(reason.size()+1), reason.size()+1};
354357
std::uninitialized_copy(reason.begin(), reason.end(),
355358
newReason.begin());
@@ -393,6 +396,38 @@ DependencyGraphImpl::markTransitive(SmallVectorImpl<const void *> &visited,
393396
}
394397
}
395398

399+
void DependencyGraphImpl::MarkTracerImpl::countStatsForNodeMarking(
400+
const OptionSet<DependencyKind> &Kind, bool IsCascading) const {
401+
402+
if (!Stats)
403+
return;
404+
405+
auto &D = Stats->getDriverCounters();
406+
if (IsCascading) {
407+
if (Kind & DependencyKind::TopLevelName)
408+
D.DriverDepCascadingTopLevel++;
409+
if (Kind & DependencyKind::DynamicLookupName)
410+
D.DriverDepCascadingDynamic++;
411+
if (Kind & DependencyKind::NominalType)
412+
D.DriverDepCascadingNominal++;
413+
if (Kind & DependencyKind::NominalTypeMember)
414+
D.DriverDepCascadingMember++;
415+
if (Kind & DependencyKind::NominalTypeMember)
416+
D.DriverDepCascadingExternal++;
417+
} else {
418+
if (Kind & DependencyKind::TopLevelName)
419+
D.DriverDepTopLevel++;
420+
if (Kind & DependencyKind::DynamicLookupName)
421+
D.DriverDepDynamic++;
422+
if (Kind & DependencyKind::NominalType)
423+
D.DriverDepNominal++;
424+
if (Kind & DependencyKind::NominalTypeMember)
425+
D.DriverDepMember++;
426+
if (Kind & DependencyKind::NominalTypeMember)
427+
D.DriverDepExternal++;
428+
}
429+
}
430+
396431
void DependencyGraphImpl::MarkTracerImpl::printPath(
397432
raw_ostream &out,
398433
const void *item,

lib/Driver/Driver.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/Basic/TaskQueue.h"
2626
#include "swift/Basic/Version.h"
2727
#include "swift/Basic/Range.h"
28+
#include "swift/Basic/Statistic.h"
2829
#include "swift/Driver/Action.h"
2930
#include "swift/Driver/Compilation.h"
3031
#include "swift/Driver/Job.h"
@@ -554,6 +555,14 @@ std::unique_ptr<Compilation> Driver::buildCompilation(
554555
if (Diags.hadAnyError())
555556
return nullptr;
556557

558+
std::unique_ptr<UnifiedStatsReporter> StatsReporter;
559+
if (const Arg *A =
560+
ArgList->getLastArgNoClaim(options::OPT_stats_output_dir)) {
561+
StatsReporter = llvm::make_unique<UnifiedStatsReporter>("swift-driver",
562+
OI.ModuleName,
563+
A->getValue());
564+
}
565+
557566
assert(OI.CompilerOutputType != types::ID::TY_INVALID &&
558567
"buildOutputInfo() must set a valid output type!");
559568

@@ -655,7 +664,8 @@ std::unique_ptr<Compilation> Driver::buildCompilation(
655664
Incremental,
656665
DriverSkipExecution,
657666
SaveTemps,
658-
ShowDriverTimeCompilation));
667+
ShowDriverTimeCompilation,
668+
std::move(StatsReporter)));
659669

660670
buildJobs(Actions, OI, OFM.get(), *TC, *C);
661671

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ static void addCommonFrontendArgs(const ToolChain &TC,
147147
inputArgs.AddLastArg(arguments, options::OPT_sanitize_coverage_EQ);
148148
inputArgs.AddLastArg(arguments, options::OPT_swift_version);
149149
inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ);
150+
inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
150151

151152
// Pass on any build config options
152153
inputArgs.AddAllArgs(arguments, options::OPT_D);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
187187
Opts.DebugTimeExpressionTypeChecking |=
188188
Args.hasArg(OPT_debug_time_expression_type_checking);
189189
Opts.DebugTimeCompilation |= Args.hasArg(OPT_debug_time_compilation);
190+
if (const Arg *A = Args.getLastArg(OPT_stats_output_dir)) {
191+
Opts.StatsOutputDir = A->getValue();
192+
}
190193

191194
Opts.ValidateTBDAgainstIR |= Args.hasArg(OPT_validate_tbd_against_ir);
192195

lib/FrontendTool/FrontendTool.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "swift/Basic/FileSystem.h"
3939
#include "swift/Basic/LLVMContext.h"
4040
#include "swift/Basic/SourceManager.h"
41+
#include "swift/Basic/Statistic.h"
4142
#include "swift/Basic/Timer.h"
4243
#include "swift/Frontend/DiagnosticVerifier.h"
4344
#include "swift/Frontend/Frontend.h"
@@ -325,6 +326,28 @@ static void debugFailWithCrash() {
325326
LLVM_BUILTIN_TRAP;
326327
}
327328

329+
static void countStatsPostSILGen(UnifiedStatsReporter &Stats,
330+
const SILModule& Module) {
331+
auto &C = Stats.getFrontendCounters();
332+
// FIXME: calculate these in constant time, via the dense maps.
333+
C.NumSILGenFunctions = Module.getFunctionList().size();
334+
C.NumSILGenVtables = Module.getVTableList().size();
335+
C.NumSILGenWitnessTables = Module.getWitnessTableList().size();
336+
C.NumSILGenDefaultWitnessTables = Module.getDefaultWitnessTableList().size();
337+
C.NumSILGenGlobalVariables = Module.getSILGlobalList().size();
338+
}
339+
340+
static void countStatsPostSILOpt(UnifiedStatsReporter &Stats,
341+
const SILModule& Module) {
342+
auto &C = Stats.getFrontendCounters();
343+
// FIXME: calculate these in constant time, via the dense maps.
344+
C.NumSILOptFunctions = Module.getFunctionList().size();
345+
C.NumSILOptVtables = Module.getVTableList().size();
346+
C.NumSILOptWitnessTables = Module.getWitnessTableList().size();
347+
C.NumSILOptDefaultWitnessTables = Module.getDefaultWitnessTableList().size();
348+
C.NumSILOptGlobalVariables = Module.getSILGlobalList().size();
349+
}
350+
328351
/// Performs the compile requested by the user.
329352
/// \param Instance Will be reset after performIRGeneration when the verifier
330353
/// mode is NoVerify and there were no errors.
@@ -333,7 +356,8 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
333356
CompilerInvocation &Invocation,
334357
ArrayRef<const char *> Args,
335358
int &ReturnValue,
336-
FrontendObserver *observer) {
359+
FrontendObserver *observer,
360+
UnifiedStatsReporter *Stats) {
337361
FrontendOptions opts = Invocation.getFrontendOptions();
338362
FrontendOptions::ActionType Action = opts.RequestedAction;
339363

@@ -551,6 +575,9 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
551575
if (observer) {
552576
observer->performedSILGeneration(*SM);
553577
}
578+
if (Stats) {
579+
countStatsPostSILGen(*Stats, *SM);
580+
}
554581

555582
// We've been told to emit SIL after SILGen, so write it now.
556583
if (Action == FrontendOptions::EmitSILGen) {
@@ -624,6 +651,9 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
624651
if (observer) {
625652
observer->performedSILOptimization(*SM);
626653
}
654+
if (Stats) {
655+
countStatsPostSILOpt(*Stats, *SM);
656+
}
627657

628658
{
629659
SharedTimer timer("SIL verification, post-optimization");
@@ -973,6 +1003,23 @@ int swift::performFrontend(ArrayRef<const char *> Args,
9731003
llvm::EnableStatistics();
9741004
}
9751005

1006+
const std::string &StatsOutputDir =
1007+
Invocation.getFrontendOptions().StatsOutputDir;
1008+
std::unique_ptr<UnifiedStatsReporter> StatsReporter;
1009+
if (!StatsOutputDir.empty()) {
1010+
auto &opts = Invocation.getFrontendOptions();
1011+
std::string TargetName = opts.ModuleName;
1012+
if (opts.PrimaryInput.hasValue() &&
1013+
opts.PrimaryInput.getValue().isFilename()) {
1014+
auto Index = opts.PrimaryInput.getValue().Index;
1015+
TargetName += ".";
1016+
TargetName += llvm::sys::path::filename(opts.InputFilenames[Index]);
1017+
}
1018+
StatsReporter = llvm::make_unique<UnifiedStatsReporter>("swift-frontend",
1019+
TargetName,
1020+
StatsOutputDir);
1021+
}
1022+
9761023
const DiagnosticOptions &diagOpts = Invocation.getDiagnosticOptions();
9771024
if (diagOpts.VerifyMode != DiagnosticOptions::NoVerify) {
9781025
enableDiagnosticVerifier(Instance->getSourceMgr());
@@ -995,7 +1042,8 @@ int swift::performFrontend(ArrayRef<const char *> Args,
9951042

9961043
int ReturnValue = 0;
9971044
bool HadError =
998-
performCompile(Instance, Invocation, Args, ReturnValue, observer);
1045+
performCompile(Instance, Invocation, Args, ReturnValue, observer,
1046+
StatsReporter.get());
9991047

10001048
if (!HadError) {
10011049
Mangle::printManglingStats();

0 commit comments

Comments
 (0)