LLVM  8.0.1
ThreadSafeModule.h
Go to the documentation of this file.
1 //===----------- ThreadSafeModule.h -- Layer interfaces ---------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Thread safe wrappers and utilities for Module and LLVMContext.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULEWRAPPER_H
15 #define LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULEWRAPPER_H
16 
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/Compiler.h"
20 
21 #include <functional>
22 #include <memory>
23 #include <mutex>
24 
25 namespace llvm {
26 namespace orc {
27 
28 /// An LLVMContext together with an associated mutex that can be used to lock
29 /// the context to prevent concurrent access by other threads.
31 private:
32  struct State {
33  State(std::unique_ptr<LLVMContext> Ctx) : Ctx(std::move(Ctx)) {}
34 
35  std::unique_ptr<LLVMContext> Ctx;
36  std::recursive_mutex Mutex;
37  };
38 
39 public:
40  // RAII based lock for ThreadSafeContext.
42  private:
43  using UnderlyingLock = std::lock_guard<std::recursive_mutex>;
44 
45  public:
46  Lock(std::shared_ptr<State> S)
47  : S(std::move(S)),
48  L(llvm::make_unique<UnderlyingLock>(this->S->Mutex)) {}
49 
50  private:
51  std::shared_ptr<State> S;
52  std::unique_ptr<UnderlyingLock> L;
53  };
54 
55  /// Construct a null context.
56  ThreadSafeContext() = default;
57 
58  /// Construct a ThreadSafeContext from the given LLVMContext.
59  ThreadSafeContext(std::unique_ptr<LLVMContext> NewCtx)
60  : S(std::make_shared<State>(std::move(NewCtx))) {
61  assert(S->Ctx != nullptr &&
62  "Can not construct a ThreadSafeContext from a nullptr");
63  }
64 
65  /// Returns a pointer to the LLVMContext that was used to construct this
66  /// instance, or null if the instance was default constructed.
67  LLVMContext *getContext() { return S ? S->Ctx.get() : nullptr; }
68 
69  /// Returns a pointer to the LLVMContext that was used to construct this
70  /// instance, or null if the instance was default constructed.
71  const LLVMContext *getContext() const { return S ? S->Ctx.get() : nullptr; }
72 
74  assert(S && "Can not lock an empty ThreadSafeContext");
75  return Lock(S);
76  }
77 
78 private:
79  std::shared_ptr<State> S;
80 };
81 
82 /// An LLVM Module together with a shared ThreadSafeContext.
84 public:
85  /// Default construct a ThreadSafeModule. This results in a null module and
86  /// null context.
87  ThreadSafeModule() = default;
88 
90 
92  // We have to explicitly define this move operator to copy the fields in
93  // reverse order (i.e. module first) to ensure the dependencies are
94  // protected: The old module that is being overwritten must be destroyed
95  // *before* the context that it depends on.
96  // We also need to lock the context to make sure the module tear-down
97  // does not overlap any other work on the context.
98  if (M) {
99  auto L = getContextLock();
100  M = nullptr;
101  }
102  M = std::move(Other.M);
103  TSCtx = std::move(Other.TSCtx);
104  return *this;
105  }
106 
107  /// Construct a ThreadSafeModule from a unique_ptr<Module> and a
108  /// unique_ptr<LLVMContext>. This creates a new ThreadSafeContext from the
109  /// given context.
110  ThreadSafeModule(std::unique_ptr<Module> M, std::unique_ptr<LLVMContext> Ctx)
111  : M(std::move(M)), TSCtx(std::move(Ctx)) {}
112 
113  /// Construct a ThreadSafeModule from a unique_ptr<Module> and an
114  /// existing ThreadSafeContext.
115  ThreadSafeModule(std::unique_ptr<Module> M, ThreadSafeContext TSCtx)
116  : M(std::move(M)), TSCtx(std::move(TSCtx)) {}
117 
119  // We need to lock the context while we destruct the module.
120  if (M) {
121  auto L = getContextLock();
122  M = nullptr;
123  }
124  }
125 
126  /// Get the module wrapped by this ThreadSafeModule.
127  Module *getModule() { return M.get(); }
128 
129  /// Get the module wrapped by this ThreadSafeModule.
130  const Module *getModule() const { return M.get(); }
131 
132  /// Take out a lock on the ThreadSafeContext for this module.
133  ThreadSafeContext::Lock getContextLock() { return TSCtx.getLock(); }
134 
135  /// Boolean conversion: This ThreadSafeModule will evaluate to true if it
136  /// wraps a non-null module.
137  explicit operator bool() {
138  if (M) {
139  assert(TSCtx.getContext() &&
140  "Non-null module must have non-null context");
141  return true;
142  }
143  return false;
144  }
145 
146 private:
147  std::unique_ptr<Module> M;
148  ThreadSafeContext TSCtx;
149 };
150 
151 using GVPredicate = std::function<bool(const GlobalValue &)>;
152 using GVModifier = std::function<void(GlobalValue &)>;
153 
154 /// Clones the given module on to a new context.
157  GVPredicate ShouldCloneDef = GVPredicate(),
158  GVModifier UpdateClonedDefSource = GVModifier());
159 
160 } // End namespace orc
161 } // End namespace llvm
162 
163 #endif // LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULEWRAPPER_H
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
An LLVMContext together with an associated mutex that can be used to lock the context to prevent conc...
static sys::Mutex Lock
ThreadSafeContext(std::unique_ptr< LLVMContext > NewCtx)
Construct a ThreadSafeContext from the given LLVMContext.
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Definition: STLExtras.h:1349
std::function< bool(const GlobalValue &)> GVPredicate
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
Definition: Compiler.h:129
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
Definition: Mutex.h:139
Definition: BitVector.h:938
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:784
const LLVMContext * getContext() const
Returns a pointer to the LLVMContext that was used to construct this instance, or null if the instanc...
Module * getModule()
Get the module wrapped by this ThreadSafeModule.
ThreadSafeModule(std::unique_ptr< Module > M, ThreadSafeContext TSCtx)
Construct a ThreadSafeModule from a unique_ptr<Module> and an existing ThreadSafeContext.
const Module * getModule() const
Get the module wrapped by this ThreadSafeModule.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
LLVMContext * getContext()
Returns a pointer to the LLVMContext that was used to construct this instance, or null if the instanc...
An LLVM Module together with a shared ThreadSafeContext.
Module.h This file contains the declarations for the Module class.
ThreadSafeContext::Lock getContextLock()
Take out a lock on the ThreadSafeContext for this module.
ThreadSafeModule(std::unique_ptr< Module > M, std::unique_ptr< LLVMContext > Ctx)
Construct a ThreadSafeModule from a unique_ptr<Module> and a unique_ptr<LLVMContext>.
ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
ThreadSafeModule & operator=(ThreadSafeModule &&Other)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::function< void(GlobalValue &)> GVModifier
Lock(std::shared_ptr< State > S)
ThreadSafeContext()=default
Construct a null context.