diff options
| author | Lang Hames <lhames@gmail.com> | 2019-11-14 15:58:21 -0800 |
|---|---|---|
| committer | Lang Hames <lhames@gmail.com> | 2019-11-14 21:27:19 -0800 |
| commit | 16f38dda292c6e2963e77f722042a9eb5da56d28 (patch) | |
| tree | 412b958c6d721df8ad15a3b014872fc5c8d9292e /llvm/lib/ExecutionEngine/Orc | |
| parent | bc11830c6a67025186d39fd9de6e49b3b570e2bd (diff) | |
| download | bcm5719-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/ExecutionEngine/Orc')
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp | 68 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp | 16 |
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. |

