Files
clang-p2996/clang/lib/Interpreter/IncrementalExecutor.cpp
Stefan Gränitz 0cf4788d9d [clang-repl] Factor out CreateJITBuilder() and allow specialization in derived classes (#84461)
The LLJITBuilder interface provides a very convenient way to configure
the ORCv2 JIT engine. IncrementalExecutor already used it internally to
construct the JIT, but didn't provide external access. This patch lifts
control of the creation process to the Interpreter and allows injection
of a custom instance through the extended interface. The Interpreter's
default behavior remains unchanged and the IncrementalExecutor remains
an implementation detail.
2024-03-25 09:44:25 +01:00

120 lines
4.2 KiB
C++

//===--- IncrementalExecutor.cpp - Incremental Execution --------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the class which performs incremental code execution.
//
//===----------------------------------------------------------------------===//
#include "IncrementalExecutor.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Interpreter/PartialTranslationUnit.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TargetSelect.h"
// Force linking some of the runtimes that helps attaching to a debugger.
LLVM_ATTRIBUTE_USED void linkComponents() {
llvm::errs() << (void *)&llvm_orc_registerJITLoaderGDBWrapper
<< (void *)&llvm_orc_registerJITLoaderGDBAllocAction;
}
namespace clang {
llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
IncrementalExecutor::createDefaultJITBuilder(
llvm::orc::JITTargetMachineBuilder JTMB) {
auto JITBuilder = std::make_unique<llvm::orc::LLJITBuilder>();
JITBuilder->setJITTargetMachineBuilder(std::move(JTMB));
JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) {
// Try to enable debugging of JIT'd code (only works with JITLink for
// ELF and MachO).
consumeError(llvm::orc::enableDebuggerSupport(J));
return llvm::Error::success();
});
return std::move(JITBuilder);
}
IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
llvm::orc::LLJITBuilder &JITBuilder,
llvm::Error &Err)
: TSCtx(TSC) {
using namespace llvm::orc;
llvm::ErrorAsOutParameter EAO(&Err);
if (auto JitOrErr = JITBuilder.create())
Jit = std::move(*JitOrErr);
else {
Err = JitOrErr.takeError();
return;
}
}
IncrementalExecutor::~IncrementalExecutor() {}
llvm::Error IncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
llvm::orc::ResourceTrackerSP RT =
Jit->getMainJITDylib().createResourceTracker();
ResourceTrackers[&PTU] = RT;
return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx});
}
llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {
llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]);
if (!RT)
return llvm::Error::success();
ResourceTrackers.erase(&PTU);
if (llvm::Error Err = RT->remove())
return Err;
return llvm::Error::success();
}
// Clean up the JIT instance.
llvm::Error IncrementalExecutor::cleanUp() {
// This calls the global dtors of registered modules.
return Jit->deinitialize(Jit->getMainJITDylib());
}
llvm::Error IncrementalExecutor::runCtors() const {
return Jit->initialize(Jit->getMainJITDylib());
}
llvm::Expected<llvm::orc::ExecutorAddr>
IncrementalExecutor::getSymbolAddress(llvm::StringRef Name,
SymbolNameKind NameKind) const {
using namespace llvm::orc;
auto SO = makeJITDylibSearchOrder({&Jit->getMainJITDylib(),
Jit->getPlatformJITDylib().get(),
Jit->getProcessSymbolsJITDylib().get()});
ExecutionSession &ES = Jit->getExecutionSession();
auto SymOrErr =
ES.lookup(SO, (NameKind == LinkerName) ? ES.intern(Name)
: Jit->mangleAndIntern(Name));
if (auto Err = SymOrErr.takeError())
return std::move(Err);
return SymOrErr->getAddress();
}
} // end namespace clang