1 //===- CompileUtils.h - Utilities for compiling IR in the JIT ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Contains utilities for compiling IR to object files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H 15 #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H 16 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ExecutionEngine/ObjectCache.h" 19 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 20 #include "llvm/IR/LegacyPassManager.h" 21 #include "llvm/Object/Binary.h" 22 #include "llvm/Object/ObjectFile.h" 23 #include "llvm/Support/Error.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/MemoryBuffer.h" 26 #include "llvm/Support/SmallVectorMemoryBuffer.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include "llvm/Target/TargetMachine.h" 29 #include <algorithm> 30 #include <memory> 31 32 namespace llvm { 33 34 class MCContext; 35 class Module; 36 37 namespace orc { 38 39 /// Simple compile functor: Takes a single IR module and returns an ObjectFile. 40 /// This compiler supports a single compilation thread and LLVMContext only. 41 /// For multithreaded compilation, use MultiThreadedSimpleCompiler below. 42 class SimpleCompiler { 43 public: 44 using CompileResult = std::unique_ptr<MemoryBuffer>; 45 46 /// Construct a simple compile functor with the given target. 47 SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr) TM(TM)48 : TM(TM), ObjCache(ObjCache) {} 49 50 /// Set an ObjectCache to query before compiling. setObjectCache(ObjectCache * NewCache)51 void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } 52 53 /// Compile a Module to an ObjectFile. operator()54 CompileResult operator()(Module &M) { 55 CompileResult CachedObject = tryToLoadFromObjectCache(M); 56 if (CachedObject) 57 return CachedObject; 58 59 SmallVector<char, 0> ObjBufferSV; 60 61 { 62 raw_svector_ostream ObjStream(ObjBufferSV); 63 64 legacy::PassManager PM; 65 MCContext *Ctx; 66 if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) 67 llvm_unreachable("Target does not support MC emission."); 68 PM.run(M); 69 } 70 71 auto ObjBuffer = 72 llvm::make_unique<SmallVectorMemoryBuffer>(std::move(ObjBufferSV)); 73 auto Obj = 74 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); 75 76 if (Obj) { 77 notifyObjectCompiled(M, *ObjBuffer); 78 return std::move(ObjBuffer); 79 } 80 81 // TODO: Actually report errors helpfully. 82 consumeError(Obj.takeError()); 83 return nullptr; 84 } 85 86 private: 87 tryToLoadFromObjectCache(const Module & M)88 CompileResult tryToLoadFromObjectCache(const Module &M) { 89 if (!ObjCache) 90 return CompileResult(); 91 92 return ObjCache->getObject(&M); 93 } 94 notifyObjectCompiled(const Module & M,const MemoryBuffer & ObjBuffer)95 void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) { 96 if (ObjCache) 97 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); 98 } 99 100 TargetMachine &TM; 101 ObjectCache *ObjCache = nullptr; 102 }; 103 104 /// A thread-safe version of SimpleCompiler. 105 /// 106 /// This class creates a new TargetMachine and SimpleCompiler instance for each 107 /// compile. 108 class MultiThreadedSimpleCompiler { 109 public: 110 MultiThreadedSimpleCompiler(JITTargetMachineBuilder JTMB, 111 ObjectCache *ObjCache = nullptr) JTMB(std::move (JTMB))112 : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} 113 setObjectCache(ObjectCache * ObjCache)114 void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; } 115 operator()116 std::unique_ptr<MemoryBuffer> operator()(Module &M) { 117 auto TM = cantFail(JTMB.createTargetMachine()); 118 SimpleCompiler C(*TM, ObjCache); 119 return C(M); 120 } 121 122 private: 123 JITTargetMachineBuilder JTMB; 124 ObjectCache *ObjCache = nullptr; 125 }; 126 127 } // end namespace orc 128 129 } // end namespace llvm 130 131 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H 132