https://github.com/dzbarsky created https://github.com/llvm/llvm-project/pull/203008
`ConfigYAML.cpp`'s `DictParser` owns its callbacks for one parse and never copies them, so this replaces `std::function` with move-only `llvm::unique_function` and removes the unused copy machinery for each lambda. In a matched Release AArch64 build, `ConfigYAML.cpp.o` shrank by 94,560 bytes, stripped clangd shrank by 16,848 bytes, unstripped clangd shrank by 82,512 bytes, and dyld fixups fell by 336. Validated with the 16 `ParseYAML` unit tests and `clangd --check`; 12 paired runs of 100,000 parses improved mean user CPU time by 3.46% (95% CI: 1.31% to 5.61%). Work towards #202616 AI tool disclosure: Co-authored with OpenAI Codex. >From 854e72d8e52fddcb0307e5f1c12c8ced6fb46525 Mon Sep 17 00:00:00 2001 From: David Zbarsky <[email protected]> Date: Wed, 10 Jun 2026 11:06:00 -0400 Subject: [PATCH] [clangd] Use unique_function for config handlers DictParser owns its key and unknown-key callbacks for one parse and never copies them. Store the callbacks in llvm::unique_function instead of std::function so each lambda does not need std::function copy support. In a matched Release AArch64 build at f3632e0b6f14, ConfigYAML.cpp.o shrank from 185,344 to 90,784 bytes, section payload shrank from 65,192 to 47,240 bytes, and relocations fell from 2,499 to 1,181. clangd shrank from 72,130,664 to 72,048,152 bytes unstripped and from 57,818,232 to 57,801,384 bytes stripped. Linked __text fell by 3,580 bytes, __DATA_CONST,__const fell by 4,032 bytes, and dyld fixups fell from 175,243 to 174,907. Twelve paired runs of 100,000 ParseYAML.SyntacticForms parses reduced mean user CPU time from 2.5575 to 2.4692 seconds, a 3.46% improvement with a paired 95% confidence interval of 1.31% to 5.61%. Validated with a Release AArch64 clangd and ClangdTests build, all 16 ParseYAML unit tests, and clangd --check using a .clangd file that injects a required preprocessor definition. --- clang-tools-extra/clangd/ConfigYAML.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp index 7b6993620fb8c..940c7b8bd2de1 100644 --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ConfigFragment.h" #include "support/Logger.h" +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" @@ -334,8 +335,11 @@ class Parser { // We don't use YamlIO as we want to control over unknown keys. class DictParser { llvm::StringRef Description; - std::vector<std::pair<llvm::StringRef, std::function<void(Node &)>>> Keys; - std::function<bool(Located<std::string>, Node &)> UnknownHandler; + std::vector< + std::pair<llvm::StringRef, llvm::unique_function<void(Node &) const>>> + Keys; + llvm::unique_function<bool(Located<std::string>, Node &) const> + UnknownHandler; Parser *Outer; public: @@ -345,7 +349,8 @@ class Parser { // Parse is called when Key is encountered, and passed the associated value. // It should emit diagnostics if the value is invalid (e.g. wrong type). // If Key is seen twice, Parse runs only once and an error is reported. - void handle(llvm::StringLiteral Key, std::function<void(Node &)> Parse) { + void handle(llvm::StringLiteral Key, + llvm::unique_function<void(Node &) const> Parse) { for (const auto &Entry : Keys) { (void)Entry; assert(Entry.first != Key && "duplicate key handler"); @@ -357,7 +362,8 @@ class Parser { // If this is unset or the Handler returns true, a warning is emitted for // the unknown key. void - unrecognized(std::function<bool(Located<std::string>, Node &)> Handler) { + unrecognized(llvm::unique_function<bool(Located<std::string>, Node &) const> + Handler) { UnknownHandler = std::move(Handler); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
