1 //===------ CompileUtils.cpp - Utilities for compiling IR in the JIT ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 10 11 #include "llvm/ADT/SmallVector.h" 12 #include "llvm/ExecutionEngine/ObjectCache.h" 13 #include "llvm/IR/LegacyPassManager.h" 14 #include "llvm/IR/Module.h" 15 #include "llvm/Object/ObjectFile.h" 16 #include "llvm/Support/Error.h" 17 #include "llvm/Support/ErrorHandling.h" 18 #include "llvm/Support/MemoryBuffer.h" 19 #include "llvm/Support/SmallVectorMemoryBuffer.h" 20 #include "llvm/Target/TargetMachine.h" 21 22 #include <algorithm> 23 24 namespace llvm { 25 namespace orc { 26 27 IRSymbolMapper::ManglingOptions 28 irManglingOptionsFromTargetOptions(const TargetOptions &Opts) { 29 IRSymbolMapper::ManglingOptions MO; 30 31 MO.EmulatedTLS = Opts.EmulatedTLS; 32 33 return MO; 34 } 35 36 /// Compile a Module to an ObjectFile. 37 Expected<SimpleCompiler::CompileResult> SimpleCompiler::operator()(Module &M) { 38 CompileResult CachedObject = tryToLoadFromObjectCache(M); 39 if (CachedObject) 40 return std::move(CachedObject); 41 42 SmallVector<char, 0> ObjBufferSV; 43 44 { 45 raw_svector_ostream ObjStream(ObjBufferSV); 46 47 legacy::PassManager PM; 48 MCContext *Ctx; 49 if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) 50 return make_error<StringError>("Target does not support MC emission", 51 inconvertibleErrorCode()); 52 PM.run(M); 53 } 54 55 auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>( 56 std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer", 57 /*RequiresNullTerminator=*/false); 58 59 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 60 61 if (!Obj) 62 return Obj.takeError(); 63 64 notifyObjectCompiled(M, *ObjBuffer); 65 return std::move(ObjBuffer); 66 } 67 68 SimpleCompiler::CompileResult 69 SimpleCompiler::tryToLoadFromObjectCache(const Module &M) { 70 if (!ObjCache) 71 return CompileResult(); 72 73 return ObjCache->getObject(&M); 74 } 75 76 void SimpleCompiler::notifyObjectCompiled(const Module &M, 77 const MemoryBuffer &ObjBuffer) { 78 if (ObjCache) 79 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 80 } 81 82 ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, 83 ObjectCache *ObjCache) 84 : IRCompiler(irManglingOptionsFromTargetOptions(JTMB.getOptions())), 85 JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 86 87 Expected<std::unique_ptr<MemoryBuffer>> 88 ConcurrentIRCompiler::operator()(Module &M) { 89 auto TM = cantFail(JTMB.createTargetMachine()); 90 SimpleCompiler C(*TM, ObjCache); 91 return C(M); 92 } 93 94 } // end namespace orc 95 } // end namespace llvm 96