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/STLExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ExecutionEngine/JITSymbol.h" 21 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" 22 #include "llvm/ExecutionEngine/Orc/Layer.h" 23 #include "llvm/ExecutionEngine/Orc/LazyReexports.h" 24 #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" 25 #include "llvm/ExecutionEngine/Orc/Speculation.h" 26 #include "llvm/ExecutionEngine/RuntimeDyld.h" 27 #include "llvm/IR/Attributes.h" 28 #include "llvm/IR/Constant.h" 29 #include "llvm/IR/Constants.h" 30 #include "llvm/IR/DataLayout.h" 31 #include "llvm/IR/Function.h" 32 #include "llvm/IR/GlobalAlias.h" 33 #include "llvm/IR/GlobalValue.h" 34 #include "llvm/IR/GlobalVariable.h" 35 #include "llvm/IR/Instruction.h" 36 #include "llvm/IR/Mangler.h" 37 #include "llvm/IR/Module.h" 38 #include "llvm/IR/Type.h" 39 #include "llvm/Support/Casting.h" 40 #include "llvm/Support/raw_ostream.h" 41 #include "llvm/Transforms/Utils/ValueMapper.h" 42 #include <algorithm> 43 #include <cassert> 44 #include <functional> 45 #include <iterator> 46 #include <list> 47 #include <memory> 48 #include <optional> 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<std::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 std::optional<GlobalValueSet> 73 compileRequested(GlobalValueSet Requested); 74 75 /// Off-the-shelf partitioning which compiles whole modules whenever any 76 /// symbol in them is requested. 77 static std::optional<GlobalValueSet> 78 compileWholeModule(GlobalValueSet Requested); 79 80 /// Construct a CompileOnDemandLayer. 81 CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, 82 LazyCallThroughManager &LCTMgr, 83 IndirectStubsManagerBuilder BuildIndirectStubsManager); 84 85 /// Sets the partition function. 86 void setPartitionFunction(PartitionFunction Partition); 87 88 /// Sets the ImplSymbolMap 89 void setImplMap(ImplSymbolMap *Imp); 90 91 /// Emits the given module. This should not be called by clients: it will be 92 /// called by the JIT when a definition added via the add method is requested. 93 void emit(std::unique_ptr<MaterializationResponsibility> R, 94 ThreadSafeModule TSM) override; 95 96 private: 97 struct PerDylibResources { 98 public: 99 PerDylibResources(JITDylib &ImplD, 100 std::unique_ptr<IndirectStubsManager> ISMgr) 101 : ImplD(ImplD), ISMgr(std::move(ISMgr)) {} 102 JITDylib &getImplDylib() { return ImplD; } 103 IndirectStubsManager &getISManager() { return *ISMgr; } 104 105 private: 106 JITDylib &ImplD; 107 std::unique_ptr<IndirectStubsManager> ISMgr; 108 }; 109 110 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>; 111 112 PerDylibResources &getPerDylibResources(JITDylib &TargetD); 113 114 void cleanUpModule(Module &M); 115 116 void expandPartition(GlobalValueSet &Partition); 117 118 void emitPartition(std::unique_ptr<MaterializationResponsibility> R, 119 ThreadSafeModule TSM, 120 IRMaterializationUnit::SymbolNameToDefinitionMap Defs); 121 122 mutable std::mutex CODLayerMutex; 123 124 IRLayer &BaseLayer; 125 LazyCallThroughManager &LCTMgr; 126 IndirectStubsManagerBuilder BuildIndirectStubsManager; 127 PerDylibResourcesMap DylibResources; 128 PartitionFunction Partition = compileRequested; 129 SymbolLinkagePromoter PromoteSymbols; 130 ImplSymbolMap *AliaseeImpls = nullptr; 131 }; 132 133 } // end namespace orc 134 } // end namespace llvm 135 136 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 137