LLVM  14.0.0git
ThreadSafeModule.h
Go to the documentation of this file.
1 //===----------- ThreadSafeModule.h -- Layer interfaces ---------*- 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 // Thread safe wrappers and utilities for Module and LLVMContext.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULE_H
14 #define LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULE_H
15 
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/Compiler.h"
19 
20 #include <functional>
21 #include <memory>
22 #include <mutex>
23 
24 namespace llvm {
25 namespace orc {
26 
27 /// An LLVMContext together with an associated mutex that can be used to lock
28 /// the context to prevent concurrent access by other threads.
30 private:
31  struct State {
32  State(std::unique_ptr<LLVMContext> Ctx) : Ctx(std::move(Ctx)) {}
33 
34  std::unique_ptr<LLVMContext> Ctx;
35  std::recursive_mutex Mutex;
36  };
37 
38 public:
39  // RAII based lock for ThreadSafeContext.
41  public:
42  Lock(std::shared_ptr<State> S) : S(std::move(S)), L(this->S->Mutex) {}
43 
44  private:
45  std::shared_ptr<State> S;
46  std::unique_lock<std::recursive_mutex> L;
47  };
48 
49  /// Construct a null context.
50  ThreadSafeContext() = default;
51 
52  /// Construct a ThreadSafeContext from the given LLVMContext.
53  ThreadSafeContext(std::unique_ptr<LLVMContext> NewCtx)
54  : S(std::make_shared<State>(std::move(NewCtx))) {
55  assert(S->Ctx != nullptr &&
56  "Can not construct a ThreadSafeContext from a nullptr");
57  }
58 
59  /// Returns a pointer to the LLVMContext that was used to construct this
60  /// instance, or null if the instance was default constructed.
61  LLVMContext *getContext() { return S ? S->Ctx.get() : nullptr; }
62 
63  /// Returns a pointer to the LLVMContext that was used to construct this
64  /// instance, or null if the instance was default constructed.
65  const LLVMContext *getContext() const { return S ? S->Ctx.get() : nullptr; }
66 
67  Lock getLock() const {
68  assert(S && "Can not lock an empty ThreadSafeContext");
69  return Lock(S);
70  }
71 
72 private:
73  std::shared_ptr<State> S;
74 };
75 
76 /// An LLVM Module together with a shared ThreadSafeContext.
78 public:
79  /// Default construct a ThreadSafeModule. This results in a null module and
80  /// null context.
81  ThreadSafeModule() = default;
82 
84 
86  // We have to explicitly define this move operator to copy the fields in
87  // reverse order (i.e. module first) to ensure the dependencies are
88  // protected: The old module that is being overwritten must be destroyed
89  // *before* the context that it depends on.
90  // We also need to lock the context to make sure the module tear-down
91  // does not overlap any other work on the context.
92  if (M) {
93  auto L = TSCtx.getLock();
94  M = nullptr;
95  }
96  M = std::move(Other.M);
97  TSCtx = std::move(Other.TSCtx);
98  return *this;
99  }
100 
101  /// Construct a ThreadSafeModule from a unique_ptr<Module> and a
102  /// unique_ptr<LLVMContext>. This creates a new ThreadSafeContext from the
103  /// given context.
104  ThreadSafeModule(std::unique_ptr<Module> M, std::unique_ptr<LLVMContext> Ctx)
105  : M(std::move(M)), TSCtx(std::move(Ctx)) {}
106 
107  /// Construct a ThreadSafeModule from a unique_ptr<Module> and an
108  /// existing ThreadSafeContext.
109  ThreadSafeModule(std::unique_ptr<Module> M, ThreadSafeContext TSCtx)
110  : M(std::move(M)), TSCtx(std::move(TSCtx)) {}
111 
113  // We need to lock the context while we destruct the module.
114  if (M) {
115  auto L = TSCtx.getLock();
116  M = nullptr;
117  }
118  }
119 
120  /// Boolean conversion: This ThreadSafeModule will evaluate to true if it
121  /// wraps a non-null module.
122  explicit operator bool() const {
123  if (M) {
124  assert(TSCtx.getContext() &&
125  "Non-null module must have non-null context");
126  return true;
127  }
128  return false;
129  }
130 
131  /// Locks the associated ThreadSafeContext and calls the given function
132  /// on the contained Module.
133  template <typename Func> decltype(auto) withModuleDo(Func &&F) {
134  assert(M && "Can not call on null module");
135  auto Lock = TSCtx.getLock();
136  return F(*M);
137  }
138 
139  /// Locks the associated ThreadSafeContext and calls the given function
140  /// on the contained Module.
141  template <typename Func> decltype(auto) withModuleDo(Func &&F) const {
142  auto Lock = TSCtx.getLock();
143  return F(*M);
144  }
145 
146  /// Get a raw pointer to the contained module without locking the context.
147  Module *getModuleUnlocked() { return M.get(); }
148 
149  /// Get a raw pointer to the contained module without locking the context.
150  const Module *getModuleUnlocked() const { return M.get(); }
151 
152  /// Returns the context for this ThreadSafeModule.
153  ThreadSafeContext getContext() const { return TSCtx; }
154 
155 private:
156  std::unique_ptr<Module> M;
157  ThreadSafeContext TSCtx;
158 };
159 
160 using GVPredicate = std::function<bool(const GlobalValue &)>;
162 
163 /// Clones the given module on to a new context.
166  GVPredicate ShouldCloneDef = GVPredicate(),
167  GVModifier UpdateClonedDefSource = GVModifier());
168 
169 } // End namespace orc
170 } // End namespace llvm
171 
172 #endif // LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULE_H
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::orc::ThreadSafeModule::~ThreadSafeModule
~ThreadSafeModule()
Definition: ThreadSafeModule.h:112
Module.h
llvm::orc::ThreadSafeModule::getContext
ThreadSafeContext getContext() const
Returns the context for this ThreadSafeModule.
Definition: ThreadSafeModule.h:153
llvm::orc::ThreadSafeModule::getModuleUnlocked
Module * getModuleUnlocked()
Get a raw pointer to the contained module without locking the context.
Definition: ThreadSafeModule.h:147
llvm::orc::ThreadSafeContext::ThreadSafeContext
ThreadSafeContext()=default
Construct a null context.
llvm::orc::ThreadSafeModule::getModuleUnlocked
const Module * getModuleUnlocked() const
Get a raw pointer to the contained module without locking the context.
Definition: ThreadSafeModule.h:150
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::sys::SmartMutex< false >
llvm::orc::ThreadSafeContext::ThreadSafeContext
ThreadSafeContext(std::unique_ptr< LLVMContext > NewCtx)
Construct a ThreadSafeContext from the given LLVMContext.
Definition: ThreadSafeModule.h:53
llvm::orc::ThreadSafeModule::ThreadSafeModule
ThreadSafeModule(std::unique_ptr< Module > M, std::unique_ptr< LLVMContext > Ctx)
Construct a ThreadSafeModule from a unique_ptr<Module> and a unique_ptr<LLVMContext>.
Definition: ThreadSafeModule.h:104
llvm::orc::ThreadSafeContext::Lock
Definition: ThreadSafeModule.h:40
llvm::orc::ThreadSafeContext::getLock
Lock getLock() const
Definition: ThreadSafeModule.h:67
llvm::orc::ThreadSafeContext::getContext
const LLVMContext * getContext() const
Returns a pointer to the LLVMContext that was used to construct this instance, or null if the instanc...
Definition: ThreadSafeModule.h:65
llvm::orc::ThreadSafeModule::ThreadSafeModule
ThreadSafeModule()=default
Default construct a ThreadSafeModule.
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::orc::ThreadSafeContext::getContext
LLVMContext * getContext()
Returns a pointer to the LLVMContext that was used to construct this instance, or null if the instanc...
Definition: ThreadSafeModule.h:61
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1639
llvm::orc::ThreadSafeContext
An LLVMContext together with an associated mutex that can be used to lock the context to prevent conc...
Definition: ThreadSafeModule.h:29
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::orc::ThreadSafeModule::withModuleDo
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module.
Definition: ThreadSafeModule.h:133
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
Compiler.h
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::orc::ThreadSafeContext::Lock::Lock
Lock(std::shared_ptr< State > S)
Definition: ThreadSafeModule.h:42
llvm::sys::Mutex
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
Definition: Mutex.h:68
llvm::orc::GVPredicate
std::function< bool(const GlobalValue &)> GVPredicate
Definition: ThreadSafeModule.h:160
std
Definition: BitVector.h:838
LLVM_NODISCARD
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
Definition: Compiler.h:161
llvm::orc::ThreadSafeModule::ThreadSafeModule
ThreadSafeModule(std::unique_ptr< Module > M, ThreadSafeContext TSCtx)
Construct a ThreadSafeModule from a unique_ptr<Module> and an existing ThreadSafeContext.
Definition: ThreadSafeModule.h:109
llvm::orc::GVModifier
std::function< void(GlobalValue &)> GVModifier
Definition: ThreadSafeModule.h:161
llvm::orc::ThreadSafeModule
An LLVM Module together with a shared ThreadSafeContext.
Definition: ThreadSafeModule.h:77
LLVMContext.h
llvm::orc::ThreadSafeModule::operator=
ThreadSafeModule & operator=(ThreadSafeModule &&Other)
Definition: ThreadSafeModule.h:85
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1191
llvm::orc::cloneToNewContext
ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
Definition: ThreadSafeModule.cpp:18