Skip to content

[SIL][Frontend] Simplify debug info generation flow for SIL files #38167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ option(SWIFT_RUNTIME_CLOBBER_FREED_OBJECTS
"${SWIFT_RUNTIME_CLOBBER_FREED_OBJECTS_default}")

option(SWIFT_STDLIB_SIL_DEBUGGING
"Compile the Swift standard library with -gsil to enable debugging and profiling on SIL level"
"Compile the Swift standard library with -sil-based-debuginfo to enable debugging and profiling on SIL level"
FALSE)

option(SWIFT_CHECK_INCREMENTAL_COMPILATION
Expand Down
15 changes: 11 additions & 4 deletions docs/DebuggingTheCompiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ benefit of all Swift developers.
- [Getting CommandLine for swift stdlib from Ninja to enable dumping stdlib SIL](#getting-commandline-for-swift-stdlib-from-ninja-to-enable-dumping-stdlib-sil)
- [Dumping the SIL and other Data in LLDB](#dumping-the-sil-and-other-data-in-lldb)
- [Debugging and Profiling on SIL level](#debugging-and-profiling-on-sil-level)
- [SIL source level profiling using -gsil](#sil-source-level-profiling-using--gsil)
- [SIL source level profiling using -sil-based-debuginfo](#sil-source-level-profiling)
- [ViewCFG: Regex based CFG Printer for SIL/LLVM-IR](#viewcfg-regex-based-cfg-printer-for-silllvm-ir)
- [Debugging the Compiler using advanced LLDB Breakpoints](#debugging-the-compiler-using-advanced-lldb-breakpoints)
- [Debugging the Compiler using LLDB Scripts](#debugging-the-compiler-using-lldb-scripts)
Expand Down Expand Up @@ -101,6 +101,12 @@ swiftc -emit-sil -Onone file.swift
swiftc -emit-sil -O file.swift
```

* **Debug info in SIL** To print debug info from `file.swift` in SIL:

```sh
swiftc -g -emit-sil -O file.swift
```

* **IRGen** To print the LLVM IR after IR generation:

```sh
Expand Down Expand Up @@ -299,12 +305,13 @@ has a `dump()` method you can call.

## Debugging and Profiling on SIL level

### SIL source level profiling using -gsil
### SIL source level profiling

The compiler provides a way to debug and profile on SIL level. To enable SIL
debugging add the front-end option -gsil together with -g. Example:
debugging add the front-end option -sil-based-debuginfo together with -g.
Example:

swiftc -g -Xfrontend -gsil -O test.swift -o a.out
swiftc -g -Xfrontend -sil-based-debuginfo -O test.swift -o a.out

This writes the SIL after optimizations into a file and generates debug info
for it. In the debugger and profiler you can then see the SIL code instead of
Expand Down
6 changes: 5 additions & 1 deletion include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ class SILOptions {
/// Don't generate code using partial_apply in SIL generation.
bool DisableSILPartialApply = false;

/// The name of the SIL outputfile if compiled with SIL debugging (-gsil).
/// Print debug information into the SIL file
bool PrintDebugInfo = false;

/// The name of the SIL outputfile if compiled with SIL debugging
/// (-sil-based-debuginfo).
std::string SILOutputFileNameForDebugging;

/// If set to true, compile with the SIL Ownership Model enabled.
Expand Down
4 changes: 3 additions & 1 deletion include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -645,9 +645,11 @@ def print_inst_counts : Flag<["-"], "print-inst-counts">,
HelpText<"Before IRGen, count all the various SIL instructions. Must be used "
"in conjunction with -print-stats.">;

def debug_on_sil : Flag<["-"], "gsil">,
def debug_on_sil : Flag<["-"], "sil-based-debuginfo">,
HelpText<"Write the SIL into a file and generate debug-info to debug on SIL "
" level.">;
def legacy_gsil : Flag<["-"], "gsil">,
HelpText<"Deprecated, use '-sil-based-debuginfo' instead">;

def print_llvm_inline_tree : Flag<["-"], "print-llvm-inline-tree">,
HelpText<"Print the LLVM inline tree.">;
Expand Down
3 changes: 2 additions & 1 deletion include/swift/SIL/SILFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,8 @@ class SILFunction
DeclCtxt = (DS ? DebugScope->Loc.getAsDeclContext() : nullptr);
}

/// Initialize the debug scope for debug info on SIL level (-gsil).
/// Initialize the debug scope for debug info on SIL level
/// (-sil-based-debuginfo).
void setSILDebugScope(const SILDebugScope *DS) {
DebugScope = DS;
}
Expand Down
5 changes: 3 additions & 2 deletions include/swift/SIL/SILLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ class SILLocation {
/// Describes a position in a source file by explicitly storing the file name,
/// line and column.
///
/// This is used for parsed locations from a SIL file, for "-gsil" (see
/// SILDebugInfoGenerator) and for the "compiler-generated" singleton location.
/// This is used for parsed locations from a SIL file, for
/// "-sil-based-debuginfo" (see SILDebugInfoGenerator) and for the
/// "compiler-generated" singleton location.
/// In future we might also use it for de-serialized locations from a
/// swiftmodule file.
struct FilenameAndLocation : public SILAllocated<FilenameAndLocation> {
Expand Down
3 changes: 2 additions & 1 deletion include/swift/SIL/SILPrintContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class SILPrintContext {

/// Constructor based on SILOptions.
///
/// DebugInfo will be set according to the -sil-print-debuginfo option.
/// DebugInfo will be set according to SILOptions::PrintDebugInfo or
/// the -sil-print-debuginfo option.
SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts);

SILPrintContext(llvm::raw_ostream &OS, bool Verbose, bool SortedSIL,
Expand Down
11 changes: 11 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/WithColor.h"

using namespace swift;
using namespace llvm::opt;
Expand Down Expand Up @@ -1360,6 +1361,16 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
if (const Arg *A = Args.getLastArg(OPT_save_optimization_record_path))
Opts.OptRecordFile = A->getValue();

// If any of the '-g<kind>', except '-gnone', is given,
// tell the SILPrinter to print debug info as well
if (const Arg *A = Args.getLastArg(OPT_g_Group)) {
if (!A->getOption().matches(options::OPT_gnone))
Opts.PrintDebugInfo = true;
}

if (Args.hasArg(OPT_legacy_gsil))
llvm::WithColor::warning() << "'-gsil' is deprecated, "
<< "use '-sil-based-debuginfo' instead\n";
if (Args.hasArg(OPT_debug_on_sil)) {
// Derive the name of the SIL file for debugging from
// the regular outputfile.
Expand Down
3 changes: 2 additions & 1 deletion lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3637,7 +3637,8 @@ SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,

SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts)
: OutStream(OS), Verbose(Opts.EmitVerboseSIL),
SortedSIL(Opts.EmitSortedSIL), DebugInfo(SILPrintDebugInfo),
SortedSIL(Opts.EmitSortedSIL),
DebugInfo(Opts.PrintDebugInfo || SILPrintDebugInfo),
PrintFullConvention(Opts.PrintFullConvention) {}

SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
Expand Down
4 changes: 2 additions & 2 deletions lib/SILOptimizer/PassManager/PassPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ SILPassPipelinePlan::getPerformancePassPipeline(const SILOptions &Options) {

addLastChanceOptPassPipeline(P);

// Has only an effect if the -gsil option is specified.
// Has only an effect if the -sil-based-debuginfo option is specified.
addSILDebugInfoGeneratorPipeline(P);

// Call the CFG viewer.
Expand Down Expand Up @@ -883,7 +883,7 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
// Create pre-specializations.
P.addOnonePrespecializations();

// Has only an effect if the -gsil option is specified.
// Has only an effect if the -sil-based-debuginfo option is specified.
P.addSILDebugInfoGenerator();

return P;
Expand Down
8 changes: 4 additions & 4 deletions lib/SILOptimizer/UtilityPasses/SILDebugInfoGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "gsil-gen"
#define DEBUG_TYPE "sil-based-debuginfo-gen"
#include "swift/AST/SILOptions.h"
#include "swift/SIL/SILPrintContext.h"
#include "swift/SIL/SILModule.h"
Expand All @@ -25,12 +25,12 @@ namespace {
/// A pass for generating debug info on SIL level.
///
/// This pass is only enabled if SILOptions::SILOutputFileNameForDebugging is
/// set (i.e. if the -gsil command line option is specified).
/// set (i.e. if the -sil-based-debuginfo frontend option is specified).
/// The pass writes all SIL functions into one or multiple output files,
/// depending on the size of the SIL. The names of the output files are derived
/// from the main output file.
///
/// output file name = <main-output-filename>.gsil_<n>.sil
/// output file name = <main-output-filename>.sil_dbg_<n>.sil
///
/// Where <n> is a consecutive number. The files are stored in the same
/// same directory as the main output file.
Expand Down Expand Up @@ -104,7 +104,7 @@ class SILDebugInfoGenerator : public SILModuleTransform {

std::string FileName;
llvm::raw_string_ostream NameOS(FileName);
NameOS << FileBaseName << ".gsil_" << FileIdx++ << ".sil";
NameOS << FileBaseName << ".sil_dbg_" << FileIdx++ << ".sil";
NameOS.flush();

char *FileNameBuf = (char *)M->allocate(FileName.size() + 1, 1);
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ endif()
list(APPEND SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS "-Xfrontend" "-verify-syntax-tree")

if(SWIFT_STDLIB_SIL_DEBUGGING)
list(APPEND SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS "-Xfrontend" "-gsil")
list(APPEND SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS "-Xfrontend" "-sil-based-debuginfo")
endif()

# Build the runtime with -Wall to catch, e.g., uninitialized variables
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -O -gsil -Xllvm -sil-print-debuginfo -emit-ir -o %t/out.ir
// RUN: %target-swift-frontend %s -O -sil-based-debuginfo -Xllvm -sil-print-debuginfo -emit-ir -o %t/out.ir
// RUN: %FileCheck %s < %t/out.ir
// RUN: %FileCheck %s --check-prefix=CHECK_OUT_SIL < %t/out.ir.gsil_0.sil
// RUN: %FileCheck %s --check-prefix=CHECK_OUT_SIL < %t/out.ir.sil_dbg_0.sil

// Second test: check that we don't crash with multi-threaded IRGen
// RUN: %target-swift-frontend -c %s %S/Inputs/testclass.swift -wmo -O -num-threads 1 -gsil -o %t/gsil.o -o %t/testclass.o
// RUN: %target-swift-frontend -c %s %S/Inputs/testclass.swift -wmo -O -num-threads 1 -sil-based-debuginfo -o %t/sil_based_dbg.o -o %t/testclass.o

// CHECK: !DIFile(filename: "{{.+}}gsil.swift", directory: "{{.+}}")
// CHECK: [[F:![0-9]+]] = !DIFile(filename: "{{.+}}out.ir.gsil_0.sil",
// CHECK: !DIFile(filename: "{{.+}}sil_based_dbg.swift", directory: "{{.+}}")
// CHECK: [[F:![0-9]+]] = !DIFile(filename: "{{.+}}out.ir.sil_dbg_0.sil",
// CHECK: !DISubprogram(linkageName: "$s3out6testityyF", scope: !{{[0-9]+}}, file: [[F]], line: {{[1-9][0-9]+}},

// CHECK_OUT_SIL: sil @$s3out6testityyF : $@convention(thin) () -> () {
Expand Down
13 changes: 13 additions & 0 deletions test/Frontend/print-sil-debug-info.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Just a simple test to see whether debug info is printed to SIL
// if any of the '-g<kind>' (except '-gnone') is given.

// RUN: %target-swift-frontend -emit-sil -gnone %s | %FileCheck --check-prefix=CHECK-GNONE %s
// RUN: %target-swift-frontend -emit-sil -gline-tables-only %s | %FileCheck %s
// RUN: %target-swift-frontend -emit-sil -g %s | %FileCheck %s

func foo(x: Int, y: Int) -> Int {
// CHECK: struct_extract
// CHECK-SAME: loc "{{.*}}.swift":{{[0-9]+}}:{{[0-9]+}}, scope {{[0-9]+}}
// CHECK-GNONE-NOT: loc "{{.*}}.swift":{{[0-9]+}}:{{[0-9]+}}, scope {{[0-9]+}}
x + y
}
2 changes: 1 addition & 1 deletion test/SILOptimizer/outliner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public func testOutlining() {
// CHECK: %15 = function_ref @$sSS10FoundationE36_unconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ : $@convention(method) (@guaranteed Optional<NSString>, @thin String.Type) -> @owned String
// CHECK: %16 = metatype $@thin String.Type
// CHECK: %17 = apply %15(%9, %16) : $@convention(method) (@guaranteed Optional<NSString>, @thin String.Type) -> @owned String
// CHECK: release_value %9 : $Optional<NSString> // id: %18
// CHECK: release_value %9 : $Optional<NSString>
// CHECK: %19 = enum $Optional<String>, #Optional.some!enumelt, %17 : $String
// CHECK: br bb3(%19 : $Optional<String>)
//
Expand Down
2 changes: 1 addition & 1 deletion utils/build-script-impl
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ KNOWN_SETTINGS=(

## Build ...
build-llvm "1" "set to 1 to build LLVM and Clang"
build-sil-debugging-stdlib "0" "set to 1 to build the Swift standard library with -gsil to enable debugging and profiling on SIL level"
build-sil-debugging-stdlib "0" "set to 1 to build the Swift standard library with -sil-based-debuginfo to enable debugging and profiling on SIL level"
build-swift-dynamic-sdk-overlay "" "set to 1 to build dynamic variants of the Swift SDK overlay"
build-swift-dynamic-stdlib "" "set to 1 to build dynamic variants of the Swift standard library"
build-swift-examples "1" "set to 1 to build examples"
Expand Down