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/MC/MCContext.h" 16 #include "llvm/Object/ObjectFile.h" 17 #include "llvm/Support/Error.h" 18 #include "llvm/Support/MemoryBuffer.h" 19 #include "llvm/Support/SmallVectorMemoryBuffer.h" 20 #include "llvm/Target/TargetMachine.h" 21 22 namespace llvm { 23 namespace orc { 24 25 IRSymbolMapper::ManglingOptions 26 irManglingOptionsFromTargetOptions(const TargetOptions &Opts) { 27 IRSymbolMapper::ManglingOptions MO; 28 29 MO.EmulatedTLS = Opts.EmulatedTLS; 30 31 return MO; 32 } 33 34 /// Compile a Module to an ObjectFile. 35 Expected<SimpleCompiler::CompileResult> SimpleCompiler::operator()(Module &M) { 36 CompileResult CachedObject = tryToLoadFromObjectCache(M); 37 if (CachedObject) 38 return std::move(CachedObject); 39 40 SmallVector<char, 0> ObjBufferSV; 41 42 { 43 raw_svector_ostream ObjStream(ObjBufferSV); 44 45 legacy::PassManager PM; 46 MCContext *Ctx; 47 if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) 48 return make_error<StringError>("Target does not support MC emission", 49 inconvertibleErrorCode()); 50 PM.run(M); 51 } 52 53 auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>( 54 std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer", 55 /*RequiresNullTerminator=*/false); 56 57 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 58 59 if (!Obj) 60 return Obj.takeError(); 61 62 notifyObjectCompiled(M, *ObjBuffer); 63 return std::move(ObjBuffer); 64 } 65 66 SimpleCompiler::CompileResult 67 SimpleCompiler::tryToLoadFromObjectCache(const Module &M) { 68 if (!ObjCache) 69 return CompileResult(); 70 71 return ObjCache->getObject(&M); 72 } 73 74 void SimpleCompiler::notifyObjectCompiled(const Module &M, 75 const MemoryBuffer &ObjBuffer) { 76 if (ObjCache) 77 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 78 } 79 80 ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, 81 ObjectCache *ObjCache) 82 : IRCompiler(irManglingOptionsFromTargetOptions(JTMB.getOptions())), 83 JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 84 85 Expected<std::unique_ptr<MemoryBuffer>> 86 ConcurrentIRCompiler::operator()(Module &M) { 87 auto TM = cantFail(JTMB.createTargetMachine()); 88 SimpleCompiler C(*TM, ObjCache); 89 return C(M); 90 } 91 92 } // end namespace orc 93 } // end namespace llvm 94