Skip to content

Commit

Permalink
[ORC][LLJIT] Move enable-debugger-support utility out of LLJITBuilder.
Browse files Browse the repository at this point in the history
This change means that debugger support only needs to be linked in if it's
used. The code size of debugger support is expected to increase as we improve
it (e.g. pulling in DWARF parsing), so making it an optional extra is useful
for controlling final binary sizes.
  • Loading branch information
lhames committed Sep 22, 2023
1 parent ab78962 commit e1a5bb5
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 75 deletions.
10 changes: 8 additions & 2 deletions clang/lib/Interpreter/IncrementalExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/Interpreter/PartialTranslationUnit.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/DebuggerSupport.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
Expand Down Expand Up @@ -46,8 +47,13 @@ IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
JTMB.addFeatures(TI.getTargetOpts().Features);
LLJITBuilder Builder;
Builder.setJITTargetMachineBuilder(JTMB);
// Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).
Builder.setEnableDebuggerSupport(true);
Builder.setPrePlatformSetup(
[](LLJIT &J) {
// Try to enable debugging of JIT'd code (only works with JITLink for
// ELF and MachO).
consumeError(enableDebuggerSupport(J));
return llvm::Error::success();
});

if (auto JitOrErr = Builder.create())
Jit = std::move(*JitOrErr);
Expand Down
4 changes: 1 addition & 3 deletions clang/tools/clang-repl/ClangRepl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,7 @@ int main(int argc, const char **argv) {
llvm::InitializeAllAsmPrinters();

if (OptHostSupportsJit) {
auto J = llvm::orc::LLJITBuilder()
.setEnableDebuggerSupport(true)
.create();
auto J = llvm::orc::LLJITBuilder().create();
if (J)
llvm::outs() << "true\n";
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ TEST(InterpreterTest, CatchException) {
llvm::InitializeNativeTargetAsmPrinter();

{
auto J = llvm::orc::LLJITBuilder()
.setEnableDebuggerSupport(true)
.create();
auto J = llvm::orc::LLJITBuilder().create();
if (!J) {
// The platform does not support JITs.
// Using llvm::consumeError will require typeinfo for ErrorInfoBase, we
Expand Down
4 changes: 1 addition & 3 deletions clang/unittests/Interpreter/InterpreterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ static std::string MangleName(NamedDecl *ND) {
}

static bool HostSupportsJit() {
auto J = llvm::orc::LLJITBuilder()
.setEnableDebuggerSupport(true)
.create();
auto J = llvm::orc::LLJITBuilder().create();
if (J)
return true;
LLVMConsumeError(llvm::wrap(J.takeError()));
Expand Down
28 changes: 28 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/DebuggerSupport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- DebugerSupport.h - Utils for enabling debugger support --*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Utilities for enabling debugger support.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_DEBUGGERSUPPORT_H
#define LLVM_EXECUTIONENGINE_ORC_DEBUGGERSUPPORT_H

#include "llvm/Support/Error.h"

namespace llvm {
namespace orc {

class LLJIT;

Error enableDebuggerSupport(LLJIT &J);

} // namespace orc
} // namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_DEBUGGERSUPPORT_H
7 changes: 0 additions & 7 deletions llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ class LLJITBuilderState {
unique_function<Error(LLJIT &)> PrePlatformSetup;
PlatformSetupFunction SetUpPlatform;
unsigned NumCompileThreads = 0;
bool EnableDebuggerSupport = false;

/// Called prior to JIT class construcion to fix up defaults.
Error prepareForConstruction();
Expand Down Expand Up @@ -455,12 +454,6 @@ class LLJITBuilderSetters {
return impl();
}

/// Enable / disable debugger support (off by default).
SetterImpl &setEnableDebuggerSupport(bool EnableDebuggerSupport) {
impl().EnableDebuggerSupport = EnableDebuggerSupport;
return impl();
}

/// Set an ExecutorProcessControl object.
///
/// If the platform uses ObjectLinkingLayer by default and no
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_llvm_component_library(LLVMOrcJIT
CompileUtils.cpp
Core.cpp
DebugObjectManagerPlugin.cpp
DebuggerSupport.cpp
DebuggerSupportPlugin.cpp
DebugUtils.cpp
EPCDynamicLibrarySearchGenerator.cpp
Expand Down
61 changes: 61 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/DebuggerSupport.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===------ DebuggerSupport.cpp - Utils for enabling debugger support -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/DebuggerSupport.h"
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"

#define DEBUG_TYPE "orc"

using namespace llvm;
using namespace llvm::orc;

namespace llvm::orc {

Error enableDebuggerSupport(LLJIT &J) {
auto *ObjLinkingLayer = dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer());
if (!ObjLinkingLayer)
return make_error<StringError>("Cannot enable LLJIT debugger support: "
"Debugger support requires JITLink",
inconvertibleErrorCode());
auto ProcessSymsJD = J.getProcessSymbolsJITDylib();
if (!ProcessSymsJD)
return make_error<StringError>("Cannot enable LLJIT debugger support: "
"Process symbols are not available",
inconvertibleErrorCode());

auto &ES = J.getExecutionSession();
const auto &TT = J.getTargetTriple();

switch (TT.getObjectFormat()) {
case Triple::ELF: {
auto Registrar = createJITLoaderGDBRegistrar(ES);
if (!Registrar)
return Registrar.takeError();
ObjLinkingLayer->addPlugin(std::make_unique<DebugObjectManagerPlugin>(
ES, std::move(*Registrar), true, true));
return Error::success();
}
case Triple::MachO: {
auto DS = GDBJITDebugInfoRegistrationPlugin::Create(ES, *ProcessSymsJD, TT);
if (!DS)
return DS.takeError();
ObjLinkingLayer->addPlugin(std::move(*DS));
return Error::success();
}
default:
return make_error<StringError>(
"Cannot enable LLJIT debugger support: " +
Triple::getObjectFormatTypeName(TT.getObjectFormat()) +
" is not supported",
inconvertibleErrorCode());
}
}

} // namespace llvm::orc
56 changes: 2 additions & 54 deletions llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
Expand Down Expand Up @@ -781,18 +779,8 @@ Error LLJITBuilderState::prepareForConstruction() {

// If we need a process JITDylib but no setup function has been given then
// create a default one.
if (!SetupProcessSymbolsJITDylib &&
(LinkProcessSymbolsByDefault || EnableDebuggerSupport)) {

LLVM_DEBUG({
dbgs() << "Creating default Process JD setup function (neeeded for";
if (LinkProcessSymbolsByDefault)
dbgs() << " <link-process-syms-by-default>";
if (EnableDebuggerSupport)
dbgs() << " <debugger-support>";
dbgs() << ")\n";
});

if (!SetupProcessSymbolsJITDylib && LinkProcessSymbolsByDefault) {
LLVM_DEBUG(dbgs() << "Creating default Process JD setup function\n");
SetupProcessSymbolsJITDylib = [this](LLJIT &J) -> Expected<JITDylibSP> {
auto &JD =
J.getExecutionSession().createBareJITDylib("<Process Symbols>");
Expand Down Expand Up @@ -1014,46 +1002,6 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
}
}

if (S.EnableDebuggerSupport) {
if (auto *OLL = dyn_cast<ObjectLinkingLayer>(ObjLinkingLayer.get())) {
switch (TT.getObjectFormat()) {
case Triple::ELF: {
auto Registrar = createJITLoaderGDBRegistrar(*ES);
if (!Registrar) {
Err = Registrar.takeError();
return;
}
OLL->addPlugin(std::make_unique<DebugObjectManagerPlugin>(
*ES, std::move(*Registrar), true, true));
break;
}
case Triple::MachO: {
assert(ProcessSymbols && "ProcessSymbols JD should be available when "
"EnableDebuggerSupport is set");
auto DS =
GDBJITDebugInfoRegistrationPlugin::Create(*ES, *ProcessSymbols, TT);
if (!DS) {
Err = DS.takeError();
return;
}
OLL->addPlugin(std::move(*DS));
break;
}
default:
LLVM_DEBUG({
dbgs() << "Cannot enable LLJIT debugger support: "
<< Triple::getObjectFormatTypeName(TT.getObjectFormat())
<< " not supported.\n";
});
}
} else {
LLVM_DEBUG({
dbgs() << "Cannot enable LLJIT debugger support: "
" debugger support is only available when using JITLink.\n";
});
}
}

if (S.PrePlatformSetup) {
if (auto Err2 = S.PrePlatformSetup(*this)) {
Err = std::move(Err2);
Expand Down
18 changes: 15 additions & 3 deletions llvm/tools/lli/lli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/DebuggerSupport.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
Expand Down Expand Up @@ -844,6 +845,17 @@ int mingw_noop_main(void) {
return 0;
}

// Try to enable debugger support for the given instance.
// This alway returns success, but prints a warning if it's not able to enable
// debugger support.
Error tryEnableDebugSupport(orc::LLJIT &J) {
if (auto Err = enableDebuggerSupport(J)) {
[[maybe_unused]] std::string ErrMsg = toString(std::move(Err));
LLVM_DEBUG(dbgs() << "lli: " << ErrMsg << "\n");
}
return Error::success();
}

int runOrcJIT(const char *ProgName) {
// Start setting up the JIT environment.

Expand Down Expand Up @@ -924,6 +936,9 @@ int runOrcJIT(const char *ProgName) {
});
}

// Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).
Builder.setPrePlatformSetup(tryEnableDebugSupport);

// Set up LLJIT platform.
LLJITPlatform P = Platform;
if (P == LLJITPlatform::Auto)
Expand Down Expand Up @@ -960,9 +975,6 @@ int runOrcJIT(const char *ProgName) {
});
}

// Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).
Builder.setEnableDebuggerSupport(true);

auto J = ExitOnErr(Builder.create());

auto *ObjLayer = &J->getObjLinkingLayer();
Expand Down

2 comments on commit e1a5bb5

@vitalybuka
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lhames
Some of your recent patches breaks https://lab.llvm.org/buildbot/#/builders/168/builds/15831

Not sure if it works fixing, or just disable these tests with asan/hwasan

@lhames
Copy link
Contributor Author

@lhames lhames commented on e1a5bb5 Sep 23, 2023 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.