How to debug the LLVM-IR generation phase in the compiler?

I need to debug the generation from SIL to LLVM-IR (specifically, IRGenSIL.cpp), however, debugging swiftc doesn't work (I'm assuming because the executable that generates the IR is launched as a subprocess).

I tried emiting SIL and debugging sil-llvm-gen. This works, but it looks like it does some extra transformations on SIL before emitting the LLVM-IR, which makes the overall LLVM-IR different from what I get from running just emit-ir on swiftc.

Also, I'm on Linux, and --waitfor isn't implemented on LLDB yet.

Any help would be appreciated!

I don't think there are any additional processes being created. (You can check this with strace on Linux or dtruss on macOS; I don't see any fork/exec calls on macOS.)

From what I can tell, the code in IRGenSIL.cpp is primarily accessed through the IRGenSILFunction type. I suspect what is happening is that the compiler is not reaching the end of IRGenModule::emitSILFunction, which seems to be the only place that type is created. Maybe you need to tweak your example somehow? I don't know much about this file, but one way to figure out what exercises that code path would be to add a fatal error in IRGenSILFunction::emitSILFunction() and run the test suite without rebuilding the stdlib and examine the smallest test case which fell over.

/// Emit the definition for the given SIL constant.
void IRGenModule::emitSILFunction(SILFunction *f) {
  if (f->isExternalDeclaration())
    return;

  // Do not emit bodies of public_external functions.
  if (hasPublicVisibility(f->getLinkage()) && f->isAvailableExternally())
    return;

  PrettyStackTraceSILFunction stackTrace("emitting IR", f);
  IRGenSILFunction(*this, f).emitSILFunction();
}

Is passing '-###' to swiftc a supported way to list command invocations? I can't find a reference to this behavior in swift/docs, but I thought to try because clang happens to behave this way.

When I tried this out on Augusto's example, I got:

% ./bin/swiftc /tmp/t.swift -o - -g -emit-ir '-###'
/Users/vsk/src/github-swift-main/build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/bin/swift-frontend -frontend -emit-ir -primary-file /tmp/t.swift -target x86_64-apple-darwin19.6.0 -enable-objc-interop -color-diagnostics -g -enable-anonymous-context-mangled-names -module-name main -o -

It's possible to break within emitSILFunction when running the listed swift-frontend invocation under lldb.

Hi @typesanitizer, thank you for the answer!

To confirm that IRGen was being called, I added a print statement in IRGenModule::emitSILFunction, and added a breakpoint on top of it. The prints were working but the debugger still wouldn't break. I called the swift-frontend invocation directly as Vedant suggested and that works.