Skip to content

Commit f407c9e

Browse files
committed
[clangd] Export preamble AST and serialized size as metrics
Differential Revision: https://reviews.llvm.org/D123672
1 parent af92100 commit f407c9e

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ bool compileCommandsAreEqual(const tooling::CompileCommand &LHS,
6464

6565
class CppFilePreambleCallbacks : public PreambleCallbacks {
6666
public:
67-
CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback)
68-
: File(File), ParsedCallback(ParsedCallback) {}
67+
CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback,
68+
PreambleBuildStats *Stats)
69+
: File(File), ParsedCallback(ParsedCallback), Stats(Stats) {}
6970

7071
IncludeStructure takeIncludes() { return std::move(Includes); }
7172

@@ -88,6 +89,25 @@ class CppFilePreambleCallbacks : public PreambleCallbacks {
8889
IsMainFileIncludeGuarded =
8990
CI.getPreprocessor().getHeaderSearchInfo().isFileMultipleIncludeGuarded(
9091
MainFE);
92+
93+
if (Stats) {
94+
const ASTContext &AST = CI.getASTContext();
95+
Stats->BuildSize = AST.getASTAllocatedMemory();
96+
Stats->BuildSize += AST.getSideTableAllocatedMemory();
97+
Stats->BuildSize += AST.Idents.getAllocator().getTotalMemory();
98+
Stats->BuildSize += AST.Selectors.getTotalMemory();
99+
100+
Stats->BuildSize += AST.getSourceManager().getContentCacheSize();
101+
Stats->BuildSize += AST.getSourceManager().getDataStructureSizes();
102+
Stats->BuildSize +=
103+
AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
104+
105+
const Preprocessor &PP = CI.getPreprocessor();
106+
Stats->BuildSize += PP.getTotalMemory();
107+
if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
108+
Stats->BuildSize += PRec->getTotalMemory();
109+
Stats->BuildSize += PP.getHeaderSearchInfo().getTotalMemory();
110+
}
91111
}
92112

93113
void BeforeExecute(CompilerInstance &CI) override {
@@ -135,6 +155,7 @@ class CppFilePreambleCallbacks : public PreambleCallbacks {
135155
std::unique_ptr<CommentHandler> IWYUHandler = nullptr;
136156
const clang::LangOptions *LangOpts = nullptr;
137157
const SourceManager *SourceMgr = nullptr;
158+
PreambleBuildStats *Stats;
138159
};
139160

140161
// Represents directives other than includes, where basic textual information is
@@ -456,7 +477,7 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
456477
// to read back. We rely on dynamic index for the comments instead.
457478
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
458479

459-
CppFilePreambleCallbacks CapturedInfo(FileName, PreambleCallback);
480+
CppFilePreambleCallbacks CapturedInfo(FileName, PreambleCallback, Stats);
460481
auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
461482
llvm::SmallString<32> AbsFileName(FileName);
462483
VFS->makeAbsolute(AbsFileName);
@@ -476,6 +497,12 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
476497
// bodies.
477498
CI.getFrontendOpts().SkipFunctionBodies = false;
478499

500+
if (Stats != nullptr) {
501+
Stats->TotalBuildTime = PreambleTimer.getTime();
502+
Stats->FileSystemTime = TimedFS->getTime();
503+
Stats->SerializedSize = BuiltPreamble ? BuiltPreamble->getSize() : 0;
504+
}
505+
479506
if (BuiltPreamble) {
480507
vlog("Built preamble of size {0} for file {1} version {2} in {3} seconds",
481508
BuiltPreamble->getSize(), FileName, Inputs.Version,
@@ -491,10 +518,6 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
491518
Result->CanonIncludes = CapturedInfo.takeCanonicalIncludes();
492519
Result->StatCache = std::move(StatCache);
493520
Result->MainIsIncludeGuarded = CapturedInfo.isMainFileIncludeGuarded();
494-
if (Stats != nullptr) {
495-
Stats->TotalBuildTime = PreambleTimer.getTime();
496-
Stats->FileSystemTime = TimedFS->getTime();
497-
}
498521
return Result;
499522
}
500523

clang-tools-extra/clangd/Preamble.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ struct PreambleBuildStats {
8383
double TotalBuildTime;
8484
/// Time spent in filesystem operations during the build, in seconds.
8585
double FileSystemTime;
86+
87+
/// Estimate of the memory used while building the preamble.
88+
/// This memory has been released when buildPreamble returns.
89+
/// For example, this includes the size of the in-memory AST (ASTContext).
90+
size_t BuildSize;
91+
/// The serialized size of the preamble.
92+
/// This storage is needed while the preamble is used (but may be on disk).
93+
size_t SerializedSize;
8694
};
8795

8896
/// Build a preamble for the new inputs unless an old one can be reused.

clang-tools-extra/clangd/TUScheduler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ constexpr trace::Metric
110110
constexpr trace::Metric PreambleBuildFilesystemLatencyRatio(
111111
"preamble_fs_latency_ratio", trace::Metric::Distribution, "build_type");
112112

113+
constexpr trace::Metric PreambleBuildSize("preamble_build_size",
114+
trace::Metric::Distribution);
115+
constexpr trace::Metric PreambleSerializedSize("preamble_serialized_size",
116+
trace::Metric::Distribution);
117+
113118
void reportPreambleBuild(const PreambleBuildStats &Stats,
114119
bool IsFirstPreamble) {
115120
auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
@@ -122,6 +127,9 @@ void reportPreambleBuild(const PreambleBuildStats &Stats,
122127
static llvm::once_flag OnceFlag;
123128
llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
124129
RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
130+
131+
PreambleBuildSize.record(Stats.BuildSize);
132+
PreambleSerializedSize.record(Stats.SerializedSize);
125133
}
126134

127135
class ASTWorker;

0 commit comments

Comments
 (0)