[llvm] [PDB] Refactor cache strategy for function symbol lookups (PR #188927)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 09:52:55 PDT 2026


================
@@ -355,29 +366,67 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
     consumeError(ExpectedModS.takeError());
     return nullptr;
   }
-  CVSymbolArray Syms = ExpectedModS->getSymbolArray();
 
-  // Search for the symbol in this module.
+  // Return empty intervals in AddressToSymbolId from Start to Stop.
+  auto getInsertRanges = [this](uint64_t Start, uint64_t Stop) {
+    SmallVector<std::pair<uint64_t, uint64_t>> Ranges;
+    auto Iter = AddressToSymbolId.find(Start);
+    while (Iter.valid() && IMapTy::KeyTraits::nonEmpty(Start, Stop)) {
+      if (IMapTy::KeyTraits::startLess(Start, Iter.start()))
+        Ranges.push_back({Start, std::min(Iter.start(), Stop)});
+
+      // Same result as Start = std::min(Stop, Iter.stop()).
+      Start = Iter.stop();
+      ++Iter;
+    }
+    if (IMapTy::KeyTraits::nonEmpty(Start, Stop))
+      Ranges.push_back({Start, Stop});
+
+    return Ranges;
+  };
+
+  // Decode symbols in this module.
+  CVSymbolArray Syms = ExpectedModS->getSymbolArray();
   for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
     if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
       continue;
+
     auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
-    if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
-        Offset < PS.CodeOffset + PS.CodeSize) {
-      // Check if the symbol is already cached.
-      auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
-      if (Found != AddressToSymbolId.end())
-        return getSymbolById(Found->second);
-
-      // Otherwise, create a new symbol.
+    uint64_t SymStart = Session.getVAFromSectOffset(PS.Segment, PS.CodeOffset);
+    uint64_t SymStop = SymStart + PS.CodeSize;
+    if (LLVM_UNLIKELY(!IMapTy::KeyTraits::nonEmpty(SymStart, SymStop))) {
+      I = Syms.at(PS.End);
+      continue;
+    }
+#ifndef NDEBUG
+    const auto &AddrToModuleIndex = Session.getAddrToModuleIndex();
+    auto ModIter = AddrToModuleIndex.find(SymStart);
+    using ModKeyTraits =
+        std::remove_reference_t<decltype(AddrToModuleIndex)>::KeyTraits;
+    assert(ModIter.valid() &&
+           !ModKeyTraits::startLess(SymStart, ModIter.start()) &&
+           !ModKeyTraits::stopLess(ModIter.stop(), SymStop - 1) &&
+           "Symbol spans modules");
----------------
Nerixyz wrote:

This could check that `moduleIndexForVA(SymStart) == moduleIndexForVA(SymStop - 1)`. Then you can avoid having `getAddrToModuleIndex`.

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


More information about the llvm-commits mailing list