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 = llvm::make_unique<SmallVectorMemoryBuffer>( 46 std::move(ObjBufferSV), 47 "<in memory object compiled from " + M.getModuleIdentifier() + ">"); 48 49 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 50 51 if (Obj) { 52 notifyObjectCompiled(M, *ObjBuffer); 53 return std::move(ObjBuffer); 54 } 55 56 // TODO: Actually report errors helpfully. 57 consumeError(Obj.takeError()); 58 return nullptr; 59 } 60 61 SimpleCompiler::CompileResult 62 SimpleCompiler::tryToLoadFromObjectCache(const Module &M) { 63 if (!ObjCache) 64 return CompileResult(); 65 66 return ObjCache->getObject(&M); 67 } 68 69 void SimpleCompiler::notifyObjectCompiled(const Module &M, 70 const MemoryBuffer &ObjBuffer) { 71 if (ObjCache) 72 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 73 } 74 75 ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, 76 ObjectCache *ObjCache) 77 : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 78 79 std::unique_ptr<MemoryBuffer> ConcurrentIRCompiler::operator()(Module &M) { 80 auto TM = cantFail(JTMB.createTargetMachine()); 81 SimpleCompiler C(*TM, ObjCache); 82 return C(M); 83 } 84 85 } // end namespace orc 86 } // end namespace llvm 87