[llvm-branch-commits] [llvm] [llvm-exegesis] Switch from MCJIT to LLJIT (PR #72838)
Aiden Grossman via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 24 02:03:43 PST 2023
https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/72838
>From 9dfa6f5607ab945e2ba36da148c3669cdf723dc2 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Mon, 20 Nov 2023 00:42:01 -0800
Subject: [PATCH 1/2] [llvm-exegesis] Switch from MCJIT to LLJIT
This patch switches from using MCJIT to LLJIT as MCJIT is going to be
deprecated soon.
---
llvm/tools/llvm-exegesis/lib/Assembler.cpp | 77 ++++++++-------------
llvm/tools/llvm-exegesis/lib/Assembler.h | 7 +-
llvm/tools/llvm-exegesis/lib/CMakeLists.txt | 2 +-
3 files changed, 32 insertions(+), 54 deletions(-)
diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.cpp b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
index 9ff33258e965f7e..54ba29ed04c6f95 100644
--- a/llvm/tools/llvm-exegesis/lib/Assembler.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
@@ -21,11 +21,12 @@
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/Object/SymbolSize.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
@@ -105,7 +106,7 @@ MachineFunction &createVoidVoidPtrMachineFunction(StringRef FunctionName,
FunctionType *FunctionType =
FunctionType::get(ReturnType, {MemParamType}, false);
Function *const F = Function::Create(
- FunctionType, GlobalValue::InternalLinkage, FunctionName, Module);
+ FunctionType, GlobalValue::ExternalLinkage, FunctionName, Module);
BasicBlock *BB = BasicBlock::Create(Module->getContext(), "", F);
new UnreachableInst(Module->getContext(), BB);
return MMI->getOrCreateMachineFunction(*F);
@@ -324,66 +325,44 @@ object::OwningBinary<object::ObjectFile> getObjectFromFile(StringRef Filename) {
return cantFail(object::ObjectFile::createObjectFile(Filename));
}
-namespace {
-
-// Implementation of this class relies on the fact that a single object with a
-// single function will be loaded into memory.
-class TrackingSectionMemoryManager : public SectionMemoryManager {
-public:
- explicit TrackingSectionMemoryManager(uintptr_t *CodeSize)
- : CodeSize(CodeSize) {}
-
- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName) override {
- *CodeSize = Size;
- return SectionMemoryManager::allocateCodeSection(Size, Alignment, SectionID,
- SectionName);
- }
-
-private:
- uintptr_t *const CodeSize = nullptr;
-};
-
-} // namespace
-
Expected<ExecutableFunction> ExecutableFunction::create(
std::unique_ptr<LLVMTargetMachine> TM,
object::OwningBinary<object::ObjectFile> &&ObjectFileHolder) {
assert(ObjectFileHolder.getBinary() && "cannot create object file");
std::unique_ptr<LLVMContext> Ctx = std::make_unique<LLVMContext>();
- // Initializing the execution engine.
- // We need to use the JIT EngineKind to be able to add an object file.
- LLVMLinkInMCJIT();
- uintptr_t CodeSize = 0;
- std::string Error;
- std::unique_ptr<ExecutionEngine> EE(
- EngineBuilder(createModule(Ctx, TM->createDataLayout()))
- .setErrorStr(&Error)
- .setMCPU(TM->getTargetCPU())
- .setEngineKind(EngineKind::JIT)
- .setMCJITMemoryManager(
- std::make_unique<TrackingSectionMemoryManager>(&CodeSize))
- .create(TM.release()));
- if (!EE)
- return make_error<StringError>(Twine(Error), inconvertibleErrorCode());
- // Adding the generated object file containing the assembled function.
- // The ExecutionEngine makes sure the object file is copied into an
- // executable page.
- EE->addObjectFile(std::move(ObjectFileHolder));
- // Fetching function bytes.
- const uint64_t FunctionAddress = EE->getFunctionAddress(FunctionID);
+
+ auto SymbolSizes = object::computeSymbolSizes(*ObjectFileHolder.getBinary());
+ assert(SymbolSizes.size() == 3);
+ uintptr_t CodeSize = std::get<1>(SymbolSizes[2]);
+
+ auto EJITOrErr = orc::LLJITBuilder().create();
+ if (!EJITOrErr)
+ return EJITOrErr.takeError();
+
+ auto EJIT = std::move(*EJITOrErr);
+
+ if (auto ObjErr =
+ EJIT->addObjectFile(std::get<1>(ObjectFileHolder.takeBinary())))
+ return ObjErr;
+
+ auto FunctionAddressOrErr = EJIT->lookup(FunctionID);
+ if (!FunctionAddressOrErr)
+ return FunctionAddressOrErr.takeError();
+
+ const uint64_t FunctionAddress = FunctionAddressOrErr->getValue();
+
assert(isAligned(kFunctionAlignment, FunctionAddress) &&
"function is not properly aligned");
+
StringRef FBytes =
StringRef(reinterpret_cast<const char *>(FunctionAddress), CodeSize);
- return ExecutableFunction(std::move(Ctx), std::move(EE), FBytes);
+ return ExecutableFunction(std::move(Ctx), std::move(EJIT), FBytes);
}
ExecutableFunction::ExecutableFunction(std::unique_ptr<LLVMContext> Ctx,
- std::unique_ptr<ExecutionEngine> EE,
+ std::unique_ptr<orc::LLJIT> EJIT,
StringRef FB)
- : FunctionBytes(FB), Context(std::move(Ctx)), ExecEngine(std::move(EE)) {}
+ : FunctionBytes(FB), Context(std::move(Ctx)), ExecJIT(std::move(EJIT)) {}
Error getBenchmarkFunctionBytes(const StringRef InputData,
std::vector<uint8_t> &Bytes) {
diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.h b/llvm/tools/llvm-exegesis/lib/Assembler.h
index 5f1bf8cdfb7ad6c..abc5aa7be8cfeef 100644
--- a/llvm/tools/llvm-exegesis/lib/Assembler.h
+++ b/llvm/tools/llvm-exegesis/lib/Assembler.h
@@ -23,7 +23,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCInst.h"
@@ -124,11 +124,10 @@ class ExecutableFunction {
private:
ExecutableFunction(std::unique_ptr<LLVMContext> Ctx,
- std::unique_ptr<ExecutionEngine> EE,
- StringRef FunctionBytes);
+ std::unique_ptr<orc::LLJIT> EJIT, StringRef FunctionBytes);
std::unique_ptr<LLVMContext> Context;
- std::unique_ptr<ExecutionEngine> ExecEngine;
+ std::unique_ptr<orc::LLJIT> ExecJIT;
};
// Copies benchmark function's bytes from benchmark object.
diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
index 92135e6aaf673be..7312811989dd800 100644
--- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
+++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
@@ -29,10 +29,10 @@ set(LLVM_LINK_COMPONENTS
MC
MCA
MCDisassembler
- MCJIT
MCParser
Object
ObjectYAML
+ OrcJIT
RuntimeDyld
Support
TargetParser
>From 1408ee2eedd4af7cbf94d6e7570c0272e92a8846 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Fri, 24 Nov 2023 02:03:29 -0800
Subject: [PATCH 2/2] Assert symbol name, add comment about symbol naming
---
llvm/tools/llvm-exegesis/lib/Assembler.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.cpp b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
index 54ba29ed04c6f95..903ecbe47b8da0f 100644
--- a/llvm/tools/llvm-exegesis/lib/Assembler.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
@@ -332,7 +332,11 @@ Expected<ExecutableFunction> ExecutableFunction::create(
std::unique_ptr<LLVMContext> Ctx = std::make_unique<LLVMContext>();
auto SymbolSizes = object::computeSymbolSizes(*ObjectFileHolder.getBinary());
+ // Get the size of the function that we want to call into (with the name of
+ // FunctionID). This should always be the third symbol returned by
+ // calculateSymbolSizes.
assert(SymbolSizes.size() == 3);
+ assert(cantFail(std::get<0>(SymbolSizes[2]).getName()) == FunctionID);
uintptr_t CodeSize = std::get<1>(SymbolSizes[2]);
auto EJITOrErr = orc::LLJITBuilder().create();
More information about the llvm-branch-commits
mailing list