From c4bacc3c9b333bb7032fb96f41d6f5b851623132 Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Mon, 6 Jan 2020 11:55:55 -0800 Subject: [PATCH] [Modules] Add stats to measure performance of building and loading modules. Measure amount of high-level or fixed-cost operations performed during building/loading modules and during header search. High-level operations like building a module or processing a .pcm file are motivated by previous issues where clang was re-building modules or re-reading .pcm files unnecessarily. Fixed-cost operations like `stat` calls are tracked because clang cannot change how long each operation takes but it can perform fewer of such operations to improve the compile time. Also tracking such stats over time can help us detect compile-time regressions. Added stats are more stable than the actual measured compilation time, so expect the detected regressions to be less noisy. rdar://problem/55715134 Reviewed By: aprantl, bruno Differential Revision: https://reviews.llvm.org/D86895 --- clang/lib/Frontend/CompilerInstance.cpp | 5 +++++ clang/lib/Serialization/ASTReader.cpp | 12 ++++++++++++ llvm/lib/Support/MemoryBuffer.cpp | 16 ++++++++++++++-- llvm/lib/Support/Path.cpp | 5 +++++ llvm/lib/Support/Unix/Path.inc | 2 ++ llvm/lib/Support/Windows/Path.inc | 3 +++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 4613ed8d7f61..445049324780 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -55,6 +55,10 @@ using namespace clang; +#define DEBUG_TYPE "modules" + +ALWAYS_ENABLED_STATISTIC(NumCompiledModules, "Number of compiled modules."); + CompilerInstance::CompilerInstance( std::shared_ptr PCHContainerOps, InMemoryModuleCache *SharedModuleCache) @@ -1063,6 +1067,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, llvm::function_ref PostBuildStep = [](CompilerInstance &) {}) { llvm::TimeTraceScope TimeScope("Module Compile", ModuleName); + ++NumCompiledModules; // Construct a compiler invocation for creating this module. auto Invocation = diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index b2780db85166..e71d73310d52 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -100,6 +100,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -142,6 +143,15 @@ using namespace clang::serialization::reader; using llvm::BitstreamCursor; using llvm::RoundingMode; +#define DEBUG_TYPE "modules" + +ALWAYS_ENABLED_STATISTIC(NumTryLoadModule, "Number of times tried to load a " + "module. Includes failed attempts " + "and using cached results."); +ALWAYS_ENABLED_STATISTIC(NumReadASTCore, + "Number of ReadASTCore() invocations. Includes only " + "actual AST core parsing and ignores cached results."); + //===----------------------------------------------------------------------===// // ChainedASTReaderListener implementation //===----------------------------------------------------------------------===// @@ -4203,6 +4213,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, SourceLocation ImportLoc, unsigned ClientLoadCapabilities, SmallVectorImpl *Imported) { + ++NumTryLoadModule; llvm::SaveAndRestore SetCurImportLocRAII(CurrentImportLoc, ImportLoc); @@ -4552,6 +4563,7 @@ ASTReader::ReadASTCore(StringRef FileName, return Failure; } + ++NumReadASTCore; // This is used for compatibility with older PCH formats. bool HaveReadControlBlock = false; while (true) { diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp index 248fb72c4968..4b851a20fc48 100644 --- a/llvm/lib/Support/MemoryBuffer.cpp +++ b/llvm/lib/Support/MemoryBuffer.cpp @@ -12,6 +12,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Config/config.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Errno.h" @@ -34,6 +35,12 @@ #endif using namespace llvm; +#define DEBUG_TYPE "memory-buffer" + +ALWAYS_ENABLED_STATISTIC(NumMmapFile, "Number of mmap-ed files."); +ALWAYS_ENABLED_STATISTIC(NumAllocFile, + "Number of files read into allocated memory buffer."); + //===----------------------------------------------------------------------===// // MemoryBuffer implementation itself. //===----------------------------------------------------------------------===// @@ -449,8 +456,10 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, // buffer by copying off the stream. sys::fs::file_type Type = Status.type(); if (Type != sys::fs::file_type::regular_file && - Type != sys::fs::file_type::block_file) + Type != sys::fs::file_type::block_file) { + ++NumAllocFile; return getMemoryBufferForStream(FD, Filename); + } FileSize = Status.getSize(); } @@ -463,8 +472,10 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, std::unique_ptr Result( new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile( RequiresNullTerminator, FD, MapSize, Offset, EC)); - if (!EC) + if (!EC) { + ++NumMmapFile; return std::move(Result); + } } auto Buf = WritableMemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); @@ -475,6 +486,7 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, } // Read until EOF, zero-initialize the rest. + ++NumAllocFile; MutableArrayRef ToRead = Buf->getBuffer(); while (!ToRead.empty()) { Expected ReadBytes = diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index bbc02a246a50..7f4b7cbdc31e 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -12,6 +12,7 @@ #include "llvm/Support/Path.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Errc.h" @@ -31,6 +32,10 @@ using namespace llvm; using namespace llvm::support::endian; +#define DEBUG_TYPE "file-system" + +ALWAYS_ENABLED_STATISTIC(NumStatusCalls, "Number of `status` calls."); + namespace { using llvm::StringRef; using llvm::sys::path::is_separator; diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 01903ea10e81..622d4fc5b4b1 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -736,6 +736,7 @@ static std::error_code fillStatus(int StatRet, const struct stat &Status, } std::error_code status(const Twine &Path, file_status &Result, bool Follow) { + ++NumStatusCalls; SmallString<128> PathStorage; StringRef P = Path.toNullTerminatedStringRef(PathStorage); @@ -745,6 +746,7 @@ std::error_code status(const Twine &Path, file_status &Result, bool Follow) { } std::error_code status(int FD, file_status &Result) { + ++NumStatusCalls; struct stat Status; int StatRet = ::fstat(FD, &Status); return fillStatus(StatRet, Status, Result); diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 399b054d36bd..cb7bf0beba1f 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -710,6 +710,7 @@ handle_status_error: } std::error_code status(const Twine &path, file_status &result, bool Follow) { + ++NumStatusCalls; SmallString<128> path_storage; SmallVector path_utf16; @@ -742,11 +743,13 @@ std::error_code status(const Twine &path, file_status &result, bool Follow) { } std::error_code status(int FD, file_status &Result) { + ++NumStatusCalls; HANDLE FileHandle = reinterpret_cast(_get_osfhandle(FD)); return getStatus(FileHandle, Result); } std::error_code status(file_t FileHandle, file_status &Result) { + ++NumStatusCalls; return getStatus(FileHandle, Result); }