[clang] [Sema] Skip ExternalSource query and clear DeleteExprs in incremental mode (PR #192856)

via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 19 14:24:17 PDT 2026


================

----------------
lucasvallejoo wrote:

Hi @vgvassilev,

These changes are aimed at resolving severe performance bottlenecks and memory accumulation in incremental mode (e.g., during long ROOT/Cling REPL sessions). Here is how each change affects the patch:

1. The !PP.isIncrementalProcessingEnabled() guard:
**Why we need it:** In a REPL environment, ActOnEndOfTranslationUnit is triggered after every input line. Unconditionally querying the ExternalSource on every cycle forces redundant AST deserialization and heavy disk I/O for data that hasn't changed.
**Effect:** It completely skips this expensive disk read during interactive sessions, eliminating the I/O bottleneck.

2. The DeleteExprs.clear() call:
**Why we need it:** DeleteExprs is a stateful map. Without clearing it, entries from previous REPL lines accumulate indefinitely. This forces the compiler to re-analyze all historical mismatching expressions over and over on subsequent inputs, leading to O(N^2) redundant AST traversals and unbounded memory growth.
**Effect:** It resets the state after the analysis pass, ensuring we only spend CPU cycles analyzing the expressions actually introduced in the current incremental cycle. (Note: The duplicate warnings weren't visible to the user because the DiagnosticsEngine suppressed them via SourceLocation deduplication, but the redundant work was still happening under the hood).

Let me know if this clears it up or if you'd like me to adjust anything in the implementation!

https://github.com/llvm/llvm-project/pull/192856


More information about the cfe-commits mailing list