Merge pull request #76662 from slavapestov/fine-grained-timers-flag

Add -fine-grained-timers flag
This commit is contained in:
Slava Pestov
2024-09-25 08:26:08 -04:00
committed by GitHub
17 changed files with 264 additions and 243 deletions

View File

@@ -167,6 +167,10 @@ private:
std::unique_ptr<StatsProfilers> EventProfilers;
std::unique_ptr<StatsProfilers> EntityProfilers;
/// Whether fine-grained timers are enabled. In practice, this means request
/// evaluator requests. This will have a runtime performance impact.
bool FineGrainedTimers;
/// Whether we are currently flushing statistics and should not therefore
/// record any additional stats until we've finished.
bool IsFlushingTracesAndProfiles;
@@ -179,6 +183,7 @@ private:
StringRef Directory,
SourceManager *SM,
clang::SourceManager *CSM,
bool FineGrainedTimers,
bool TraceEvents,
bool ProfileEvents,
bool ProfileEntities);
@@ -190,13 +195,16 @@ public:
StringRef OutputType,
StringRef OptType,
StringRef Directory,
SourceManager *SM=nullptr,
clang::SourceManager *CSM=nullptr,
bool TraceEvents=false,
bool ProfileEvents=false,
bool ProfileEntities=false);
SourceManager *SM,
clang::SourceManager *CSM,
bool FineGrainedTimers,
bool TraceEvents,
bool ProfileEvents,
bool ProfileEntities);
~UnifiedStatsReporter();
bool fineGrainedTimers() const { return FineGrainedTimers; }
AlwaysOnDriverCounters &getDriverCounters();
AlwaysOnFrontendCounters &getFrontendCounters();
void flushTracesAndProfiles();

View File

@@ -228,6 +228,10 @@ public:
/// The path to which we should output statistics files.
std::string StatsOutputDir;
/// Whether to enable timers tracking individual requests. This adds some
/// runtime overhead.
bool FineGrainedTimers = false;
/// Trace changes to stats to files in StatsOutputDir.
bool TraceStats = false;

View File

@@ -361,6 +361,9 @@ def driver_time_compilation : Flag<["-"], "driver-time-compilation">,
def stats_output_dir: Separate<["-"], "stats-output-dir">,
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
HelpText<"Directory to write unified compilation-statistics files to">;
def fine_grained_timers: Flag<["-"], "fine-grained-timers">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Enable per-request timers">;
def trace_stats_events: Flag<["-"], "trace-stats-events">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Trace changes to stats in -stats-output-dir">;

View File

@@ -928,12 +928,16 @@ swift::detail::ImportPathBuilder_getIdentifierImpl(ASTContext &ctx,
/// Set a new stats reporter.
void ASTContext::setStatsReporter(UnifiedStatsReporter *stats) {
if (stats) {
stats->getFrontendCounters().NumASTBytesAllocated =
getAllocator().getBytesAllocated();
}
evaluator.setStatsReporter(stats);
if (!stats)
return;
Stats = stats;
stats->getFrontendCounters().NumASTBytesAllocated =
getAllocator().getBytesAllocated();
if (stats->fineGrainedTimers())
evaluator.setStatsReporter(stats);
}
/// getIdentifier - Return the uniqued and AST-Context-owned version of the

View File

@@ -240,9 +240,6 @@ void UnqualifiedLookupFactory::performUnqualifiedLookup() {
auto localCounter = lookupCounter;
(void)localCounter; // for debugging
#endif
FrontendStatsTracer StatsTracer(Ctx.Stats,
"performUnqualifiedLookup",
DC->getParentSourceFile());
if (options.contains(UnqualifiedLookupFlags::ModuleLookup)) {
lookForAModuleWithTheGivenName(DC->getModuleScopeContext());

View File

@@ -319,6 +319,7 @@ UnifiedStatsReporter::UnifiedStatsReporter(StringRef ProgramName,
StringRef Directory,
SourceManager *SM,
clang::SourceManager *CSM,
bool FineGrainedTimers,
bool TraceEvents,
bool ProfileEvents,
bool ProfileEntities)
@@ -329,7 +330,7 @@ UnifiedStatsReporter::UnifiedStatsReporter(StringRef ProgramName,
OutputType,
OptType),
Directory,
SM, CSM,
SM, CSM, FineGrainedTimers,
TraceEvents, ProfileEvents, ProfileEntities)
{
}
@@ -339,6 +340,7 @@ UnifiedStatsReporter::UnifiedStatsReporter(StringRef ProgramName,
StringRef Directory,
SourceManager *SM,
clang::SourceManager *CSM,
bool FineGrainedTimers,
bool TraceEvents,
bool ProfileEvents,
bool ProfileEntities)
@@ -355,7 +357,8 @@ UnifiedStatsReporter::UnifiedStatsReporter(StringRef ProgramName,
SourceMgr(SM),
ClangSourceMgr(CSM),
RecursiveTimers(std::make_unique<RecursionSafeTimers>()),
IsFlushingTracesAndProfiles(false)
IsFlushingTracesAndProfiles(false),
FineGrainedTimers(FineGrainedTimers)
{
path::append(StatsFilename, makeStatsFileName(ProgramName, AuxName));
path::append(TraceFilename, makeTraceFileName(ProgramName, AuxName));
@@ -453,20 +456,22 @@ UnifiedStatsReporter::printAlwaysOnStatsAndTimers(raw_ostream &OS) {
const char *delim = "";
if (FrontendCounters) {
auto &C = getFrontendCounters();
#define FRONTEND_STATISTIC(TY, NAME) \
do { \
OS << delim << "\t\"" #TY "." #NAME "\": " << C.NAME; \
delim = ",\n"; \
#define FRONTEND_STATISTIC(TY, NAME) \
do { \
if (C.NAME) \
OS << delim << "\t\"" #TY "." #NAME "\": " << C.NAME; \
delim = ",\n"; \
} while (0);
#include "swift/Basic/Statistics.def"
#undef FRONTEND_STATISTIC
}
if (DriverCounters) {
auto &C = getDriverCounters();
#define DRIVER_STATISTIC(NAME) \
do { \
OS << delim << "\t\"Driver." #NAME "\": " << C.NAME; \
delim = ",\n"; \
#define DRIVER_STATISTIC(NAME) \
do { \
if (C.NAME) \
OS << delim << "\t\"Driver." #NAME "\": " << C.NAME; \
delim = ",\n"; \
} while (0);
#include "swift/Basic/Statistics.def"
#undef DRIVER_STATISTIC

View File

@@ -516,7 +516,13 @@ createStatsReporter(const llvm::opt::InputArgList *ArgList,
DefaultTargetTriple,
OutputType,
OptType,
A->getValue());
A->getValue(),
nullptr,
nullptr,
false,
false,
false,
false);
}
static bool

View File

@@ -416,6 +416,9 @@ void ArgsToFrontendOptionsConverter::computeDebugTimeOptions() {
using namespace options;
if (const Arg *A = Args.getLastArg(OPT_stats_output_dir)) {
Opts.StatsOutputDir = A->getValue();
if (Args.getLastArg(OPT_fine_grained_timers)) {
Opts.FineGrainedTimers = true;
}
if (Args.getLastArg(OPT_trace_stats_events)) {
Opts.TraceStats = true;
}

View File

@@ -381,6 +381,7 @@ void CompilerInstance::setupStatsReporter() {
StatsOutputDir,
&getSourceMgr(),
getClangSourceManager(getASTContext()),
Invoke.getFrontendOptions().FineGrainedTimers,
Invoke.getFrontendOptions().TraceStats,
Invoke.getFrontendOptions().ProfileEvents,
Invoke.getFrontendOptions().ProfileEntities);

View File

@@ -1450,123 +1450,127 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
IGM->addLinkLibraries();
IGMcreated = true;
}
if (!IGMcreated) {
// TODO: Check this already at argument parsing.
Ctx.Diags.diagnose(SourceLoc(), diag::no_input_files_for_mt);
return;
}
// Emit the module contents.
irgen.emitGlobalTopLevel(desc.getLinkerDirectives());
{
FrontendStatsTracer tracer(Ctx.Stats, "IRGen");
for (auto *File : M->getFiles()) {
if (auto *SF = dyn_cast<SourceFile>(File)) {
{
CurrentIGMPtr IGM = irgen.getGenModule(SF);
IGM->emitSourceFile(*SF);
}
if (auto *synthSFU = File->getSynthesizedFile()) {
CurrentIGMPtr IGM = irgen.getGenModule(synthSFU);
IGM->emitSynthesizedFileUnit(*synthSFU);
// Emit the module contents.
irgen.emitGlobalTopLevel(desc.getLinkerDirectives());
for (auto *File : M->getFiles()) {
if (auto *SF = dyn_cast<SourceFile>(File)) {
{
CurrentIGMPtr IGM = irgen.getGenModule(SF);
IGM->emitSourceFile(*SF);
}
if (auto *synthSFU = File->getSynthesizedFile()) {
CurrentIGMPtr IGM = irgen.getGenModule(synthSFU);
IGM->emitSynthesizedFileUnit(*synthSFU);
}
}
}
}
// Okay, emit any definitions that we suddenly need.
irgen.emitLazyDefinitions();
irgen.emitSwiftProtocols();
// Okay, emit any definitions that we suddenly need.
irgen.emitLazyDefinitions();
irgen.emitDynamicReplacements();
irgen.emitSwiftProtocols();
irgen.emitProtocolConformances();
irgen.emitDynamicReplacements();
irgen.emitTypeMetadataRecords();
irgen.emitProtocolConformances();
irgen.emitAccessibleFunctions();
irgen.emitTypeMetadataRecords();
irgen.emitReflectionMetadataVersion();
irgen.emitAccessibleFunctions();
irgen.emitEagerClassInitialization();
irgen.emitObjCActorsNeedingSuperclassSwizzle();
irgen.emitReflectionMetadataVersion();
// Emit reflection metadata for builtin and imported types.
irgen.emitBuiltinReflectionMetadata();
irgen.emitEagerClassInitialization();
irgen.emitObjCActorsNeedingSuperclassSwizzle();
// Emit coverage mapping info. This needs to happen after we've emitted
// any lazy definitions, as we need to know whether or not we emitted a
// profiler increment for a given coverage map.
irgen.emitCoverageMapping();
// Emit reflection metadata for builtin and imported types.
irgen.emitBuiltinReflectionMetadata();
IRGenModule *PrimaryGM = irgen.getPrimaryIGM();
// Emit coverage mapping info. This needs to happen after we've emitted
// any lazy definitions, as we need to know whether or not we emitted a
// profiler increment for a given coverage map.
irgen.emitCoverageMapping();
// Emit symbols for eliminated dead methods.
PrimaryGM->emitVTableStubs();
IRGenModule *PrimaryGM = irgen.getPrimaryIGM();
// Emit symbols for eliminated dead methods.
PrimaryGM->emitVTableStubs();
// Verify type layout if we were asked to.
if (!Opts.VerifyTypeLayoutNames.empty())
PrimaryGM->emitTypeVerifier();
// Verify type layout if we were asked to.
if (!Opts.VerifyTypeLayoutNames.empty())
PrimaryGM->emitTypeVerifier();
std::for_each(Opts.LinkLibraries.begin(), Opts.LinkLibraries.end(),
[&](LinkLibrary linkLib) {
PrimaryGM->addLinkLibrary(linkLib);
});
llvm::DenseSet<StringRef> referencedGlobals;
std::for_each(Opts.LinkLibraries.begin(), Opts.LinkLibraries.end(),
[&](LinkLibrary linkLib) {
PrimaryGM->addLinkLibrary(linkLib);
});
for (auto it = irgen.begin(); it != irgen.end(); ++it) {
IRGenModule *IGM = it->second;
llvm::Module *M = IGM->getModule();
auto collectReference = [&](llvm::GlobalValue &G) {
if (G.isDeclaration()
&& (G.getLinkage() == GlobalValue::LinkOnceODRLinkage ||
G.getLinkage() == GlobalValue::ExternalLinkage)) {
referencedGlobals.insert(G.getName());
G.setLinkage(GlobalValue::ExternalLinkage);
llvm::DenseSet<StringRef> referencedGlobals;
for (auto it = irgen.begin(); it != irgen.end(); ++it) {
IRGenModule *IGM = it->second;
llvm::Module *M = IGM->getModule();
auto collectReference = [&](llvm::GlobalValue &G) {
if (G.isDeclaration()
&& (G.getLinkage() == GlobalValue::LinkOnceODRLinkage ||
G.getLinkage() == GlobalValue::ExternalLinkage)) {
referencedGlobals.insert(G.getName());
G.setLinkage(GlobalValue::ExternalLinkage);
}
};
for (llvm::GlobalVariable &G : M->globals()) {
collectReference(G);
}
};
for (llvm::GlobalVariable &G : M->globals()) {
collectReference(G);
}
for (llvm::Function &F : M->getFunctionList()) {
collectReference(F);
}
for (llvm::GlobalAlias &A : M->aliases()) {
collectReference(A);
}
}
for (auto it = irgen.begin(); it != irgen.end(); ++it) {
IRGenModule *IGM = it->second;
llvm::Module *M = IGM->getModule();
// Update the linkage of shared functions/globals.
// If a shared function/global is referenced from another file it must have
// weak instead of linkonce linkage. Otherwise LLVM would remove the
// definition (if it's not referenced in the same file).
auto updateLinkage = [&](llvm::GlobalValue &G) {
if (!G.isDeclaration()
&& G.getLinkage() == GlobalValue::LinkOnceODRLinkage
&& referencedGlobals.count(G.getName()) != 0) {
G.setLinkage(GlobalValue::WeakODRLinkage);
for (llvm::Function &F : M->getFunctionList()) {
collectReference(F);
}
for (llvm::GlobalAlias &A : M->aliases()) {
collectReference(A);
}
};
for (llvm::GlobalVariable &G : M->globals()) {
updateLinkage(G);
}
for (llvm::Function &F : M->getFunctionList()) {
updateLinkage(F);
}
for (llvm::GlobalAlias &A : M->aliases()) {
updateLinkage(A);
}
if (!IGM->finalize())
return;
for (auto it = irgen.begin(); it != irgen.end(); ++it) {
IRGenModule *IGM = it->second;
llvm::Module *M = IGM->getModule();
setModuleFlags(*IGM);
// Update the linkage of shared functions/globals.
// If a shared function/global is referenced from another file it must have
// weak instead of linkonce linkage. Otherwise LLVM would remove the
// definition (if it's not referenced in the same file).
auto updateLinkage = [&](llvm::GlobalValue &G) {
if (!G.isDeclaration()
&& G.getLinkage() == GlobalValue::LinkOnceODRLinkage
&& referencedGlobals.count(G.getName()) != 0) {
G.setLinkage(GlobalValue::WeakODRLinkage);
}
};
for (llvm::GlobalVariable &G : M->globals()) {
updateLinkage(G);
}
for (llvm::Function &F : M->getFunctionList()) {
updateLinkage(F);
}
for (llvm::GlobalAlias &A : M->aliases()) {
updateLinkage(A);
}
if (!IGM->finalize())
return;
setModuleFlags(*IGM);
}
}
// Bail out if there are any errors.

View File

@@ -2016,134 +2016,93 @@ void SILGenModule::visitPoundDiagnosticDecl(PoundDiagnosticDecl *PDD) {
// Nothing to do for #error/#warning; they've already been emitted.
}
namespace {
void SILGenModule::emitSourceFile(SourceFile *sf) {
// Type-check the file if we haven't already.
performTypeChecking(*sf);
// An RAII object that constructs a \c SILGenModule instance.
// On destruction, delayed definitions are automatically emitted.
class SILGenModuleRAII {
SILGenModule SGM;
if (sf->isScriptMode()) {
emitEntryPoint(sf);
}
public:
void emitSourceFile(SourceFile *sf) {
// Type-check the file if we haven't already.
performTypeChecking(*sf);
for (auto *D : sf->getTopLevelDecls()) {
// Emit auxiliary decls.
D->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
visit(auxiliaryDecl);
});
if (sf->isScriptMode()) {
SGM.emitEntryPoint(sf);
}
visit(D);
}
for (auto *D : sf->getTopLevelDecls()) {
// Emit auxiliary decls.
D->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
"SILgen-decl", auxiliaryDecl);
SGM.visit(auxiliaryDecl);
});
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
"SILgen-decl", D);
SGM.visit(D);
}
// FIXME: Visit macro-generated extensions separately.
//
// The code below that visits auxiliary decls of the top-level
// decls in the source file does not work for nested types with
// attached conformance macros:
// ```
// struct Outer {
// @AddConformance struct Inner {}
// }
// ```
// Because the attached-to decl is not at the top-level. To fix this,
// visit the macro-generated conformances that are recorded in the
// synthesized file unit to cover all macro-generated extension decls.
if (auto *synthesizedFile = sf->getSynthesizedFile()) {
for (auto *D : synthesizedFile->getTopLevelDecls()) {
if (!isa<ExtensionDecl>(D))
continue;
auto *sf = D->getInnermostDeclContext()->getParentSourceFile();
if (sf->getFulfilledMacroRole() != MacroRole::Conformance &&
sf->getFulfilledMacroRole() != MacroRole::Extension)
continue;
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
"SILgen-decl", D);
SGM.visit(D);
}
}
for (Decl *D : sf->getHoistedDecls()) {
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
"SILgen-decl", D);
SGM.visit(D);
}
for (TypeDecl *TD : sf->getLocalTypeDecls()) {
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
"SILgen-tydecl", TD);
// FIXME: Delayed parsing would prevent these types from being added to
// the module in the first place.
if (TD->getDeclContext()->getInnermostSkippedFunctionContext())
// FIXME: Visit macro-generated extensions separately.
//
// The code below that visits auxiliary decls of the top-level
// decls in the source file does not work for nested types with
// attached conformance macros:
// ```
// struct Outer {
// @AddConformance struct Inner {}
// }
// ```
// Because the attached-to decl is not at the top-level. To fix this,
// visit the macro-generated conformances that are recorded in the
// synthesized file unit to cover all macro-generated extension decls.
if (auto *synthesizedFile = sf->getSynthesizedFile()) {
for (auto *D : synthesizedFile->getTopLevelDecls()) {
if (!isa<ExtensionDecl>(D))
continue;
SGM.visit(TD);
}
// If the source file contains an artificial main, emit the implicit
// top-level code.
if (auto *mainDecl = sf->getMainDecl()) {
if (isa<FuncDecl>(mainDecl) &&
static_cast<FuncDecl *>(mainDecl)->hasAsync())
emitSILFunctionDefinition(
SILDeclRef::getAsyncMainDeclEntryPoint(mainDecl));
emitSILFunctionDefinition(SILDeclRef::getMainDeclEntryPoint(mainDecl));
auto *sf = D->getInnermostDeclContext()->getParentSourceFile();
if (sf->getFulfilledMacroRole() != MacroRole::Conformance &&
sf->getFulfilledMacroRole() != MacroRole::Extension)
continue;
visit(D);
}
}
void emitSymbolSource(SymbolSource Source) {
switch (Source.kind) {
case SymbolSource::Kind::SIL:
emitSILFunctionDefinition(Source.getSILDeclRef());
break;
case SymbolSource::Kind::Global:
SGM.addGlobalVariable(Source.getGlobal());
break;
case SymbolSource::Kind::IR:
llvm_unreachable("Unimplemented: Emission of LinkEntities");
case SymbolSource::Kind::Unknown:
case SymbolSource::Kind::LinkerDirective:
// Nothing to do
break;
for (Decl *D : sf->getHoistedDecls()) {
visit(D);
}
for (TypeDecl *TD : sf->getLocalTypeDecls()) {
// FIXME: Delayed parsing would prevent these types from being added to
// the module in the first place.
if (TD->getDeclContext()->getInnermostSkippedFunctionContext())
continue;
visit(TD);
}
// If the source file contains an artificial main, emit the implicit
// top-level code.
if (auto *mainDecl = sf->getMainDecl()) {
if (isa<FuncDecl>(mainDecl) &&
static_cast<FuncDecl *>(mainDecl)->hasAsync()) {
auto ref = SILDeclRef::getAsyncMainDeclEntryPoint(mainDecl);
emitFunctionDefinition(ref, getFunction(ref, ForDefinition));
}
auto ref = SILDeclRef::getMainDeclEntryPoint(mainDecl);
emitFunctionDefinition(ref, getFunction(ref, ForDefinition));
}
}
void emitSILFunctionDefinition(SILDeclRef ref) {
SGM.emitFunctionDefinition(ref, SGM.getFunction(ref, ForDefinition));
void SILGenModule::emitSymbolSource(SymbolSource Source) {
switch (Source.kind) {
case SymbolSource::Kind::SIL: {
auto ref = Source.getSILDeclRef();
emitFunctionDefinition(ref, getFunction(ref, ForDefinition));
break;
}
explicit SILGenModuleRAII(SILModule &M) : SGM{M, M.getSwiftModule()} {}
~SILGenModuleRAII() {
// Emit any delayed definitions that were forced.
// Emitting these may in turn force more definitions, so we have to take
// care to keep pumping the queues.
while (!SGM.pendingForcedFunctions.empty()
|| !SGM.pendingConformances.empty()) {
while (!SGM.pendingForcedFunctions.empty()) {
auto &front = SGM.pendingForcedFunctions.front();
SGM.emitFunctionDefinition(
front, SGM.getEmittedFunction(front, ForDefinition));
SGM.pendingForcedFunctions.pop_front();
}
while (!SGM.pendingConformances.empty()) {
(void)SGM.getWitnessTable(SGM.pendingConformances.front());
SGM.pendingConformances.pop_front();
}
}
case SymbolSource::Kind::Global:
addGlobalVariable(Source.getGlobal());
break;
case SymbolSource::Kind::IR:
llvm_unreachable("Unimplemented: Emission of LinkEntities");
case SymbolSource::Kind::Unknown:
case SymbolSource::Kind::LinkerDirective:
// Nothing to do
break;
}
};
} // end anonymous namespace
}
std::unique_ptr<SILModule>
ASTLoweringRequest::evaluate(Evaluator &evaluator,
@@ -2156,28 +2115,31 @@ ASTLoweringRequest::evaluate(Evaluator &evaluator,
auto silMod = SILModule::createEmptyModule(desc.context, desc.conv,
desc.opts, desc.irgenOptions);
auto &ctx = silMod->getASTContext();
FrontendStatsTracer tracer(ctx.Stats, "SILGen");
// If all function bodies are being skipped there's no reason to do any
// SIL generation.
if (desc.opts.SkipFunctionBodies == FunctionBodySkipping::All)
return silMod;
// Skip emitting SIL if there's been any compilation errors
if (silMod->getASTContext().hadError() &&
silMod->getASTContext().LangOpts.AllowModuleWithCompilerErrors)
if (ctx.hadError() &&
ctx.LangOpts.AllowModuleWithCompilerErrors)
return silMod;
SILGenModuleRAII scope(*silMod);
SILGenModule SGM(*silMod, silMod->getSwiftModule());
// Emit a specific set of SILDeclRefs if needed.
if (auto Sources = desc.SourcesToEmit) {
for (auto Source : *Sources)
scope.emitSymbolSource(std::move(Source));
SGM.emitSymbolSource(std::move(Source));
}
// Emit any whole-files needed.
for (auto file : desc.getFilesToEmit()) {
if (auto *nextSF = dyn_cast<SourceFile>(file))
scope.emitSourceFile(nextSF);
SGM.emitSourceFile(nextSF);
}
// Also make sure to process any intermediate files that may contain SIL.
@@ -2191,6 +2153,23 @@ ASTLoweringRequest::evaluate(Evaluator &evaluator,
primary);
}
// Emit any delayed definitions that were forced.
// Emitting these may in turn force more definitions, so we have to take
// care to keep pumping the queues.
while (!SGM.pendingForcedFunctions.empty()
|| !SGM.pendingConformances.empty()) {
while (!SGM.pendingForcedFunctions.empty()) {
auto &front = SGM.pendingForcedFunctions.front();
SGM.emitFunctionDefinition(
front, SGM.getEmittedFunction(front, ForDefinition));
SGM.pendingForcedFunctions.pop_front();
}
while (!SGM.pendingConformances.empty()) {
(void)SGM.getWitnessTable(SGM.pendingConformances.front());
SGM.pendingConformances.pop_front();
}
}
return silMod;
}

View File

@@ -28,6 +28,7 @@
namespace swift {
class SILBasicBlock;
class ForeignAsyncConvention;
class SymbolSource;
namespace Lowering {
class TypeConverter;
@@ -124,6 +125,12 @@ public:
ASTContext &getASTContext() { return M.getASTContext(); }
/// Main entry point.
void emitSourceFile(SourceFile *sf);
/// Lazy entry point for Feature::LazyImmediate.
void emitSymbolSource(SymbolSource Source);
llvm::StringMap<std::pair<std::string, /*isWinner=*/bool>> FileIDsByFilePath;
static DeclName getMagicFunctionName(SILDeclRef ref);

View File

@@ -1693,11 +1693,6 @@ SynthesizeDefaultInitRequest::evaluate(Evaluator &evaluator,
NominalTypeDecl *decl) const {
auto &ctx = decl->getASTContext();
FrontendStatsTracer StatsTracer(ctx.Stats,
"define-default-ctor", decl);
PrettyStackTraceDecl stackTrace("defining default constructor for",
decl);
// Create the default constructor.
auto ctorKind = decl->isDistributedActor() ?
ImplicitConstructorKind::DefaultDistributedActor :

View File

@@ -10,8 +10,8 @@
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -parse-as-library -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
// RUN: %target-swift-frontend -typecheck -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -stats-output-dir %t/stats-no-lookup -primary-file %t/b.swift %t/a.swift
// RUN: %target-swift-frontend -typecheck -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -stats-output-dir %t/stats-lookup -primary-file %t/c.swift %t/a.swift
// RUN: %target-swift-frontend -typecheck -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -stats-output-dir %t/stats-no-lookup -fine-grained-timers -primary-file %t/b.swift %t/a.swift
// RUN: %target-swift-frontend -typecheck -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -stats-output-dir %t/stats-lookup -fine-grained-timers -primary-file %t/c.swift %t/a.swift
// We use '<=' here instead of '==' to take account of the fact that in debug
// builds we'll be doing round-trip checking, which will parse the syntax tree

View File

@@ -1,8 +1,8 @@
// RUN: %empty-directory(%t)
// RUN: %empty-directory(%t/stats-events)
// RUN: %empty-directory(%t/stats-entities)
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t/stats-events %s -profile-stats-events
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t/stats-entities %s -profile-stats-entities
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t/stats-events %s -profile-stats-events -Xfrontend -fine-grained-timers
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t/stats-entities %s -profile-stats-entities -Xfrontend -fine-grained-timers
// Need to use %long-tmp because in Windows the * may expand to a path longer
// than 260 characters.

View File

@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t %s -trace-stats-events
// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t %s -trace-stats-events -Xfrontend -fine-grained-timers
// RUN: %FileCheck -input-file %t/*.csv %s
// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","SelfBoundsFromWhereClauseRequest","Sema.SelfBoundsFromWhereClauseRequest",[0-9]+,[0-9]+,"Proto",".*stats_dir_tracer.swift.*"}}

View File

@@ -149,6 +149,8 @@ def run_once_with_primary(args, ast, rng, primary_idx):
[line.split() for line in open(os.path.join(d, trace))]
if len(fields) == 2}
else:
command += ["-fine-grained-timers"]
if args.debug:
command = ["lldb", "--"] + command
stats = "stats.json"
@@ -633,6 +635,9 @@ def report(args, rng, runs):
rows = []
for k in keys:
vals = [r[k] for r in runs]
if all(v == 0 for v in vals):
print("Missing data")
return True
bounded = [max(v, 1) for v in vals]
one_fit = False
perfect_fit = False