[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
This commit is contained in:
Volodymyr Sapsai 2020-01-06 11:55:55 -08:00
parent e75afc9acf
commit c4bacc3c9b
6 changed files with 41 additions and 2 deletions

View File

@ -55,6 +55,10 @@
using namespace clang;
#define DEBUG_TYPE "modules"
ALWAYS_ENABLED_STATISTIC(NumCompiledModules, "Number of compiled modules.");
CompilerInstance::CompilerInstance(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
InMemoryModuleCache *SharedModuleCache)
@ -1063,6 +1067,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
llvm::function_ref<void(CompilerInstance &)> PostBuildStep =
[](CompilerInstance &) {}) {
llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
++NumCompiledModules;
// Construct a compiler invocation for creating this module.
auto Invocation =

View File

@ -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<ImportedSubmodule> *Imported) {
++NumTryLoadModule;
llvm::SaveAndRestore<SourceLocation>
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) {

View File

@ -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<MB> Result(
new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile<MB>(
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<char> ToRead = Buf->getBuffer();
while (!ToRead.empty()) {
Expected<size_t> ReadBytes =

View File

@ -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;

View File

@ -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);

View File

@ -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<wchar_t, 128> 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<HANDLE>(_get_osfhandle(FD));
return getStatus(FileHandle, Result);
}
std::error_code status(file_t FileHandle, file_status &Result) {
++NumStatusCalls;
return getStatus(FileHandle, Result);
}