Skip to content

Commit 4106480

Browse files
[lldb][progress] Improve Swift progress reporting (#7769)
LLDB's progress reporting infrastructure has had the ability to add details to an overall progress report (added in https://reviews.llvm.org/D143690) but this had yet to be implemented in existing progress reports. This commit adds this functionality to progress reports made for Swift operations (such as caching user imports) so that instead of sending several individual progress reports for each step in these operations, one progress report is created and then incrementally updated. Importing Swift modules takes place in the Swift compiler which uses a callback function so that LLDB can perform its progress report. This originally called into a function in `lldb_private::SwiftASTContext` but will instead use a lambda function to increment a locally created progress report. Related to: swiftlang/swift#69730 rdar://105286354
1 parent 7ec3fb1 commit 4106480

File tree

5 files changed

+78
-37
lines changed

5 files changed

+78
-37
lines changed

lldb/source/Core/Progress.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ Progress::~Progress() {
3030
// Make sure to always report progress completed when this object is
3131
// destructed so it indicates the progress dialog/activity should go away.
3232
std::lock_guard<std::mutex> guard(m_mutex);
33-
if (!m_completed) {
33+
if (!m_completed)
3434
m_completed = m_total;
35-
ReportProgress();
36-
}
35+
ReportProgress();
3736
}
3837

3938
void Progress::Increment(uint64_t amount, std::string update) {

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,18 +473,15 @@ void SwiftLanguageRuntimeImpl::ProcessModulesToAdd() {
473473

474474
auto &target = m_process.GetTarget();
475475
auto exe_module = target.GetExecutableModule();
476-
Progress progress(
477-
llvm::formatv("Setting up Swift reflection for '{0}'",
478-
exe_module->GetFileSpec().GetFilename().AsCString()),
479-
modules_to_add_snapshot.GetSize());
480-
476+
Progress progress("Setting up Swift reflection");
481477
size_t completion = 0;
482478

483479
// Add all defered modules to reflection context that were added to
484480
// the target since this SwiftLanguageRuntime was created.
485481
modules_to_add_snapshot.ForEach([&](const ModuleSP &module_sp) -> bool {
486482
AddModuleToReflectionContext(module_sp);
487-
progress.Increment(++completion);
483+
progress.Increment(++completion,
484+
module_sp->GetFileSpec().GetFilename().AsCString());
488485
return true;
489486
});
490487
}

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
120120
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
121121

122+
#include <memory>
122123
#include <mutex>
123124
#include <queue>
124125
#include <set>
@@ -2008,6 +2009,25 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
20082009
{
20092010
LLDB_SCOPED_TIMERF("%s (getStdlibModule)", m_description.c_str());
20102011
const bool can_create = true;
2012+
2013+
// Report progress on module importing by using a callback function in
2014+
// swift::ASTContext
2015+
Progress progress("Importing Swift standard library");
2016+
swift_ast_sp->m_ast_context_ap->SetPreModuleImportCallback(
2017+
[&progress](llvm::StringRef module_name, bool is_overlay) {
2018+
progress.Increment(1, (is_overlay ? module_name.str() + " (overlay)"
2019+
: module_name.str()));
2020+
});
2021+
2022+
// Clear the callback function on scope exit to prevent an out-of-scope
2023+
// access of the progress local variable
2024+
auto on_exit = llvm::make_scope_exit([&]() {
2025+
swift_ast_sp->m_ast_context_ap->SetPreModuleImportCallback(
2026+
[](llvm::StringRef module_name, bool is_overlay) {
2027+
Progress("Importing Swift modules");
2028+
});
2029+
});
2030+
20112031
swift::ModuleDecl *stdlib =
20122032
swift_ast_sp->m_ast_context_ap->getStdlibModule(can_create);
20132033
if (!stdlib || IsDWARFImported(*stdlib)) {
@@ -2499,6 +2519,25 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
24992519
{
25002520
LLDB_SCOPED_TIMERF("%s (getStdlibModule)", m_description.c_str());
25012521
const bool can_create = true;
2522+
2523+
// Report progress on module importing by using a callback function in
2524+
// swift::ASTContext
2525+
Progress progress("Importing Swift standard library");
2526+
swift_ast_sp->m_ast_context_ap->SetPreModuleImportCallback(
2527+
[&progress](llvm::StringRef module_name, bool is_overlay) {
2528+
progress.Increment(1, (is_overlay ? module_name.str() + " (overlay)"
2529+
: module_name.str()));
2530+
});
2531+
2532+
// Clear the callback function on scope exit to prevent an out-of-scope
2533+
// access of the progress local variable
2534+
auto on_exit = llvm::make_scope_exit([&]() {
2535+
swift_ast_sp->m_ast_context_ap->SetPreModuleImportCallback(
2536+
[](llvm::StringRef module_name, bool is_overlay) {
2537+
Progress("Importing Swift modules");
2538+
});
2539+
});
2540+
25022541
swift::ModuleDecl *stdlib =
25032542
swift_ast_sp->m_ast_context_ap->getStdlibModule(can_create);
25042543
if (!stdlib || IsDWARFImported(*stdlib)) {
@@ -3203,7 +3242,7 @@ swift::ASTContext *SwiftASTContext::GetASTContext() {
32033242
GetLanguageOptions(), GetTypeCheckerOptions(), GetSILOptions(),
32043243
GetSearchPathOptions(), GetClangImporterOptions(),
32053244
GetSymbolGraphOptions(), GetSourceManager(), GetDiagnosticEngine(),
3206-
/*OutputBackend=*/nullptr, ReportModuleLoadingProgress));
3245+
/*OutputBackend=*/nullptr));
32073246

32083247
if (getenv("LLDB_SWIFT_DUMP_DIAGS")) {
32093248
// NOTE: leaking a swift::PrintingDiagnosticConsumer() here, but
@@ -3486,15 +3525,6 @@ void SwiftASTContext::CacheModule(swift::ModuleDecl *module) {
34863525
m_swift_module_cache.insert({ID, module});
34873526
}
34883527

3489-
bool SwiftASTContext::ReportModuleLoadingProgress(llvm::StringRef module_name,
3490-
bool is_overlay) {
3491-
Progress progress(llvm::formatv(is_overlay ? "Importing overlay module {0}"
3492-
: "Importing module {0}",
3493-
module_name)
3494-
.str());
3495-
return true;
3496-
}
3497-
34983528
swift::ModuleDecl *SwiftASTContext::GetModule(const SourceModule &module,
34993529
Status &error, bool *cached) {
35003530
if (cached)
@@ -3545,6 +3575,24 @@ swift::ModuleDecl *SwiftASTContext::GetModule(const SourceModule &module,
35453575
// Create a diagnostic consumer for the diagnostics produced by the import.
35463576
auto import_diags = getScopedDiagnosticConsumer();
35473577

3578+
// Report progress on module importing by using a callback function in
3579+
// swift::ASTContext
3580+
Progress progress("Importing Swift modules");
3581+
ast->SetPreModuleImportCallback([&progress](llvm::StringRef module_name,
3582+
bool is_overlay) {
3583+
progress.Increment(
3584+
1, (is_overlay ? module_name.str() + " (overlay)" : module_name.str()));
3585+
});
3586+
3587+
// Clear the callback function on scope exit to prevent an out-of-scope access
3588+
// of the progress local variable
3589+
auto on_exit = llvm::make_scope_exit([&]() {
3590+
ast->SetPreModuleImportCallback(
3591+
[](llvm::StringRef module_name, bool is_overlay) {
3592+
Progress("Importing Swift modules");
3593+
});
3594+
});
3595+
35483596
// Perform the import.
35493597
swift::ModuleDecl *module_decl = ast->getModuleByName(module_basename_sref);
35503598

@@ -4152,10 +4200,9 @@ void SwiftASTContext::ValidateSectionModules(
41524200
Status error;
41534201

41544202
Progress progress(
4155-
llvm::formatv("Loading Swift module {0}",
4203+
llvm::formatv("Loading Swift module '{0}' dependencies",
41564204
module.GetFileSpec().GetFilename().AsCString()),
41574205
module_names.size());
4158-
41594206
size_t completion = 0;
41604207

41614208
for (const std::string &module_name : module_names) {
@@ -4164,7 +4211,7 @@ void SwiftASTContext::ValidateSectionModules(
41644211

41654212
// We have to increment the completion value even if we can't get the module
41664213
// object to stay in-sync with the total progress reporting.
4167-
progress.Increment(++completion);
4214+
progress.Increment(++completion, module_name);
41684215
if (!GetModule(module_info, error))
41694216
module.ReportWarning("unable to load swift module \"{0}\" ({1})",
41704217
module_name.c_str(), error.AsCString());
@@ -8596,10 +8643,7 @@ bool SwiftASTContextForExpressions::CacheUserImports(
85968643

85978644
auto src_file_imports = source_file.getImports();
85988645

8599-
Progress progress(llvm::formatv("Caching Swift user imports from '{0}'",
8600-
source_file.getFilename().data()),
8601-
src_file_imports.size());
8602-
8646+
Progress progress("Importing modules used in expression");
86038647
size_t completion = 0;
86048648

86058649
/// Find all explicit imports in the expression.
@@ -8617,7 +8661,9 @@ bool SwiftASTContextForExpressions::CacheUserImports(
86178661
source_file.walk(import_finder);
86188662

86198663
for (const auto &attributed_import : src_file_imports) {
8620-
progress.Increment(++completion);
8664+
progress.Increment(
8665+
++completion,
8666+
attributed_import.module.importedModule->getModuleFilename().str());
86218667
swift::ModuleDecl *module = attributed_import.module.importedModule;
86228668
if (module && import_finder.imports.count(module)) {
86238669
std::string module_name;
@@ -8737,10 +8783,9 @@ bool SwiftASTContext::GetCompileUnitImportsImpl(
87378783
llvm::formatv("Getting Swift compile unit imports for '{0}'",
87388784
compile_unit->GetPrimaryFile().GetFilename()),
87398785
cu_imports.size());
8740-
87418786
size_t completion = 0;
87428787
for (const SourceModule &module : cu_imports) {
8743-
progress.Increment(++completion);
8788+
progress.Increment(++completion, module.path.back().GetStringRef().str());
87448789
// When building the Swift stdlib with debug info these will
87458790
// show up in "Swift.o", but we already imported them and
87468791
// manually importing them will fail.

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,6 @@ class SwiftASTContext : public TypeSystemSwift {
298298
swift::ModuleDecl *CreateModule(const SourceModule &module, Status &error,
299299
swift::ImplicitImportInfo importInfo);
300300

301-
static bool ReportModuleLoadingProgress(llvm::StringRef module_name,
302-
bool is_overlay);
303-
304301
// This function should only be called when all search paths
305302
// for all items in a swift::ASTContext have been setup to
306303
// allow for imports to happen correctly. Use with caution,

lldb/test/API/functionalities/progress_reporting/swift_progress_reporting/TestSwiftProgressReporting.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ def test_swift_progress_report(self):
3737
self.runCmd("expr boo")
3838
self.runCmd("v s")
3939

40-
beacons = [ "Loading Swift module",
41-
"Caching Swift user imports from",
42-
"Setting up Swift reflection for",
43-
"Getting Swift compile unit imports for",
44-
"Importing module", "Importing overlay module"]
40+
beacons = [
41+
"Loading Swift module",
42+
"Importing modules used in expression",
43+
"Setting up Swift reflection",
44+
"Getting Swift compile unit imports for",
45+
"Importing Swift modules",
46+
"Importing Swift standard library",
47+
]
4548

4649
while len(beacons):
4750
event = lldbutil.fetch_next_event(self, self.listener, self.broadcaster)

0 commit comments

Comments
 (0)