[PDB] Use one func id DenseMap instead of per-source maps, NFC
authorReid Kleckner <rnk@google.com>
Wed, 30 Sep 2020 21:40:53 +0000 (14:40 -0700)
committerReid Kleckner <rnk@google.com>
Thu, 1 Oct 2020 19:22:27 +0000 (12:22 -0700)
This avoids some DenseMap copies when /Zi is in use, and results in
fewer data structures.

Differential Revision: https://reviews.llvm.org/D88617

lld/COFF/DebugTypes.cpp
lld/COFF/DebugTypes.h
lld/COFF/PDB.cpp
lld/COFF/TypeMerger.h

index 557bdd9..4ce0311 100644 (file)
@@ -525,9 +525,6 @@ Error UsePrecompSource::mergeInPrecompHeaderObj() {
                          precompSrc->tpiMap.begin() +
                              precompDependency.getTypesCount());
 
-  if (config->debugGHashes)
-    funcIdToType = precompSrc->funcIdToType; // FIXME: Save copy
-
   return Error::success();
 }
 
@@ -612,7 +609,7 @@ void TpiSource::fillIsItemIndexFromDebugT() {
   });
 }
 
-void TpiSource::mergeTypeRecord(CVType ty) {
+void TpiSource::mergeTypeRecord(TypeIndex curIndex, CVType ty) {
   // Decide if the merged type goes into TPI or IPI.
   bool isItem = isIdRecord(ty.kind());
   MergedInfo &merged = isItem ? mergedIpi : mergedTpi;
@@ -637,6 +634,25 @@ void TpiSource::mergeTypeRecord(CVType ty) {
   uint32_t pdbHash = check(pdb::hashTypeRecord(CVType(newRec)));
   merged.recSizes.push_back(static_cast<uint16_t>(newSize));
   merged.recHashes.push_back(pdbHash);
+
+  // Retain a mapping from PDB function id to PDB function type. This mapping is
+  // used during symbol procesing to rewrite S_GPROC32_ID symbols to S_GPROC32
+  // symbols.
+  if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) {
+    bool success = ty.length() >= 12;
+    TypeIndex funcId = curIndex;
+    if (success)
+      success &= remapTypeIndex(funcId, TiRefKind::IndexRef);
+    TypeIndex funcType =
+        *reinterpret_cast<const TypeIndex *>(&newRec.data()[8]);
+    if (success) {
+      funcIdToType.push_back({funcId, funcType});
+    } else {
+      StringRef fname = file ? file->getName() : "<unknown PDB>";
+      warn("corrupt LF_[M]FUNC_ID record 0x" + utohexstr(curIndex.getIndex()) +
+           " in " + fname);
+    }
+  }
 }
 
 void TpiSource::mergeUniqueTypeRecords(ArrayRef<uint8_t> typeRecords,
@@ -655,27 +671,9 @@ void TpiSource::mergeUniqueTypeRecords(ArrayRef<uint8_t> typeRecords,
   forEachTypeChecked(typeRecords, [&](const CVType &ty) {
     if (nextUniqueIndex != uniqueTypes.end() &&
         *nextUniqueIndex == ghashIndex) {
-      mergeTypeRecord(ty);
+      mergeTypeRecord(beginIndex + ghashIndex, ty);
       ++nextUniqueIndex;
     }
-    if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) {
-      bool success = ty.length() >= 12;
-      TypeIndex srcFuncIdIndex = beginIndex + ghashIndex;
-      TypeIndex funcId = srcFuncIdIndex;
-      TypeIndex funcType;
-      if (success) {
-        funcType = *reinterpret_cast<const TypeIndex *>(&ty.data()[8]);
-        success &= remapTypeIndex(funcId, TiRefKind::IndexRef);
-        success &= remapTypeIndex(funcType, TiRefKind::TypeRef);
-      }
-      if (success) {
-        funcIdToType.insert({funcId, funcType});
-      } else {
-        StringRef fname = file ? file->getName() : "<unknown PDB>";
-        warn("corrupt LF_[M]FUNC_ID record 0x" +
-             utohexstr(srcFuncIdIndex.getIndex()) + " in " + fname);
-      }
-    }
     ++ghashIndex;
   });
   assert(nextUniqueIndex == uniqueTypes.end() &&
@@ -758,7 +756,6 @@ void TypeServerSource::remapTpiWithGHashes(GHashState *g) {
     ipiSrc->tpiMap = tpiMap;
     ipiSrc->ipiMap = ipiMap;
     ipiSrc->mergeUniqueTypeRecords(typeArrayToBytes(ipi.typeArray()));
-    funcIdToType = ipiSrc->funcIdToType; // FIXME: Save copy
   }
 }
 
@@ -775,7 +772,6 @@ void UseTypeServerSource::remapTpiWithGHashes(GHashState *g) {
   TypeServerSource *tsSrc = *maybeTsSrc;
   tpiMap = tsSrc->tpiMap;
   ipiMap = tsSrc->ipiMap;
-  funcIdToType = tsSrc->funcIdToType; // FIXME: Save copy
 }
 
 void PrecompSource::loadGHashes() {
@@ -1102,6 +1098,13 @@ void TypeMerger::mergeTypesWithGHash() {
     source->remapTpiWithGHashes(&ghashState);
   });
 
+  // Build a global map of from function ID to function type.
+  for (TpiSource *source : TpiSource::instances) {
+    for (auto idToType : source->funcIdToType)
+      funcIdToType.insert(idToType);
+    source->funcIdToType.clear();
+  }
+
   TpiSource::clearGHashes();
 }
 
index 1736824..ebb3b2b 100644 (file)
@@ -72,7 +72,7 @@ protected:
   void remapRecord(MutableArrayRef<uint8_t> rec,
                    ArrayRef<llvm::codeview::TiReference> typeRefs);
 
-  void mergeTypeRecord(llvm::codeview::CVType ty);
+  void mergeTypeRecord(TypeIndex curIndex, llvm::codeview::CVType ty);
 
   // Merge the type records listed in uniqueTypes. beginIndex is the TypeIndex
   // of the first record in this source, typically 0x1000. When PCHs are
@@ -164,7 +164,7 @@ public:
 
   /// When ghashing is used, record the mapping from LF_[M]FUNC_ID to function
   /// type index here. Both indices are PDB indices, not object type indexes.
-  llvm::DenseMap<TypeIndex, TypeIndex> funcIdToType;
+  std::vector<std::pair<TypeIndex, TypeIndex>> funcIdToType;
 
   /// Indicates if a type record is an item index or a type index.
   llvm::BitVector isItemIndex;
index 21a1341..ae2dc9a 100644 (file)
@@ -334,8 +334,8 @@ static void translateIdSymbols(MutableArrayRef<uint8_t> &recordData,
     // in both cases we just need the second type index.
     if (!ti->isSimple() && !ti->isNoneType()) {
       if (config->debugGHashes) {
-        auto idToType = source->funcIdToType.find(*ti);
-        if (idToType == source->funcIdToType.end()) {
+        auto idToType = tMerger.funcIdToType.find(*ti);
+        if (idToType == tMerger.funcIdToType.end()) {
           warn(formatv("S_[GL]PROC32_ID record in {0} refers to PDB item "
                        "index {1:X} which is not a LF_[M]FUNC_ID record",
                        source->file->getName(), ti->getIndex()));
index be877cf..72fd5fc 100644 (file)
@@ -45,6 +45,10 @@ public:
   /// indices in each TpiSource.
   void mergeTypesWithGHash();
 
+  /// Map from PDB function id type indexes to PDB function type indexes.
+  /// Populated after mergeTypesWithGHash.
+  llvm::DenseMap<TypeIndex, TypeIndex> funcIdToType;
+
   /// Type records that will go into the PDB TPI stream.
   llvm::codeview::MergingTypeTableBuilder typeTable;