1 //===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===// 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 // JIT layer for breaking up modules and inserting callbacks to allow 10 // individual functions to be compiled on demand. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 15 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 16 17 #include "llvm/ADT/APInt.h" 18 #include "llvm/ADT/Optional.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/ExecutionEngine/JITSymbol.h" 22 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" 23 #include "llvm/ExecutionEngine/Orc/Layer.h" 24 #include "llvm/ExecutionEngine/Orc/LazyReexports.h" 25 #include "llvm/ExecutionEngine/Orc/Speculation.h" 26 #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" 27 #include "llvm/ExecutionEngine/RuntimeDyld.h" 28 #include "llvm/IR/Attributes.h" 29 #include "llvm/IR/Constant.h" 30 #include "llvm/IR/Constants.h" 31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/Function.h" 33 #include "llvm/IR/GlobalAlias.h" 34 #include "llvm/IR/GlobalValue.h" 35 #include "llvm/IR/GlobalVariable.h" 36 #include "llvm/IR/Instruction.h" 37 #include "llvm/IR/Mangler.h" 38 #include "llvm/IR/Module.h" 39 #include "llvm/IR/Type.h" 40 #include "llvm/Support/Casting.h" 41 #include "llvm/Support/raw_ostream.h" 42 #include "llvm/Transforms/Utils/ValueMapper.h" 43 #include <algorithm> 44 #include <cassert> 45 #include <functional> 46 #include <iterator> 47 #include <list> 48 #include <memory> 49 #include <set> 50 #include <utility> 51 #include <vector> 52 53 namespace llvm { 54 namespace orc { 55 56 class CompileOnDemandLayer : public IRLayer { 57 friend class PartitioningIRMaterializationUnit; 58 59 public: 60 /// Builder for IndirectStubsManagers. 61 using IndirectStubsManagerBuilder = 62 std::function<std::unique_ptr<IndirectStubsManager>()>; 63 64 using GlobalValueSet = std::set<const GlobalValue *>; 65 66 /// Partitioning function. 67 using PartitionFunction = 68 std::function<Optional<GlobalValueSet>(GlobalValueSet Requested)>; 69 70 /// Off-the-shelf partitioning which compiles all requested symbols (usually 71 /// a single function at a time). 72 static Optional<GlobalValueSet> compileRequested(GlobalValueSet Requested); 73 74 /// Off-the-shelf partitioning which compiles whole modules whenever any 75 /// symbol in them is requested. 76 static Optional<GlobalValueSet> compileWholeModule(GlobalValueSet Requested); 77 78 /// Construct a CompileOnDemandLayer. 79 CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, 80 LazyCallThroughManager &LCTMgr, 81 IndirectStubsManagerBuilder BuildIndirectStubsManager); 82 83 /// Sets the partition function. 84 void setPartitionFunction(PartitionFunction Partition); 85 86 /// Sets the ImplSymbolMap 87 void setImplMap(ImplSymbolMap *Imp); 88 89 /// Emits the given module. This should not be called by clients: it will be 90 /// called by the JIT when a definition added via the add method is requested. 91 void emit(std::unique_ptr<MaterializationResponsibility> R, 92 ThreadSafeModule TSM) override; 93 94 private: 95 struct PerDylibResources { 96 public: 97 PerDylibResources(JITDylib &ImplD, 98 std::unique_ptr<IndirectStubsManager> ISMgr) 99 : ImplD(ImplD), ISMgr(std::move(ISMgr)) {} 100 JITDylib &getImplDylib() { return ImplD; } 101 IndirectStubsManager &getISManager() { return *ISMgr; } 102 103 private: 104 JITDylib &ImplD; 105 std::unique_ptr<IndirectStubsManager> ISMgr; 106 }; 107 108 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>; 109 110 PerDylibResources &getPerDylibResources(JITDylib &TargetD); 111 112 void cleanUpModule(Module &M); 113 114 void expandPartition(GlobalValueSet &Partition); 115 116 void emitPartition(std::unique_ptr<MaterializationResponsibility> R, 117 ThreadSafeModule TSM, 118 IRMaterializationUnit::SymbolNameToDefinitionMap Defs); 119 120 mutable std::mutex CODLayerMutex; 121 122 IRLayer &BaseLayer; 123 LazyCallThroughManager &LCTMgr; 124 IndirectStubsManagerBuilder BuildIndirectStubsManager; 125 PerDylibResourcesMap DylibResources; 126 PartitionFunction Partition = compileRequested; 127 SymbolLinkagePromoter PromoteSymbols; 128 ImplSymbolMap *AliaseeImpls = nullptr; 129 }; 130 131 } // end namespace orc 132 } // end namespace llvm 133 134 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 135