[Lldb-commits] [lldb] 9b809cc - [LLDB][NativePDB] Improve ParseDeclsForContext time.

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 21 10:33:24 PDT 2022


Author: Zequan Wu
Date: 2022-10-21T10:33:16-07:00
New Revision: 9b809cc5b69a45601910bf4c60a2ece2f5462a18

URL: https://github.com/llvm/llvm-project/commit/9b809cc5b69a45601910bf4c60a2ece2f5462a18
DIFF: https://github.com/llvm/llvm-project/commit/9b809cc5b69a45601910bf4c60a2ece2f5462a18.diff

LOG: [LLDB][NativePDB] Improve ParseDeclsForContext time.

1. When we evaluating an expression multiple times and the searching scope is translation unit, ParseDeclsForContext iterates the type info and symbol info multiple times, though only the debug info is parsed once. Using llvm::call_once to make it only iterating and parsing once.

2. When evaluating an expression with identifier whose parent scope is a namespace, ParseDeclsForContext needs to search the entire type info to complete those records whose name is prefixed with the namespace's name and the entire symbol info to to parse functions and non-local variables. Caching parsed namespaces to avoid unnecessary searching.

Reviewed By: labath

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

Added: 
    

Modified: 
    lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index fb27d0ae05c3..90684cf56a1e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -21,7 +21,6 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/LLDBAssert.h"
-
 #include "PdbUtil.h"
 #include "UdtRecordCompleter.h"
 #include "SymbolFileNativePDB.h"
@@ -1232,8 +1231,11 @@ static bool isBlockDecl(clang::DeclContext &context) {
   return llvm::isa<clang::BlockDecl>(&context);
 }
 
-void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
-    llvm::Optional<llvm::StringRef> parent) {
+void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) {
+  clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context);
+  if (m_parsed_namespaces.contains(ns))
+    return;
+  std::string qname = ns->getQualifiedNameAsString();
   SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
       m_clang.GetSymbolFile()->GetBackingSymbolFile());
   PdbIndex &index = pdb->GetIndex();
@@ -1247,12 +1249,6 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
 
     CVTagRecord tag = CVTagRecord::create(cvt);
 
-    if (!parent) {
-      clang::QualType qt = GetOrCreateType(tid);
-      CompleteType(qt);
-      continue;
-    }
-
     // Call CreateDeclInfoForType unconditionally so that the namespace info
     // gets created.  But only call CreateRecordType if the namespace name
     // matches.
@@ -1263,41 +1259,68 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
       continue;
 
     clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);
-    std::string actual_ns = ns->getQualifiedNameAsString();
-    if (llvm::StringRef(actual_ns).startswith(*parent)) {
-      clang::QualType qt = GetOrCreateType(tid);
-      CompleteType(qt);
-      continue;
+    llvm::StringRef ns_name = ns->getName();
+    if (ns_name.startswith(qname)) {
+      ns_name = ns_name.drop_front(qname.size());
+      if (ns_name.startswith("::"))
+        GetOrCreateType(tid);
     }
   }
+  ParseAllFunctionsAndNonLocalVars();
+  m_parsed_namespaces.insert(ns);
+}
 
-  uint32_t module_count = index.dbi().modules().getModuleCount();
-  for (uint16_t modi = 0; modi < module_count; ++modi) {
-    CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);
-    const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
-    auto iter = symbols.begin();
-    while (iter != symbols.end()) {
-      PdbCompilandSymId sym_id{modi, iter.offset()};
-
-      switch (iter->kind()) {
-      case S_GPROC32:
-      case S_LPROC32:
-        GetOrCreateFunctionDecl(sym_id);
-        iter = symbols.at(getScopeEndOffset(*iter));
-        break;
-      case S_GDATA32:
-      case S_GTHREAD32:
-      case S_LDATA32:
-      case S_LTHREAD32:
-        GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
-        ++iter;
-        break;
-      default:
-        ++iter;
+void PdbAstBuilder::ParseAllTypes() {
+  llvm::call_once(m_parse_all_types, [this]() {
+    SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+        m_clang.GetSymbolFile()->GetBackingSymbolFile());
+    PdbIndex &index = pdb->GetIndex();
+    TypeIndex ti{index.tpi().TypeIndexBegin()};
+    for (const CVType &cvt : index.tpi().typeArray()) {
+      PdbTypeSymId tid{ti};
+      ++ti;
+
+      if (!IsTagRecord(cvt))
         continue;
+
+      GetOrCreateType(tid);
+    }
+  });
+}
+
+void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() {
+  llvm::call_once(m_parse_functions_and_non_local_vars, [this]() {
+    SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+        m_clang.GetSymbolFile()->GetBackingSymbolFile());
+    PdbIndex &index = pdb->GetIndex();
+    uint32_t module_count = index.dbi().modules().getModuleCount();
+    for (uint16_t modi = 0; modi < module_count; ++modi) {
+      CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);
+      const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
+      auto iter = symbols.begin();
+      while (iter != symbols.end()) {
+        PdbCompilandSymId sym_id{modi, iter.offset()};
+
+        switch (iter->kind()) {
+        case S_GPROC32:
+        case S_LPROC32:
+          GetOrCreateFunctionDecl(sym_id);
+          iter = symbols.at(getScopeEndOffset(*iter));
+          break;
+        case S_GDATA32:
+        case S_GTHREAD32:
+        case S_LDATA32:
+        case S_LTHREAD32:
+          GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
+          ++iter;
+          break;
+        default:
+          ++iter;
+          continue;
+        }
       }
     }
-  }
+  });
 }
 
 static CVSymbolArray skipFunctionParameters(clang::Decl &decl,
@@ -1384,14 +1407,13 @@ void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {
   // work (such as parsing the items that appear within the namespaces) at the
   // same time.
   if (context.isTranslationUnit()) {
-    ParseAllNamespacesPlusChildrenOf(llvm::None);
+    ParseAllTypes();
+    ParseAllFunctionsAndNonLocalVars();
     return;
   }
 
   if (context.isNamespace()) {
-    clang::NamespaceDecl &ns = *llvm::dyn_cast<clang::NamespaceDecl>(&context);
-    std::string qname = ns.getQualifiedNameAsString();
-    ParseAllNamespacesPlusChildrenOf(llvm::StringRef{qname});
+    ParseNamespace(context);
     return;
   }
 

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index b94176e815e0..bd359ce34b16 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Threading.h"
 
 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
 
@@ -122,7 +123,9 @@ class PdbAstBuilder {
                      TypeIndex func_ti, CompilerType func_ct,
                      uint32_t param_count, clang::StorageClass func_storage,
                      bool is_inline, clang::DeclContext *parent);
-  void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
+  void ParseNamespace(clang::DeclContext &parent);
+  void ParseAllTypes();
+  void ParseAllFunctionsAndNonLocalVars();
   void ParseDeclsForSimpleContext(clang::DeclContext &context);
   void ParseBlockChildren(PdbCompilandSymId block_id);
 
@@ -135,7 +138,8 @@ class PdbAstBuilder {
   TypeSystemClang &m_clang;
 
   ClangASTImporter m_importer;
-
+  llvm::once_flag m_parse_functions_and_non_local_vars;
+  llvm::once_flag m_parse_all_types;
   llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
   llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
   llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
@@ -145,6 +149,7 @@ class PdbAstBuilder {
   llvm::DenseMap<lldb::opaque_compiler_type_t,
                  llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
       m_cxx_record_map;
+  llvm::DenseSet<clang::NamespaceDecl *> m_parsed_namespaces;
 };
 
 } // namespace npdb


        


More information about the lldb-commits mailing list