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 58 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 59 60 if (!Obj) 61 return Obj.takeError(); 62 63 notifyObjectCompiled(M, *ObjBuffer); 64 return std::move(ObjBuffer); 65 } 66 67 SimpleCompiler::CompileResult 68 SimpleCompiler::tryToLoadFromObjectCache(const Module &M) { 69 if (!ObjCache) 70 return CompileResult(); 71 72 return ObjCache->getObject(&M); 73 } 74 75 void SimpleCompiler::notifyObjectCompiled(const Module &M, 76 const MemoryBuffer &ObjBuffer) { 77 if (ObjCache) 78 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 79 } 80 81 ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, 82 ObjectCache *ObjCache) 83 : IRCompiler(irManglingOptionsFromTargetOptions(JTMB.getOptions())), 84 JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 85 86 Expected<std::unique_ptr<MemoryBuffer>> 87 ConcurrentIRCompiler::operator()(Module &M) { 88 auto TM = cantFail(JTMB.createTargetMachine()); 89 SimpleCompiler C(*TM, ObjCache); 90 return C(M); 91 } 92 93 } // end namespace orc 94 } // end namespace llvm 95