Merge pull request #12075 from apple/revert-12062-make-fewer-gsbs
Revert "Create fewer generic signature builders"
diff --git a/benchmark/single-source/AnyHashableWithAClass.swift b/benchmark/single-source/AnyHashableWithAClass.swift
index b46f635..e2b5a76 100644
--- a/benchmark/single-source/AnyHashableWithAClass.swift
+++ b/benchmark/single-source/AnyHashableWithAClass.swift
@@ -14,6 +14,20 @@
// upcast the instance to the type that introduces the Hashable
// conformance.
+import TestsUtils
+
+// 23% _swift_dynamicCast
+// 23% _swift_release_
+// 18% _swift_stdlib_makeAnyHashableUsingDefaultRepresentation
+// 11% _swift_stdlib_makeAnyHashableUpcastingToHashableBaseType
+// 16% _swift_retain_[n]
+// 5% swift_conformsToProtocol
+public var AnyHashableWithAClass = BenchmarkInfo(
+ name: "AnyHashableWithAClass",
+ runFunction: run_AnyHashableWithAClass,
+ tags: [.abstraction, .runtime, .cpubench]
+)
+
class TestHashableBase : Hashable {
var value: Int
init(_ value: Int) {
diff --git a/benchmark/single-source/Exclusivity.swift b/benchmark/single-source/Exclusivity.swift
index 368953a..e75dca9 100644
--- a/benchmark/single-source/Exclusivity.swift
+++ b/benchmark/single-source/Exclusivity.swift
@@ -17,6 +17,36 @@
import TestsUtils
+// At -Onone
+// 25% swift_beginAccess
+// 15% tlv_get_addr
+// 15% swift_endAccess
+public var ExclusivityGlobal = BenchmarkInfo(
+ name: "ExclusivityGlobal",
+ runFunction: run_accessGlobal,
+ tags: [.runtime, .cpubench]
+)
+// At -Onone
+// 23% swift_retain
+// 22% swift_release
+// 9% swift_beginAccess
+// 3% swift_endAccess
+public var ExclusivityInMatSet = BenchmarkInfo(
+ name: "ExclusivityInMatSet",
+ runFunction: run_accessInMatSet,
+ tags: [.runtime, .cpubench]
+)
+// At -Onone
+// 25% swift_release
+// 23% swift_retain
+// 16% swift_beginAccess
+// 8% swift_endAccess
+public var ExclusivityIndependent = BenchmarkInfo(
+ name: "ExclusivityIndependent",
+ runFunction: run_accessIndependent,
+ tags: [.runtime, .cpubench]
+)
+
// Initially these benchmarks only measure access checks at -Onone. In
// the future, access checks will also be emitted at -O.
diff --git a/benchmark/single-source/LinkedList.swift b/benchmark/single-source/LinkedList.swift
index 2bc7811..2cfbfa6 100644
--- a/benchmark/single-source/LinkedList.swift
+++ b/benchmark/single-source/LinkedList.swift
@@ -14,6 +14,14 @@
// utils/benchmark, with modifications for performance measuring.
import TestsUtils
+// 47% _swift_retain
+// 43% _swift_release
+public var LinkedList = BenchmarkInfo(
+ name: "LinkedList",
+ runFunction: run_LinkedList,
+ tags: [.runtime, .cpubench, .refcount]
+)
+
final class Node {
var next: Node?
var data: Int
diff --git a/benchmark/single-source/PolymorphicCalls.swift b/benchmark/single-source/PolymorphicCalls.swift
index 1ecb15d..64aedae 100644
--- a/benchmark/single-source/PolymorphicCalls.swift
+++ b/benchmark/single-source/PolymorphicCalls.swift
@@ -22,6 +22,12 @@
import TestsUtils
+public var PolymorphicCalls = BenchmarkInfo(
+ name: "PolymorphicCalls",
+ runFunction: run_PolymorphicCalls,
+ tags: [.abstraction, .cpubench]
+)
+
public class A {
let b: B
init(b:B) {
diff --git a/benchmark/single-source/SevenBoom.swift b/benchmark/single-source/SevenBoom.swift
index 99f1fd7..be59afe 100644
--- a/benchmark/single-source/SevenBoom.swift
+++ b/benchmark/single-source/SevenBoom.swift
@@ -13,6 +13,21 @@
import TestsUtils
import Foundation
+// 15% _swift_allocObject (String.bridgeToObjectiveC)
+// 14% [NSError dealloc]
+// 14% objc_allocWithZone
+// 10% _swift_allocObject
+// 11% _swift_release_dealloc
+// 8% objc_release
+// 7% objc_msgSend
+// 5% _swift_release_
+// 2% _swift_retain_
+public var SevenBoom = BenchmarkInfo(
+ name: "SevenBoom",
+ runFunction: run_SevenBoom,
+ tags: [.runtime, .exceptions, .bridging, .cpubench]
+)
+
@inline(never)
func filter_seven(_ input : Int) throws {
guard case 7 = input else {
diff --git a/benchmark/utils/TestsUtils.swift b/benchmark/utils/TestsUtils.swift
index dcd9c0a..fd9ab99 100644
--- a/benchmark/utils/TestsUtils.swift
+++ b/benchmark/utils/TestsUtils.swift
@@ -17,54 +17,54 @@
#endif
public enum BenchmarkCategories : CustomStringConvertible {
-// Validation "micro" benchmarks test a specific operation or critical path that
-// we know is important to measure.
-case validation
-// subsystems to validate and their subcategories.
-case api, Array, String, Dictionary, Codable, Set
-case sdk
-case runtime, refcount, metadata
-// Other general areas of compiled code validation.
-case abstraction, safetychecks, exceptions, bridging, concurrency
-
-// Algorithms are "micro" that test some well-known algorithm in isolation:
-// sorting, searching, hashing, fibonaci, crypto, etc.
-case algorithm
-
-// Miniapplications are contrived to mimic some subset of application behavior
-// in a way that can be easily measured. They are larger than micro-benchmarks,
-// combining multiple APIs, data structures, or algorithms. This includes small
-// standardized benchmarks, pieces of real applications that have been extracted
-// into a benchmark, important functionality like JSON parsing, etc.
-case miniapplication
-
-// Regression benchmarks is a catch-all for less important "micro"
-// benchmarks. This could be a random piece of code that was attached to a bug
-// report. We want to make sure the optimizer as a whole continues to handle
-// this case, but don't know how applicable it is to general Swift performance
-// relative to the other micro-benchmarks. In particular, these aren't weighted
-// as highly as "validation" benchmarks and likely won't be the subject of
-// future investigation unless they significantly regress.
-case regression
-
-// Most benchmarks are assumed to be "stable" and will be regularly tracked at
-// each commit. A handful may be marked unstable if continually tracking them is
-// counterproductive.
-case unstable
-
-// CPU benchmarks represent instrinsic Swift performance. They are useful for
-// measuring a fully baked Swift implementation across different platforms and
-// hardware. The benchmark should also be reasonably applicable to real Swift
-// code--it should exercise a known performance critical area. Typically these
-// will be drawn from the validation benchmarks once the language and standard
-// library implementation of the benchmark meets a reasonable efficiency
-// baseline. A benchmark should only be tagged "cpubench" after a full
-// performance investigation of the benchmark has been completed to determine
-// that it is a good representation of future Swift performance. Benchmarks
-// should not be tagged if they make use of an API that we plan on
-// reimplementing or call into code paths that have known opportunities for
-// significant optimization.
-case cpubench
+ // Validation "micro" benchmarks test a specific operation or critical path that
+ // we know is important to measure.
+ case validation
+ // subsystems to validate and their subcategories.
+ case api, Array, String, Dictionary, Codable, Set
+ case sdk
+ case runtime, refcount, metadata
+ // Other general areas of compiled code validation.
+ case abstraction, safetychecks, exceptions, bridging, concurrency
+
+ // Algorithms are "micro" that test some well-known algorithm in isolation:
+ // sorting, searching, hashing, fibonaci, crypto, etc.
+ case algorithm
+
+ // Miniapplications are contrived to mimic some subset of application behavior
+ // in a way that can be easily measured. They are larger than micro-benchmarks,
+ // combining multiple APIs, data structures, or algorithms. This includes small
+ // standardized benchmarks, pieces of real applications that have been extracted
+ // into a benchmark, important functionality like JSON parsing, etc.
+ case miniapplication
+
+ // Regression benchmarks is a catch-all for less important "micro"
+ // benchmarks. This could be a random piece of code that was attached to a bug
+ // report. We want to make sure the optimizer as a whole continues to handle
+ // this case, but don't know how applicable it is to general Swift performance
+ // relative to the other micro-benchmarks. In particular, these aren't weighted
+ // as highly as "validation" benchmarks and likely won't be the subject of
+ // future investigation unless they significantly regress.
+ case regression
+
+ // Most benchmarks are assumed to be "stable" and will be regularly tracked at
+ // each commit. A handful may be marked unstable if continually tracking them is
+ // counterproductive.
+ case unstable
+
+ // CPU benchmarks represent instrinsic Swift performance. They are useful for
+ // measuring a fully baked Swift implementation across different platforms and
+ // hardware. The benchmark should also be reasonably applicable to real Swift
+ // code--it should exercise a known performance critical area. Typically these
+ // will be drawn from the validation benchmarks once the language and standard
+ // library implementation of the benchmark meets a reasonable efficiency
+ // baseline. A benchmark should only be tagged "cpubench" after a full
+ // performance investigation of the benchmark has been completed to determine
+ // that it is a good representation of future Swift performance. Benchmarks
+ // should not be tagged if they make use of an API that we plan on
+ // reimplementing or call into code paths that have known opportunities for
+ // significant optimization.
+ case cpubench
public var description : String {
switch self {
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index c9bf9c2..88b7326 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -125,6 +125,21 @@
import XorLoop
@inline(__always)
+private func registerBenchmark(_ bench: BenchmarkInfo) {
+ registeredBenchmarks.append(bench)
+}
+
+registerBenchmark(AnyHashableWithAClass)
+registerBenchmark(ArraySetElement)
+registerBenchmark(ExclusivityGlobal)
+registerBenchmark(ExclusivityInMatSet)
+registerBenchmark(ExclusivityIndependent)
+registerBenchmark(LinkedList)
+registerBenchmark(ObjectAllocation)
+registerBenchmark(PolymorphicCalls)
+registerBenchmark(SevenBoom)
+
+@inline(__always)
private func addTo(
_ testSuite: inout [String : ((Int) -> (), [BenchmarkCategories])],
_ name: String,
@@ -134,14 +149,6 @@
testSuite[name] = (function, tags)
}
-@inline(__always)
-private func registerBenchmark(_ bench: BenchmarkInfo) {
- registeredBenchmarks.append(bench)
-}
-
-registerBenchmark(ArraySetElement)
-registerBenchmark(ObjectAllocation)
-
// The main test suite: precommit tests
addTo(&precommitTests, "AngryPhonebook", run_AngryPhonebook, [.validation, .api, .String])
addTo(&precommitTests, "AnyHashableWithAClass", run_AnyHashableWithAClass, [.validation, .abstraction, .runtime])
diff --git a/docs/CompilerPerformance.md b/docs/CompilerPerformance.md
index d76259c..f12ddc2 100644
--- a/docs/CompilerPerformance.md
+++ b/docs/CompilerPerformance.md
@@ -780,7 +780,7 @@
How the test-script determines the presence of a regression is up to you: a
typical approach is to measure against a baseline (eg. using
`utils/process-stats-dir.py --compare-to-csv-baseline`, if your regression range
-covers compilers that all support `--output-stats-dir`). Alternatively, just
+covers compilers that all support `-stats-output-dir`). Alternatively, just
measure raw time or instruction counts. An example script that uses the
`perf`-based `count_instructions` shell function (see the section on `perf`) to
judge whether a revision contains a bug looks something like this:
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/include/swift/SIL/Dominance.h b/include/swift/SIL/Dominance.h
index 16ea2ca..79e20d8 100644
--- a/include/swift/SIL/Dominance.h
+++ b/include/swift/SIL/Dominance.h
@@ -25,6 +25,18 @@
extern template class llvm::DominatorTreeBase<swift::SILBasicBlock, true>;
extern template class llvm::DomTreeNodeBase<swift::SILBasicBlock>;
+namespace llvm {
+namespace DomTreeBuilder {
+using SILDomTree = llvm::DomTreeBase<swift::SILBasicBlock>;
+using SILPostDomTree = llvm::PostDomTreeBase<swift::SILBasicBlock>;
+
+extern template void Calculate<SILDomTree, swift::SILFunction>(
+ SILDomTree &DT, swift::SILFunction &F);
+extern template void Calculate<SILPostDomTree, swift::SILFunction>(
+ SILPostDomTree &DT, swift::SILFunction &F);
+} // namespace DomTreeBuilder
+} // namespace llvm
+
namespace swift {
using DominatorTreeBase = llvm::DominatorTreeBase<swift::SILBasicBlock, false>;
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/SIL/Dominance.cpp b/lib/SIL/Dominance.cpp
index 2cce9fc..09b406d 100644
--- a/lib/SIL/Dominance.cpp
+++ b/lib/SIL/Dominance.cpp
@@ -14,7 +14,6 @@
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/Dominance.h"
-#include "llvm/Support/GenericDomTree.h"
#include "llvm/Support/GenericDomTreeConstruction.h"
using namespace swift;
@@ -22,14 +21,15 @@
template class llvm::DominatorTreeBase<SILBasicBlock, false>;
template class llvm::DominatorTreeBase<SILBasicBlock, true>;
template class llvm::DomTreeNodeBase<SILBasicBlock>;
-using SILDomTree = llvm::DomTreeBase<SILBasicBlock>;
-using SILPostDomTree = llvm::PostDomTreeBase<SILBasicBlock>;
-template void
-llvm::DomTreeBuilder::Calculate<SILDomTree, swift::SILFunction>(
+
+namespace llvm {
+namespace DomTreeBuilder {
+template void Calculate<SILDomTree, swift::SILFunction>(
SILDomTree &DT, swift::SILFunction &F);
-template void
-llvm::DomTreeBuilder::Calculate<SILPostDomTree, swift::SILFunction>(
+template void Calculate<SILPostDomTree, swift::SILFunction>(
SILPostDomTree &DT, swift::SILFunction &F);
+} // namespace DomTreeBuilder
+} // namespace llvm
/// Compute the immediate-dominators map.
DominanceInfo::DominanceInfo(SILFunction *F)
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 9f46093..fcfc379 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3936,6 +3936,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);