From ce18a187f71a67125395181e821340b27d8fbdd9 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 14 Jul 2015 00:26:00 +0000 Subject: [PATCH] Extend -ftime-report to give more information about time spent reading module files. llvm-svn: 242094 --- .../include/clang/Frontend/CompilerInstance.h | 6 +++++- clang/include/clang/Serialization/ASTReader.h | 12 +++++++++-- clang/lib/Frontend/CompilerInstance.cpp | 21 +++++++++++++++++-- clang/lib/Serialization/ASTReader.cpp | 12 ++++++++++- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 084d876a2ae2..2f3e1b6cebb1 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -30,6 +30,7 @@ namespace llvm { class raw_fd_ostream; class Timer; +class TimerGroup; } namespace clang { @@ -101,7 +102,10 @@ class CompilerInstance : public ModuleLoader { /// \brief The semantic analysis object. std::unique_ptr TheSema; - /// \brief The frontend timer + /// \brief The frontend timer group. + std::unique_ptr FrontendTimerGroup; + + /// \brief The frontend timer. std::unique_ptr FrontendTimer; /// \brief The ASTReader, if one exists. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 6fa7ffa116b0..9377dfac99cc 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -42,6 +42,7 @@ #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Timer.h" #include #include #include @@ -380,6 +381,9 @@ private: /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; + /// \brief A timer used to track the time spent deserializing. + std::unique_ptr ReadTimer; + /// \brief The location where the module file will be considered as /// imported from. For non-module AST types it should be invalid. SourceLocation CurrentImportLoc; @@ -1281,12 +1285,16 @@ public: /// /// \param UseGlobalIndex If true, the AST reader will try to load and use /// the global module index. + /// + /// \param ReadTimer If non-null, a timer used to track the time spent + /// deserializing. ASTReader(Preprocessor &PP, ASTContext &Context, const PCHContainerOperations &PCHContainerOps, StringRef isysroot = "", bool DisableValidation = false, bool AllowASTWithCompilerErrors = false, bool AllowConfigurationMismatch = false, - bool ValidateSystemInputs = false, bool UseGlobalIndex = true); + bool ValidateSystemInputs = false, bool UseGlobalIndex = true, + std::unique_ptr ReadTimer = {}); ~ASTReader() override; @@ -1710,7 +1718,7 @@ public: /// \brief Notify ASTReader that we started deserialization of /// a decl or type so until FinishedDeserializing is called there may be /// decls that are initializing. Must be paired with FinishedDeserializing. - void StartedDeserializing() override { ++NumCurrentElementsDeserializing; } + void StartedDeserializing() override; /// \brief Notify ASTReader that we finished the deserialization of /// a decl or type. Must be paired with StartedDeserializing. diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index f42198df4f8a..ff041a8ec431 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -497,7 +497,9 @@ void CompilerInstance::createCodeCompletionConsumer() { } void CompilerInstance::createFrontendTimer() { - FrontendTimer.reset(new llvm::Timer("Clang front-end timer")); + FrontendTimerGroup.reset(new llvm::TimerGroup("Clang front-end time report")); + FrontendTimer.reset( + new llvm::Timer("Clang front-end timer", *FrontendTimerGroup)); } CodeCompleteConsumer * @@ -1237,13 +1239,18 @@ void CompilerInstance::createModuleManager() { HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); std::string Sysroot = HSOpts.Sysroot; const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + std::unique_ptr ReadTimer; + if (FrontendTimerGroup) + ReadTimer = llvm::make_unique("Reading modules", + *FrontendTimerGroup); ModuleManager = new ASTReader( getPreprocessor(), *Context, *getPCHContainerOperations(), Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, /*AllowASTWithCompilerErrors=*/false, /*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders, - getFrontendOpts().UseGlobalModuleIndex); + getFrontendOpts().UseGlobalModuleIndex, + std::move(ReadTimer)); if (hasASTConsumer()) { ModuleManager->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); @@ -1259,6 +1266,11 @@ void CompilerInstance::createModuleManager() { } bool CompilerInstance::loadModuleFile(StringRef FileName) { + llvm::Timer Timer; + if (FrontendTimerGroup) + Timer.init("Preloading " + FileName.str(), *FrontendTimerGroup); + llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); + // Helper to recursively read the module names for all modules we're adding. // We mark these as known and redirect any attempt to load that module to // the files we were handed. @@ -1418,6 +1430,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, for (auto &Listener : DependencyCollectors) Listener->attachToASTReader(*ModuleManager); + llvm::Timer Timer; + if (FrontendTimerGroup) + Timer.init("Loading " + ModuleFileName, *FrontendTimerGroup); + llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); + // Try to load the module file. unsigned ARRFlags = Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 275dfc5a6082..70362a6db08c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -8396,6 +8396,11 @@ void ASTReader::diagnoseOdrViolations() { } } +void ASTReader::StartedDeserializing() { + if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get()) + ReadTimer->startTimer(); +} + void ASTReader::FinishedDeserializing() { assert(NumCurrentElementsDeserializing && "FinishedDeserializing not paired with StartedDeserializing"); @@ -8420,6 +8425,9 @@ void ASTReader::FinishedDeserializing() { diagnoseOdrViolations(); + if (ReadTimer) + ReadTimer->stopTimer(); + // We are not in recursive loading, so it's safe to pass the "interesting" // decls to the consumer. if (Consumer) @@ -8458,12 +8466,14 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot, bool DisableValidation, bool AllowASTWithCompilerErrors, bool AllowConfigurationMismatch, bool ValidateSystemInputs, - bool UseGlobalIndex) + bool UseGlobalIndex, + std::unique_ptr ReadTimer) : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr), OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), PCHContainerOps(PCHContainerOps), Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context), Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerOps), + ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidation(DisableValidation), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), AllowConfigurationMismatch(AllowConfigurationMismatch),