Skip to content

Commit c64ca9a

Browse files
authored
Merge pull request swiftlang#33301 from compnerd/jit-state-of-mind
Frontend: support dumping the JIT state
2 parents d3f132b + 8d21750 commit c64ca9a

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
139139
PointerAuthSchema ResilientClassStubInitCallbacks;
140140
};
141141

142+
enum class JITDebugArtifact : unsigned {
143+
None, ///< None
144+
LLVMIR, ///< LLVM IR
145+
Object, ///< Object File
146+
};
147+
142148
/// The set of options supported by IR generation.
143149
class IRGenOptions {
144150
public:
@@ -326,6 +332,8 @@ class IRGenOptions {
326332
Optional<llvm::VersionTuple> AutolinkRuntimeCompatibilityLibraryVersion;
327333
Optional<llvm::VersionTuple> AutolinkRuntimeCompatibilityDynamicReplacementLibraryVersion;
328334

335+
JITDebugArtifact DumpJIT = JITDebugArtifact::None;
336+
329337
IRGenOptions()
330338
: DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssembly),
331339
Verify(true), OptMode(OptimizationMode::NotSet),

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ def disable_llvm_verify : Flag<["-"], "disable-llvm-verify">,
329329
def disable_llvm_value_names : Flag<["-"], "disable-llvm-value-names">,
330330
HelpText<"Don't add names to local values in LLVM IR">;
331331

332+
def dump_jit : JoinedOrSeparate<["-"], "dump-jit">,
333+
HelpText<"Dump JIT contents">;
334+
332335
def enable_llvm_value_names : Flag<["-"], "enable-llvm-value-names">,
333336
HelpText<"Add names to local values in LLVM IR">;
334337

lib/Frontend/CompilerInvocation.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,9 +1448,23 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
14481448
if (Args.hasArg(OPT_disable_concrete_type_metadata_mangled_name_accessors))
14491449
Opts.DisableConcreteTypeMetadataMangledNameAccessors = true;
14501450

1451-
if (Args.hasArg(OPT_use_jit))
1451+
if (Args.hasArg(OPT_use_jit)) {
14521452
Opts.UseJIT = true;
1453-
1453+
if (const Arg *A = Args.getLastArg(OPT_dump_jit)) {
1454+
llvm::Optional<swift::JITDebugArtifact> artifact =
1455+
llvm::StringSwitch<llvm::Optional<swift::JITDebugArtifact>>(A->getValue())
1456+
.Case("llvm-ir", JITDebugArtifact::LLVMIR)
1457+
.Case("object", JITDebugArtifact::Object)
1458+
.Default(None);
1459+
if (!artifact) {
1460+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
1461+
A->getOption().getName(), A->getValue());
1462+
return true;
1463+
}
1464+
Opts.DumpJIT = *artifact;
1465+
}
1466+
}
1467+
14541468
for (const Arg *A : Args.filtered(OPT_verify_type_layout)) {
14551469
Opts.VerifyTypeLayoutNames.push_back(A->getValue());
14561470
}

lib/Immediate/Immediate.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/SILOptimizer/PassManager/Passes.h"
3131
#include "llvm/ADT/SmallString.h"
3232
#include "llvm/Config/config.h"
33+
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
3334
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
3435
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
3536
#include "llvm/IR/LLVMContext.h"
@@ -75,6 +76,18 @@ static void *loadRuntimeLib(StringRef sharedLibName,
7576
return nullptr;
7677
}
7778

79+
static void DumpLLVMIR(const llvm::Module &M) {
80+
std::string path = (M.getName() + ".ll").str();
81+
for (size_t count = 0; llvm::sys::fs::exists(path); )
82+
path = (M.getName() + llvm::utostr(count++) + ".ll").str();
83+
84+
std::error_code error;
85+
llvm::raw_fd_ostream stream(path, error);
86+
if (error)
87+
return;
88+
M.print(stream, /*AssemblyAnnotationWriter=*/nullptr);
89+
}
90+
7891
void *swift::immediate::loadSwiftRuntime(ArrayRef<std::string>
7992
runtimeLibPaths) {
8093
#if defined(_WIN32)
@@ -290,6 +303,18 @@ int swift::RunImmediately(CompilerInstance &CI,
290303
}
291304

292305
auto Module = GenModule.getModule();
306+
307+
switch (IRGenOpts.DumpJIT) {
308+
case JITDebugArtifact::None:
309+
break;
310+
case JITDebugArtifact::LLVMIR:
311+
DumpLLVMIR(*Module);
312+
break;
313+
case JITDebugArtifact::Object:
314+
JIT->getObjTransformLayer().setTransform(llvm::orc::DumpObjects());
315+
break;
316+
}
317+
293318
{
294319
// Get a generator for the process symbols and attach it to the main
295320
// JITDylib.

test/IRGen/jit-debugging.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// %empty-directory(%t)
2+
// RUN: not %target-swift-frontend -use-jit -dump-jit invalid -interpret %s 2>&1 | %FileCheck -check-prefix CHECK-INVALID %s
3+
// CHECK-INVALID: error: invalid value 'invalid' in 'dump-jit'
4+
5+
// RUN: %empty-directory(%t)
6+
// RUN: cd %t && %target-swift-frontend -use-jit -dump-jit llvm-ir -interpret %s
7+
// RUN: %FileCheck -check-prefix CHECK-LLIR %s < %t/main.ll
8+
// CHECK-LLIR: ; ModuleID = 'main'
9+
10+
// RUN: %empty-directory(%t)
11+
// RUN: cd %t && %target-swift-frontend -use-jit -dump-jit object -interpret %s
12+
// RUN: %llvm-nm --defined-only --extern-only %t/main-jitted-objectbuffer.o | %FileCheck -check-prefix CHECK-OBJ %s
13+
// CHECK-OBJ: T {{_?}}main
14+
15+
let zero = 0

0 commit comments

Comments
 (0)