xref: /openbsd-src/gnu/llvm/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===------ CompileUtils.cpp - Utilities for compiling IR in the JIT ------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
909467b48Spatrick #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
1009467b48Spatrick 
1109467b48Spatrick #include "llvm/ADT/SmallVector.h"
1209467b48Spatrick #include "llvm/ExecutionEngine/ObjectCache.h"
1309467b48Spatrick #include "llvm/IR/LegacyPassManager.h"
1409467b48Spatrick #include "llvm/IR/Module.h"
15*d415bd75Srobert #include "llvm/MC/MCContext.h"
1609467b48Spatrick #include "llvm/Object/ObjectFile.h"
1709467b48Spatrick #include "llvm/Support/Error.h"
1809467b48Spatrick #include "llvm/Support/ErrorHandling.h"
1909467b48Spatrick #include "llvm/Support/MemoryBuffer.h"
2009467b48Spatrick #include "llvm/Support/SmallVectorMemoryBuffer.h"
2109467b48Spatrick #include "llvm/Target/TargetMachine.h"
2209467b48Spatrick 
2309467b48Spatrick #include <algorithm>
2409467b48Spatrick 
2509467b48Spatrick namespace llvm {
2609467b48Spatrick namespace orc {
2709467b48Spatrick 
28097a140dSpatrick IRSymbolMapper::ManglingOptions
irManglingOptionsFromTargetOptions(const TargetOptions & Opts)2909467b48Spatrick irManglingOptionsFromTargetOptions(const TargetOptions &Opts) {
30097a140dSpatrick   IRSymbolMapper::ManglingOptions MO;
3109467b48Spatrick 
3209467b48Spatrick   MO.EmulatedTLS = Opts.EmulatedTLS;
3309467b48Spatrick 
3409467b48Spatrick   return MO;
3509467b48Spatrick }
3609467b48Spatrick 
3709467b48Spatrick /// Compile a Module to an ObjectFile.
operator ()(Module & M)3809467b48Spatrick Expected<SimpleCompiler::CompileResult> SimpleCompiler::operator()(Module &M) {
3909467b48Spatrick   CompileResult CachedObject = tryToLoadFromObjectCache(M);
4009467b48Spatrick   if (CachedObject)
4109467b48Spatrick     return std::move(CachedObject);
4209467b48Spatrick 
4309467b48Spatrick   SmallVector<char, 0> ObjBufferSV;
4409467b48Spatrick 
4509467b48Spatrick   {
4609467b48Spatrick     raw_svector_ostream ObjStream(ObjBufferSV);
4709467b48Spatrick 
4809467b48Spatrick     legacy::PassManager PM;
4909467b48Spatrick     MCContext *Ctx;
5009467b48Spatrick     if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
5109467b48Spatrick       return make_error<StringError>("Target does not support MC emission",
5209467b48Spatrick                                      inconvertibleErrorCode());
5309467b48Spatrick     PM.run(M);
5409467b48Spatrick   }
5509467b48Spatrick 
5609467b48Spatrick   auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
57*d415bd75Srobert       std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer",
58*d415bd75Srobert       /*RequiresNullTerminator=*/false);
5909467b48Spatrick 
6009467b48Spatrick   auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
6109467b48Spatrick 
6209467b48Spatrick   if (!Obj)
6309467b48Spatrick     return Obj.takeError();
6409467b48Spatrick 
6509467b48Spatrick   notifyObjectCompiled(M, *ObjBuffer);
6609467b48Spatrick   return std::move(ObjBuffer);
6709467b48Spatrick }
6809467b48Spatrick 
6909467b48Spatrick SimpleCompiler::CompileResult
tryToLoadFromObjectCache(const Module & M)7009467b48Spatrick SimpleCompiler::tryToLoadFromObjectCache(const Module &M) {
7109467b48Spatrick   if (!ObjCache)
7209467b48Spatrick     return CompileResult();
7309467b48Spatrick 
7409467b48Spatrick   return ObjCache->getObject(&M);
7509467b48Spatrick }
7609467b48Spatrick 
notifyObjectCompiled(const Module & M,const MemoryBuffer & ObjBuffer)7709467b48Spatrick void SimpleCompiler::notifyObjectCompiled(const Module &M,
7809467b48Spatrick                                           const MemoryBuffer &ObjBuffer) {
7909467b48Spatrick   if (ObjCache)
8009467b48Spatrick     ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
8109467b48Spatrick }
8209467b48Spatrick 
ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,ObjectCache * ObjCache)8309467b48Spatrick ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,
8409467b48Spatrick                                            ObjectCache *ObjCache)
8509467b48Spatrick     : IRCompiler(irManglingOptionsFromTargetOptions(JTMB.getOptions())),
8609467b48Spatrick       JTMB(std::move(JTMB)), ObjCache(ObjCache) {}
8709467b48Spatrick 
8809467b48Spatrick Expected<std::unique_ptr<MemoryBuffer>>
operator ()(Module & M)8909467b48Spatrick ConcurrentIRCompiler::operator()(Module &M) {
9009467b48Spatrick   auto TM = cantFail(JTMB.createTargetMachine());
9109467b48Spatrick   SimpleCompiler C(*TM, ObjCache);
9209467b48Spatrick   return C(M);
9309467b48Spatrick }
9409467b48Spatrick 
9509467b48Spatrick } // end namespace orc
9609467b48Spatrick } // end namespace llvm
97