[llvm] 7115a0b - IRLinker: avoid quadratic behavior (#157045)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 5 01:55:14 PDT 2025


Author: Vitaly Buka
Date: 2025-09-05T08:55:10Z
New Revision: 7115a0bf93b66d2ba7c42cf8359ce64c25aa5c8f

URL: https://github.com/llvm/llvm-project/commit/7115a0bf93b66d2ba7c42cf8359ce64c25aa5c8f
DIFF: https://github.com/llvm/llvm-project/commit/7115a0bf93b66d2ba7c42cf8359ce64c25aa5c8f.diff

LOG: IRLinker: avoid quadratic behavior (#157045)

After #146020  `is_contained` does linear search trough
all previously inserted operands.

On large binaries it can take up to 30%
for ThinLTO linking with CFI, which has
large `cfi.functions` metadata.

Added: 
    

Modified: 
    llvm/lib/Linker/IRMover.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index d6c15de4c4cdc..f53fe8f84fe3c 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -8,6 +8,8 @@
 
 #include "llvm/Linker/IRMover.h"
 #include "LinkDiagnosticInfo.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/IR/AutoUpgrade.h"
@@ -290,6 +292,9 @@ class IRLinker {
   Module &DstM;
   std::unique_ptr<Module> SrcM;
 
+  // Lookup table to optimize IRMover::linkNamedMDNodes().
+  DenseMap<StringRef, DenseSet<MDNode *>> NamedMDNodes;
+
   /// See IRMover::move().
   IRMover::LazyCallback AddLazyFor;
 
@@ -1132,12 +1137,20 @@ void IRLinker::linkNamedMDNodes() {
       continue;
 
     NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName());
+
+    auto &Inserted = NamedMDNodes[DestNMD->getName()];
+    if (Inserted.empty()) {
+      // Must be the first module, copy everything from DestNMD.
+      Inserted.insert(DestNMD->operands().begin(), DestNMD->operands().end());
+    }
+
     // Add Src elements into Dest node.
     for (const MDNode *Op : NMD.operands()) {
       MDNode *MD = Mapper.mapMDNode(*Op);
-      if (!is_contained(DestNMD->operands(), MD))
+      if (Inserted.insert(MD).second)
         DestNMD->addOperand(MD);
     }
+    assert(Inserted.size() == DestNMD->getNumOperands());
   }
 }
 


        


More information about the llvm-commits mailing list