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