1*0b57cec5SDimitry Andric //===------ CompileUtils.cpp - Utilities for compiling IR in the JIT ------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 10*0b57cec5SDimitry Andric 11*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 12*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ObjectCache.h" 13*0b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h" 14*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 15*0b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h" 16*0b57cec5SDimitry Andric #include "llvm/Support/Error.h" 17*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 18*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 19*0b57cec5SDimitry Andric #include "llvm/Support/SmallVectorMemoryBuffer.h" 20*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric #include <algorithm> 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric namespace llvm { 25*0b57cec5SDimitry Andric namespace orc { 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric /// Compile a Module to an ObjectFile. 28*0b57cec5SDimitry Andric SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) { 29*0b57cec5SDimitry Andric CompileResult CachedObject = tryToLoadFromObjectCache(M); 30*0b57cec5SDimitry Andric if (CachedObject) 31*0b57cec5SDimitry Andric return CachedObject; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric SmallVector<char, 0> ObjBufferSV; 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric { 36*0b57cec5SDimitry Andric raw_svector_ostream ObjStream(ObjBufferSV); 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric legacy::PassManager PM; 39*0b57cec5SDimitry Andric MCContext *Ctx; 40*0b57cec5SDimitry Andric if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) 41*0b57cec5SDimitry Andric llvm_unreachable("Target does not support MC emission."); 42*0b57cec5SDimitry Andric PM.run(M); 43*0b57cec5SDimitry Andric } 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric auto ObjBuffer = llvm::make_unique<SmallVectorMemoryBuffer>( 46*0b57cec5SDimitry Andric std::move(ObjBufferSV), 47*0b57cec5SDimitry Andric "<in memory object compiled from " + M.getModuleIdentifier() + ">"); 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric if (Obj) { 52*0b57cec5SDimitry Andric notifyObjectCompiled(M, *ObjBuffer); 53*0b57cec5SDimitry Andric return std::move(ObjBuffer); 54*0b57cec5SDimitry Andric } 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric // TODO: Actually report errors helpfully. 57*0b57cec5SDimitry Andric consumeError(Obj.takeError()); 58*0b57cec5SDimitry Andric return nullptr; 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric SimpleCompiler::CompileResult 62*0b57cec5SDimitry Andric SimpleCompiler::tryToLoadFromObjectCache(const Module &M) { 63*0b57cec5SDimitry Andric if (!ObjCache) 64*0b57cec5SDimitry Andric return CompileResult(); 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric return ObjCache->getObject(&M); 67*0b57cec5SDimitry Andric } 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric void SimpleCompiler::notifyObjectCompiled(const Module &M, 70*0b57cec5SDimitry Andric const MemoryBuffer &ObjBuffer) { 71*0b57cec5SDimitry Andric if (ObjCache) 72*0b57cec5SDimitry Andric ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 73*0b57cec5SDimitry Andric } 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, 76*0b57cec5SDimitry Andric ObjectCache *ObjCache) 77*0b57cec5SDimitry Andric : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> ConcurrentIRCompiler::operator()(Module &M) { 80*0b57cec5SDimitry Andric auto TM = cantFail(JTMB.createTargetMachine()); 81*0b57cec5SDimitry Andric SimpleCompiler C(*TM, ObjCache); 82*0b57cec5SDimitry Andric return C(M); 83*0b57cec5SDimitry Andric } 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric } // end namespace orc 86*0b57cec5SDimitry Andric } // end namespace llvm 87