7bool ReOptimizeLayer::ReOptMaterializationUnitState::tryStartReoptimize() {
8 std::unique_lock<std::mutex> Lock(Mutex);
16void ReOptimizeLayer::ReOptMaterializationUnitState::reoptimizeSucceeded() {
17 std::unique_lock<std::mutex> Lock(Mutex);
18 assert(Reoptimizing &&
"Tried to mark unstarted reoptimization as done");
23void ReOptimizeLayer::ReOptMaterializationUnitState::reoptimizeFailed() {
24 std::unique_lock<std::mutex> Lock(Mutex);
25 assert(Reoptimizing &&
"Tried to mark unstarted reoptimization as done");
32 WFs[Mangle(
"__orc_rt_reoptimize_tag")] =
33 ES.wrapAsyncWithSPS<ReoptimizeSPSSig>(
this,
34 &ReOptimizeLayer::rt_reoptimize);
35 return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
40 auto &JD = R->getTargetJITDylib();
42 bool HasNonCallable =
false;
43 for (
auto &KV : R->getSymbols()) {
44 auto &Flags = KV.second;
45 if (!Flags.isCallable())
46 HasNonCallable =
true;
50 BaseLayer.emit(std::move(R), std::move(TSM));
54 auto &MUState = createMaterializationUnitState(TSM);
57 registerMaterializationUnitResource(Key, MUState);
59 ES.reportError(std::move(Err));
60 R->failMaterialization();
65 ProfilerFunc(*
this, MUState.getID(), MUState.getCurVersion(), TSM)) {
66 ES.reportError(std::move(Err));
67 R->failMaterialization();
72 emitMUImplSymbols(MUState, MUState.getCurVersion(), JD, std::move(TSM));
74 ES.reportError(InitialDests.takeError());
75 R->failMaterialization();
79 RSManager.emitRedirectableSymbols(std::move(R), std::move(*InitialDests));
91 auto ArgBufferConst = createReoptimizeArgBuffer(M, MUID, CurVersion);
92 if (
auto Err = ArgBufferConst.takeError())
98 if (
F.isDeclaration())
100 auto &BB =
F.getEntryBlock();
101 auto *IP = &*BB.getFirstInsertionPt();
117ReOptimizeLayer::emitMUImplSymbols(ReOptMaterializationUnitState &MUState,
122 MangleAndInterner Mangle(ES, M.getDataLayout());
124 if (!F.isDeclaration()) {
125 std::string NewName =
126 (F.getName() +
".__def__." + Twine(Version)).str();
127 RenamedMap[Mangle(F.getName())] = Mangle(NewName);
133 auto RT = JD.createResourceTracker();
135 JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(
139 MUState.setResourceTracker(RT);
142 for (
auto [K, V] : RenamedMap)
143 LookupSymbols.
add(V);
148 if (
auto Err = ImplSymbols.takeError())
152 for (
auto [K, V] : RenamedMap)
158void ReOptimizeLayer::rt_reoptimize(SendErrorFn SendResult,
160 uint32_t CurVersion) {
161 auto &MUState = getMaterializationUnitState(MUID);
162 if (CurVersion < MUState.getCurVersion() || !MUState.tryStartReoptimize()) {
168 auto OldRT = MUState.getResourceTracker();
169 auto &JD = OldRT->getJITDylib();
171 if (
auto Err = ReOptFunc(*
this, MUID, CurVersion + 1, OldRT, TSM)) {
172 ES.reportError(std::move(Err));
173 MUState.reoptimizeFailed();
179 emitMUImplSymbols(MUState, CurVersion + 1, JD, std::move(TSM));
181 ES.reportError(SymbolDests.takeError());
182 MUState.reoptimizeFailed();
187 if (
auto Err = RSManager.redirect(JD, std::move(*SymbolDests))) {
188 ES.reportError(std::move(Err));
189 MUState.reoptimizeFailed();
194 MUState.reoptimizeSucceeded();
198Expected<Constant *> ReOptimizeLayer::createReoptimizeArgBuffer(
200 size_t ArgBufferSize = SPSReoptimizeArgList::size(MUID, CurVersion);
201 std::vector<char> ArgBuffer(ArgBufferSize);
202 shared::SPSOutputBuffer
OB(ArgBuffer.data(), ArgBuffer.size());
203 if (!SPSReoptimizeArgList::serialize(OB, MUID, CurVersion))
212 M.getGlobalVariable(
"__orc_rt_jit_dispatch_ctx");
216 nullptr,
"__orc_rt_jit_dispatch_ctx");
218 M.getGlobalVariable(
"__orc_rt_reoptimize_tag");
222 nullptr,
"__orc_rt_reoptimize_tag");
232 "__orc_rt_jit_dispatch", &M);
234 size_t ArgBufferSizeConst =
236 Constant *ArgBufferSize = ConstantInt::get(
240 {DispatchCtx, ReoptimizeTag, ArgBuffer, ArgBufferSize});
243ReOptimizeLayer::ReOptMaterializationUnitState &
244ReOptimizeLayer::createMaterializationUnitState(
const ThreadSafeModule &TSM) {
245 std::unique_lock<std::mutex> Lock(
Mutex);
247 MUStates.emplace(MUID,
250 return MUStates.at(MUID);
253ReOptimizeLayer::ReOptMaterializationUnitState &
255 std::unique_lock<std::mutex> Lock(
Mutex);
256 return MUStates.at(MUID);
259void ReOptimizeLayer::registerMaterializationUnitResource(
261 std::unique_lock<std::mutex> Lock(
Mutex);
262 MUResources[
Key].insert(State.getID());
266 std::unique_lock<std::mutex> Lock(Mutex);
267 for (
auto MUID : MUResources[K])
268 MUStates.erase(MUID);
270 MUResources.erase(K);
276 std::unique_lock<std::mutex> Lock(Mutex);
277 MUResources[DstK].insert_range(MUResources[SrcK]);
278 MUResources.erase(SrcK);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Machine Check Debug Module
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
This is an important base class in LLVM.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const Function & getFunction() const
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM Value Representation.
LLVM_ABI void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
DenseMap< SymbolStringPtr, JITDispatchHandlerFunction > JITDispatchHandlerAssociationMap
A map associating tag names with asynchronous wrapper function implementations in the JIT.
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
Represents a JIT'd dynamic library.
ReOptimizeLayer(ExecutionSession &ES, DataLayout &DL, IRLayer &BaseLayer, RedirectableSymbolManager &RM)
void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM) override
Emits the given module.
Error reigsterRuntimeFunctions(JITDylib &PlatformJD)
Registers reoptimize runtime dispatch handlers to given PlatformJD.
static void createReoptimizeCall(Module &M, Instruction &IP, GlobalVariable *ArgBuffer)
uint64_t ReOptMaterializationUnitID
void handleTransferResources(JITDylib &JD, ResourceKey DstK, ResourceKey SrcK) override
This function will be called inside the session lock.
static Error reoptimizeIfCallFrequent(ReOptimizeLayer &Parent, ReOptMaterializationUnitID MUID, unsigned CurVersion, ThreadSafeModule &TSM)
Basic AddProfilerFunc that reoptimizes the function when the call count exceeds CallCountThreshold.
Error handleRemoveResources(JITDylib &JD, ResourceKey K) override
This function will be called outside the session lock.
static const uint64_t CallCountThreshold
A set of symbols to look up, each associated with a SymbolLookupFlags value.
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
An LLVM Module together with a shared ThreadSafeContext.
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module.
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
LLVM_ABI ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
@ Resolved
Queried, materialization begun.
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
FunctionAddr VTableAddr uintptr_t uintptr_t Version
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...