summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2019-11-14 15:58:21 -0800
committerLang Hames <lhames@gmail.com>2019-11-14 21:27:19 -0800
commit16f38dda292c6e2963e77f722042a9eb5da56d28 (patch)
tree412b958c6d721df8ad15a3b014872fc5c8d9292e /llvm/lib
parentbc11830c6a67025186d39fd9de6e49b3b570e2bd (diff)
downloadbcm5719-llvm-16f38dda292c6e2963e77f722042a9eb5da56d28.tar.gz
bcm5719-llvm-16f38dda292c6e2963e77f722042a9eb5da56d28.zip
[ORC] Add a utility to support dumping JIT'd objects to disk for debugging.
Adds a DumpObjects utility that can be used to dump JIT'd objects to disk. Instances of DebugObjects may be used by ObjectTransformLayer as no-op transforms. This patch also adds an ObjectTransformLayer to LLJIT and an example of how to use this utility to dump JIT'd objects in LLJIT.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/ExecutionEngine/Orc/CMakeLists.txt1
-rw-r--r--llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp3
-rw-r--r--llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp68
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LLJIT.cpp10
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp16
5 files changed, 86 insertions, 12 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
index e615fd8f234..4a18f884744 100644
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -2,6 +2,7 @@ add_llvm_library(LLVMOrcJIT
CompileOnDemandLayer.cpp
CompileUtils.cpp
Core.cpp
+ DebugUtils.cpp
ExecutionUtils.cpp
IndirectionUtils.cpp
IRCompileLayer.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
index f8251627a4e..f5671d90420 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
@@ -43,8 +43,7 @@ SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) {
}
auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
- std::move(ObjBufferSV),
- "<in memory object compiled from " + M.getModuleIdentifier() + ">");
+ std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer");
auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
diff --git a/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp b/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp
new file mode 100644
index 00000000000..4e573dad118
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp
@@ -0,0 +1,68 @@
+//===---------- DebugUtils.cpp - Utilities for debugging ORC JITs ---------===//
+//
+// 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/DebugUtils.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define DEBUG_TYPE "orc"
+
+namespace llvm {
+namespace orc {
+
+DumpObjects::DumpObjects(std::string DumpDir, std::string IdentifierOverride)
+ : DumpDir(std::move(DumpDir)),
+ IdentifierOverride(std::move(IdentifierOverride)) {
+
+ /// Discard any trailing separators.
+ while (!this->DumpDir.empty() &&
+ sys::path::is_separator(this->DumpDir.back()))
+ this->DumpDir.pop_back();
+}
+
+Expected<std::unique_ptr<MemoryBuffer>>
+DumpObjects::operator()(std::unique_ptr<MemoryBuffer> Obj) {
+ size_t Idx = 1;
+
+ std::string DumpPathStem;
+ raw_string_ostream(DumpPathStem)
+ << DumpDir << (DumpDir.empty() ? "" : "/") << getBufferIdentifier(*Obj);
+
+ std::string DumpPath = DumpPathStem + ".o";
+ while (sys::fs::exists(DumpPath)) {
+ DumpPath.clear();
+ raw_string_ostream(DumpPath) << DumpPathStem << "." << (++Idx) << ".o";
+ }
+
+ LLVM_DEBUG({
+ dbgs() << "Dumping object buffer [ " << (void *)Obj->getBufferStart()
+ << " -- " << (void *)(Obj->getBufferEnd() - 1) << " ] to "
+ << DumpPath << "\n";
+ });
+
+ std::error_code EC;
+ raw_fd_ostream DumpStream(DumpPath, EC);
+ if (EC)
+ return errorCodeToError(EC);
+ DumpStream.write(Obj->getBufferStart(), Obj->getBufferSize());
+
+ return Obj;
+}
+
+StringRef DumpObjects::getBufferIdentifier(MemoryBuffer &B) {
+ if (!IdentifierOverride.empty())
+ return IdentifierOverride;
+ StringRef Identifier = B.getBufferIdentifier();
+ Identifier.consume_back(".o");
+ return Identifier;
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index a80f78afe80..03f22e0c2a2 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -51,7 +51,7 @@ Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
assert(Obj && "Can not add null object");
- return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
+ return ObjTransformLayer.add(JD, std::move(Obj), ES->allocateVModule());
}
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
@@ -103,13 +103,13 @@ LLJIT::createCompileFunction(LLJITBuilderState &S,
LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
: ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()),
- Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main),
+ Main(this->ES->getMainJITDylib()), DL(""),
+ ObjLinkingLayer(createObjectLinkingLayer(S, *ES)),
+ ObjTransformLayer(*this->ES, *ObjLinkingLayer), CtorRunner(Main),
DtorRunner(Main) {
ErrorAsOutParameter _(&Err);
- ObjLinkingLayer = createObjectLinkingLayer(S, *ES);
-
if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
DL = std::move(*DLOrErr);
else {
@@ -124,7 +124,7 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
return;
}
CompileLayer = std::make_unique<IRCompileLayer>(
- *ES, *ObjLinkingLayer, std::move(*CompileFunction));
+ *ES, ObjTransformLayer, std::move(*CompileFunction));
}
if (S.NumCompileThreads > 0) {
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
index 815517321b7..d18eb38a414 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
@@ -21,12 +21,18 @@ void ObjectTransformLayer::emit(MaterializationResponsibility R,
std::unique_ptr<MemoryBuffer> O) {
assert(O && "Module must not be null");
- if (auto TransformedObj = Transform(std::move(O)))
- BaseLayer.emit(std::move(R), std::move(*TransformedObj));
- else {
- R.failMaterialization();
- getExecutionSession().reportError(TransformedObj.takeError());
+ // If there is a transform set then apply it.
+ if (Transform) {
+ if (auto TransformedObj = Transform(std::move(O)))
+ O = std::move(*TransformedObj);
+ else {
+ R.failMaterialization();
+ getExecutionSession().reportError(TransformedObj.takeError());
+ return;
+ }
}
+
+ BaseLayer.emit(std::move(R), std::move(O));
}
} // End namespace orc.
OpenPOWER on IntegriCloud