summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2019-07-02 16:25:20 -0700
committerAli B <abittin@gmail.com>2019-07-05 19:33:16 +0300
commit9afee4e65dc5f9f5eb371683729ff67b8df81d03 (patch)
tree4cf241d6c9044f91ee8c06e6920174d06f8de0b6 /clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
parent2f19bd722c4c825320d1511c1ed83161b7f95d51 (diff)
Update prebuilt Clang to r353983e.HEADq10.0
clang 9.0.5 (based on r353983e) from build 5696680. Bug: http://b/135931688 Bug: http://b/136008926 Test: N/A Change-Id: I922d17410047d2e2df4625615352c588ee71b203
Diffstat (limited to 'clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h')
-rw-r--r--clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
new file mode 100644
index 00000000..57875003
--- /dev/null
+++ b/clang-r353983e/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
@@ -0,0 +1,162 @@
+//===----------- ThreadSafeModule.h -- Layer interfaces ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Thread safe wrappers and utilities for Module and LLVMContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULEWRAPPER_H
+#define LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULEWRAPPER_H
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Compiler.h"
+
+#include <functional>
+#include <memory>
+#include <mutex>
+
+namespace llvm {
+namespace orc {
+
+/// An LLVMContext together with an associated mutex that can be used to lock
+/// the context to prevent concurrent access by other threads.
+class ThreadSafeContext {
+private:
+ struct State {
+ State(std::unique_ptr<LLVMContext> Ctx) : Ctx(std::move(Ctx)) {}
+
+ std::unique_ptr<LLVMContext> Ctx;
+ std::recursive_mutex Mutex;
+ };
+
+public:
+ // RAII based lock for ThreadSafeContext.
+ class LLVM_NODISCARD Lock {
+ private:
+ using UnderlyingLock = std::lock_guard<std::recursive_mutex>;
+
+ public:
+ Lock(std::shared_ptr<State> S)
+ : S(std::move(S)),
+ L(llvm::make_unique<UnderlyingLock>(this->S->Mutex)) {}
+
+ private:
+ std::shared_ptr<State> S;
+ std::unique_ptr<UnderlyingLock> L;
+ };
+
+ /// Construct a null context.
+ ThreadSafeContext() = default;
+
+ /// Construct a ThreadSafeContext from the given LLVMContext.
+ ThreadSafeContext(std::unique_ptr<LLVMContext> NewCtx)
+ : S(std::make_shared<State>(std::move(NewCtx))) {
+ assert(S->Ctx != nullptr &&
+ "Can not construct a ThreadSafeContext from a nullptr");
+ }
+
+ /// Returns a pointer to the LLVMContext that was used to construct this
+ /// instance, or null if the instance was default constructed.
+ LLVMContext *getContext() { return S ? S->Ctx.get() : nullptr; }
+
+ /// Returns a pointer to the LLVMContext that was used to construct this
+ /// instance, or null if the instance was default constructed.
+ const LLVMContext *getContext() const { return S ? S->Ctx.get() : nullptr; }
+
+ Lock getLock() {
+ assert(S && "Can not lock an empty ThreadSafeContext");
+ return Lock(S);
+ }
+
+private:
+ std::shared_ptr<State> S;
+};
+
+/// An LLVM Module together with a shared ThreadSafeContext.
+class ThreadSafeModule {
+public:
+ /// Default construct a ThreadSafeModule. This results in a null module and
+ /// null context.
+ ThreadSafeModule() = default;
+
+ ThreadSafeModule(ThreadSafeModule &&Other) = default;
+
+ ThreadSafeModule &operator=(ThreadSafeModule &&Other) {
+ // We have to explicitly define this move operator to copy the fields in
+ // reverse order (i.e. module first) to ensure the dependencies are
+ // protected: The old module that is being overwritten must be destroyed
+ // *before* the context that it depends on.
+ // We also need to lock the context to make sure the module tear-down
+ // does not overlap any other work on the context.
+ if (M) {
+ auto L = getContextLock();
+ M = nullptr;
+ }
+ M = std::move(Other.M);
+ TSCtx = std::move(Other.TSCtx);
+ return *this;
+ }
+
+ /// Construct a ThreadSafeModule from a unique_ptr<Module> and a
+ /// unique_ptr<LLVMContext>. This creates a new ThreadSafeContext from the
+ /// given context.
+ ThreadSafeModule(std::unique_ptr<Module> M, std::unique_ptr<LLVMContext> Ctx)
+ : M(std::move(M)), TSCtx(std::move(Ctx)) {}
+
+ /// Construct a ThreadSafeModule from a unique_ptr<Module> and an
+ /// existing ThreadSafeContext.
+ ThreadSafeModule(std::unique_ptr<Module> M, ThreadSafeContext TSCtx)
+ : M(std::move(M)), TSCtx(std::move(TSCtx)) {}
+
+ ~ThreadSafeModule() {
+ // We need to lock the context while we destruct the module.
+ if (M) {
+ auto L = getContextLock();
+ M = nullptr;
+ }
+ }
+
+ /// Get the module wrapped by this ThreadSafeModule.
+ Module *getModule() { return M.get(); }
+
+ /// Get the module wrapped by this ThreadSafeModule.
+ const Module *getModule() const { return M.get(); }
+
+ /// Take out a lock on the ThreadSafeContext for this module.
+ ThreadSafeContext::Lock getContextLock() { return TSCtx.getLock(); }
+
+ /// Boolean conversion: This ThreadSafeModule will evaluate to true if it
+ /// wraps a non-null module.
+ explicit operator bool() {
+ if (M) {
+ assert(TSCtx.getContext() &&
+ "Non-null module must have non-null context");
+ return true;
+ }
+ return false;
+ }
+
+private:
+ std::unique_ptr<Module> M;
+ ThreadSafeContext TSCtx;
+};
+
+using GVPredicate = std::function<bool(const GlobalValue &)>;
+using GVModifier = std::function<void(GlobalValue &)>;
+
+/// Clones the given module on to a new context.
+ThreadSafeModule
+cloneToNewContext(ThreadSafeModule &TSMW,
+ GVPredicate ShouldCloneDef = GVPredicate(),
+ GVModifier UpdateClonedDefSource = GVModifier());
+
+} // End namespace orc
+} // End namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_THREADSAFEMODULEWRAPPER_H