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