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