[llvm] [IR] Skip remove_if scan for empty maps in removeNotPreservedAnalysis (PR #200292)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 28 15:49:40 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Fangrui Song (MaskRay)

<details>
<summary>Changes</summary>

removeNotPreservedAnalysis runs after every legacy-PM pass. #<!-- -->198982
changed it to DenseMap::remove_if, which iterates the raw bucket array
even when the map is empty. The old begin()/end() loop did not: begin()'s
makeBegin returns end() directly for an empty map (its "avoid advancing
past empty buckets" shortcut), so the loop touched no buckets. These maps
are usually empty here but keep a grown bucket array after their entries
are erased (a 64-bucket array when compiling sqlite3.i at -O0 -g), so
remove_if walks empty buckets for nothing, regressing instructions:u
(most visible at -O0). #<!-- -->199571 was a small fix for the out-of-lined
remove_if call; this addresses the dominant cost.

Skip empty maps, which fixes the regression:
https://llvm-compile-time-tracker.com/compare.php?from=8ab00f2c21e5975f5de977ca68607b4acc23c856&to=6a33135fad599da0c2c9919ec37f81217e5c8f6b&stat=instructions:u


---
Full diff: https://github.com/llvm/llvm-project/pull/200292.diff


1 Files Affected:

- (modified) llvm/lib/IR/LegacyPassManager.cpp (+5) 


``````````diff
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index 1cdb721c87051..641c49a213b80 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -914,6 +914,11 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
   // call site makes the inliner emit it out of line, which adds a call in this
   // hot per-pass path. A single call site keeps it inlined here.
   for (DenseMap<AnalysisID, Pass *> *M : Maps) {
+    // These maps are usually empty here, but a DenseMap keeps its grown bucket
+    // array after the entries are erased, so remove_if would still scan all
+    // those empty buckets. Skip it.
+    if (M->empty())
+      continue;
     M->remove_if([&](const auto &Entry) {
       if (Entry.second->getAsImmutablePass() != nullptr ||
           is_contained(PreservedSet, Entry.first))

``````````

</details>


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


More information about the llvm-commits mailing list