14637e158SLang Hames //===------ CompileUtils.cpp - Utilities for compiling IR in the JIT ------===//
24637e158SLang Hames //
34637e158SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44637e158SLang Hames // See https://llvm.org/LICENSE.txt for license information.
54637e158SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64637e158SLang Hames //
74637e158SLang Hames //===----------------------------------------------------------------------===//
84637e158SLang Hames
94637e158SLang Hames #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
104637e158SLang Hames
114637e158SLang Hames #include "llvm/ADT/SmallVector.h"
124637e158SLang Hames #include "llvm/ExecutionEngine/ObjectCache.h"
134637e158SLang Hames #include "llvm/IR/LegacyPassManager.h"
144637e158SLang Hames #include "llvm/IR/Module.h"
15*d4bcb45dSJez Ng #include "llvm/MC/MCContext.h"
164637e158SLang Hames #include "llvm/Object/ObjectFile.h"
174637e158SLang Hames #include "llvm/Support/Error.h"
184637e158SLang Hames #include "llvm/Support/ErrorHandling.h"
194637e158SLang Hames #include "llvm/Support/MemoryBuffer.h"
204637e158SLang Hames #include "llvm/Support/SmallVectorMemoryBuffer.h"
214637e158SLang Hames #include "llvm/Target/TargetMachine.h"
224637e158SLang Hames
234637e158SLang Hames #include <algorithm>
244637e158SLang Hames
254637e158SLang Hames namespace llvm {
264637e158SLang Hames namespace orc {
274637e158SLang Hames
2885fb9976SLang Hames IRSymbolMapper::ManglingOptions
irManglingOptionsFromTargetOptions(const TargetOptions & Opts)29ce2207abSLang Hames irManglingOptionsFromTargetOptions(const TargetOptions &Opts) {
3085fb9976SLang Hames IRSymbolMapper::ManglingOptions MO;
31ce2207abSLang Hames
32ce2207abSLang Hames MO.EmulatedTLS = Opts.EmulatedTLS;
33ce2207abSLang Hames
34ce2207abSLang Hames return MO;
35ce2207abSLang Hames }
36ce2207abSLang Hames
374637e158SLang Hames /// Compile a Module to an ObjectFile.
operator ()(Module & M)38ce2207abSLang Hames Expected<SimpleCompiler::CompileResult> SimpleCompiler::operator()(Module &M) {
394637e158SLang Hames CompileResult CachedObject = tryToLoadFromObjectCache(M);
404637e158SLang Hames if (CachedObject)
41c55cf4afSBill Wendling return std::move(CachedObject);
424637e158SLang Hames
434637e158SLang Hames SmallVector<char, 0> ObjBufferSV;
444637e158SLang Hames
454637e158SLang Hames {
464637e158SLang Hames raw_svector_ostream ObjStream(ObjBufferSV);
474637e158SLang Hames
484637e158SLang Hames legacy::PassManager PM;
494637e158SLang Hames MCContext *Ctx;
504637e158SLang Hames if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
51ce2207abSLang Hames return make_error<StringError>("Target does not support MC emission",
52ce2207abSLang Hames inconvertibleErrorCode());
534637e158SLang Hames PM.run(M);
544637e158SLang Hames }
554637e158SLang Hames
560eaee545SJonas Devlieghere auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
57d0262c23SJan Svoboda std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer",
58d0262c23SJan Svoboda /*RequiresNullTerminator=*/false);
594637e158SLang Hames
604637e158SLang Hames auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
614637e158SLang Hames
62ce2207abSLang Hames if (!Obj)
63ce2207abSLang Hames return Obj.takeError();
64ce2207abSLang Hames
654637e158SLang Hames notifyObjectCompiled(M, *ObjBuffer);
66c55cf4afSBill Wendling return std::move(ObjBuffer);
674637e158SLang Hames }
684637e158SLang Hames
694637e158SLang Hames SimpleCompiler::CompileResult
tryToLoadFromObjectCache(const Module & M)704637e158SLang Hames SimpleCompiler::tryToLoadFromObjectCache(const Module &M) {
714637e158SLang Hames if (!ObjCache)
724637e158SLang Hames return CompileResult();
734637e158SLang Hames
744637e158SLang Hames return ObjCache->getObject(&M);
754637e158SLang Hames }
764637e158SLang Hames
notifyObjectCompiled(const Module & M,const MemoryBuffer & ObjBuffer)774637e158SLang Hames void SimpleCompiler::notifyObjectCompiled(const Module &M,
784637e158SLang Hames const MemoryBuffer &ObjBuffer) {
794637e158SLang Hames if (ObjCache)
804637e158SLang Hames ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
814637e158SLang Hames }
824637e158SLang Hames
ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,ObjectCache * ObjCache)834637e158SLang Hames ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,
844637e158SLang Hames ObjectCache *ObjCache)
85ce2207abSLang Hames : IRCompiler(irManglingOptionsFromTargetOptions(JTMB.getOptions())),
86ce2207abSLang Hames JTMB(std::move(JTMB)), ObjCache(ObjCache) {}
874637e158SLang Hames
88ce2207abSLang Hames Expected<std::unique_ptr<MemoryBuffer>>
operator ()(Module & M)89ce2207abSLang Hames ConcurrentIRCompiler::operator()(Module &M) {
904637e158SLang Hames auto TM = cantFail(JTMB.createTargetMachine());
914637e158SLang Hames SimpleCompiler C(*TM, ObjCache);
924637e158SLang Hames return C(M);
934637e158SLang Hames }
944637e158SLang Hames
954637e158SLang Hames } // end namespace orc
964637e158SLang Hames } // end namespace llvm
97