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 /// Compile a Module to an ObjectFile. 28 SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) { 29 CompileResult CachedObject = tryToLoadFromObjectCache(M); 30 if (CachedObject) 31 return CachedObject; 32 33 SmallVector<char, 0> ObjBufferSV; 34 35 { 36 raw_svector_ostream ObjStream(ObjBufferSV); 37 38 legacy::PassManager PM; 39 MCContext *Ctx; 40 if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) 41 llvm_unreachable("Target does not support MC emission."); 42 PM.run(M); 43 } 44 45 auto ObjBuffer = std::make_unique<SmallVectorMemoryBuffer>( 46 std::move(ObjBufferSV), M.getModuleIdentifier() + "-jitted-objectbuffer"); 47 48 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 49 50 if (Obj) { 51 notifyObjectCompiled(M, *ObjBuffer); 52 return std::move(ObjBuffer); 53 } 54 55 // TODO: Actually report errors helpfully. 56 consumeError(Obj.takeError()); 57 return nullptr; 58 } 59 60 SimpleCompiler::CompileResult 61 SimpleCompiler::tryToLoadFromObjectCache(const Module &M) { 62 if (!ObjCache) 63 return CompileResult(); 64 65 return ObjCache->getObject(&M); 66 } 67 68 void SimpleCompiler::notifyObjectCompiled(const Module &M, 69 const MemoryBuffer &ObjBuffer) { 70 if (ObjCache) 71 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 72 } 73 74 ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, 75 ObjectCache *ObjCache) 76 : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 77 78 std::unique_ptr<MemoryBuffer> ConcurrentIRCompiler::operator()(Module &M) { 79 auto TM = cantFail(JTMB.createTargetMachine()); 80 SimpleCompiler C(*TM, ObjCache); 81 return C(M); 82 } 83 84 } // end namespace orc 85 } // end namespace llvm 86