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 52 namespace llvm { 53 namespace orc { 54 55 class CompileOnDemandLayer : public IRLayer { 56 friend class PartitioningIRMaterializationUnit; 57 58 public: 59 /// Builder for IndirectStubsManagers. 60 using IndirectStubsManagerBuilder = 61 std::function<std::unique_ptr<IndirectStubsManager>()>; 62 63 using GlobalValueSet = std::set<const GlobalValue *>; 64 65 /// Partitioning function. 66 using PartitionFunction = 67 std::function<std::optional<GlobalValueSet>(GlobalValueSet Requested)>; 68 69 /// Off-the-shelf partitioning which compiles all requested symbols (usually 70 /// a single function at a time). 71 static std::optional<GlobalValueSet> 72 compileRequested(GlobalValueSet Requested); 73 74 /// Off-the-shelf partitioning which compiles whole modules whenever any 75 /// symbol in them is requested. 76 static std::optional<GlobalValueSet> 77 compileWholeModule(GlobalValueSet Requested); 78 79 /// Construct a CompileOnDemandLayer. 80 CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, 81 LazyCallThroughManager &LCTMgr, 82 IndirectStubsManagerBuilder BuildIndirectStubsManager); 83 84 /// Sets the partition function. 85 void setPartitionFunction(PartitionFunction Partition); 86 87 /// Sets the ImplSymbolMap 88 void setImplMap(ImplSymbolMap *Imp); 89 90 /// Emits the given module. This should not be called by clients: it will be 91 /// called by the JIT when a definition added via the add method is requested. 92 void emit(std::unique_ptr<MaterializationResponsibility> R, 93 ThreadSafeModule TSM) override; 94 95 private: 96 struct PerDylibResources { 97 public: 98 PerDylibResources(JITDylib &ImplD, 99 std::unique_ptr<IndirectStubsManager> ISMgr) 100 : ImplD(ImplD), ISMgr(std::move(ISMgr)) {} 101 JITDylib &getImplDylib() { return ImplD; } 102 IndirectStubsManager &getISManager() { return *ISMgr; } 103 104 private: 105 JITDylib &ImplD; 106 std::unique_ptr<IndirectStubsManager> ISMgr; 107 }; 108 109 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>; 110 111 PerDylibResources &getPerDylibResources(JITDylib &TargetD); 112 113 void cleanUpModule(Module &M); 114 115 void expandPartition(GlobalValueSet &Partition); 116 117 void emitPartition(std::unique_ptr<MaterializationResponsibility> R, 118 ThreadSafeModule TSM, 119 IRMaterializationUnit::SymbolNameToDefinitionMap Defs); 120 121 mutable std::mutex CODLayerMutex; 122 123 IRLayer &BaseLayer; 124 LazyCallThroughManager &LCTMgr; 125 IndirectStubsManagerBuilder BuildIndirectStubsManager; 126 PerDylibResourcesMap DylibResources; 127 PartitionFunction Partition = compileRequested; 128 SymbolLinkagePromoter PromoteSymbols; 129 ImplSymbolMap *AliaseeImpls = nullptr; 130 }; 131 132 } // end namespace orc 133 } // end namespace llvm 134 135 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 136