diff --git a/llvm/docs/ProgrammersManual.rst b/llvm/docs/ProgrammersManual.rst --- a/llvm/docs/ProgrammersManual.rst +++ b/llvm/docs/ProgrammersManual.rst @@ -3068,14 +3068,6 @@ using the resultant compiler to build a copy of LLVM with multithreading support. -.. _shutdown: - -Ending Execution with ``llvm_shutdown()`` ------------------------------------------ - -When you are done using the LLVM APIs, you should call ``llvm_shutdown()`` to -deallocate memory used for internal structures. - .. _llvmcontext: Achieving Isolation with ``LLVMContext`` diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -474,10 +474,8 @@ void LLVMInitializeCore(LLVMPassRegistryRef R); -/** Deallocate and destroy all ManagedStatic variables. - @see llvm::llvm_shutdown - @see ManagedStatic */ -void LLVMShutdown(void); +LLVM_ATTRIBUTE_C_DEPRECATED(void LLVMShutdown(void), + "This function has become a no-op"); /*===-- Error handling ----------------------------------------------------===*/ diff --git a/llvm/include/llvm/Support/ManagedStatic.h b/llvm/include/llvm/Support/ManagedStatic.h --- a/llvm/include/llvm/Support/ManagedStatic.h +++ b/llvm/include/llvm/Support/ManagedStatic.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines the ManagedStatic class and the llvm_shutdown() function. +// This file used to define the ManagedStatic class. It will be removed. // //===----------------------------------------------------------------------===// @@ -18,109 +18,12 @@ namespace llvm { -/// object_creator - Helper method for ManagedStatic. -template struct object_creator { - static void *call() { return new C(); } -}; +[[deprecated("llvm_shutdown is a no-op; shutdown now happens by " + "default")]] static inline void +llvm_shutdown() {} -/// object_deleter - Helper method for ManagedStatic. -/// -template struct object_deleter { - static void call(void *Ptr) { delete (T *)Ptr; } -}; -template struct object_deleter { - static void call(void *Ptr) { delete[](T *)Ptr; } -}; - -// ManagedStatic must be initialized to zero, and it must *not* have a dynamic -// initializer because managed statics are often created while running other -// dynamic initializers. In standard C++11, the best way to accomplish this is -// with a constexpr default constructor. However, different versions of the -// Visual C++ compiler have had bugs where, even though the constructor may be -// constexpr, a dynamic initializer may be emitted depending on optimization -// settings. For the affected versions of MSVC, use the old linker -// initialization pattern of not providing a constructor and leaving the fields -// uninitialized. See http://llvm.org/PR41367 for details. -#if !defined(_MSC_VER) || (_MSC_VER >= 1925) || defined(__clang__) -#define LLVM_USE_CONSTEXPR_CTOR -#endif - -/// ManagedStaticBase - Common base class for ManagedStatic instances. -class ManagedStaticBase { -protected: -#ifdef LLVM_USE_CONSTEXPR_CTOR - mutable std::atomic Ptr{}; - mutable void (*DeleterFn)(void *) = nullptr; - mutable const ManagedStaticBase *Next = nullptr; -#else - // This should only be used as a static variable, which guarantees that this - // will be zero initialized. - mutable std::atomic Ptr; - mutable void (*DeleterFn)(void *); - mutable const ManagedStaticBase *Next; -#endif - - void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; - -public: -#ifdef LLVM_USE_CONSTEXPR_CTOR - constexpr ManagedStaticBase() = default; -#endif - - /// isConstructed - Return true if this object has not been created yet. - bool isConstructed() const { return Ptr != nullptr; } - - void destroy() const; -}; - -/// ManagedStatic - This transparently changes the behavior of global statics to -/// be lazily constructed on demand (good for reducing startup times of dynamic -/// libraries that link in LLVM components) and for making destruction be -/// explicit through the llvm_shutdown() function call. -/// -template , - class Deleter = object_deleter> -class [[deprecated("ManagedStatic is deprecated and will be removed; use " - "function scope static variables in a getter function " - "instead")]] ManagedStatic : public ManagedStaticBase { -public: - // Accessors. - C &operator*() { - void *Tmp = Ptr.load(std::memory_order_acquire); - if (!Tmp) - RegisterManagedStatic(Creator::call, Deleter::call); - - return *static_cast(Ptr.load(std::memory_order_relaxed)); - } - - C *operator->() { return &**this; } - - const C &operator*() const { - void *Tmp = Ptr.load(std::memory_order_acquire); - if (!Tmp) - RegisterManagedStatic(Creator::call, Deleter::call); - - return *static_cast(Ptr.load(std::memory_order_relaxed)); - } - - const C *operator->() const { return &**this; } - - // Extract the instance, leaving the ManagedStatic uninitialized. The - // user is then responsible for the lifetime of the returned instance. - C *claim() { - return static_cast(Ptr.exchange(nullptr)); - } -}; - -/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. -void llvm_shutdown(); - -/// llvm_shutdown_obj - This is a simple helper class that calls -/// llvm_shutdown() when it is destroyed. -struct llvm_shutdown_obj { - llvm_shutdown_obj() = default; - ~llvm_shutdown_obj() { llvm_shutdown(); } -}; +struct [[deprecated("llvm_shutdown_obj is a no-op; shutdown now happens by " + "default")]] llvm_shutdown_obj{}; } // end namespace llvm diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -32,7 +32,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" @@ -57,9 +56,8 @@ initializeCore(*unwrap(R)); } -void LLVMShutdown() { - llvm_shutdown(); -} +// Deprecated. +void LLVMShutdown() {} /*===-- Error handling ----------------------------------------------------===*/ diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -178,7 +178,6 @@ Locale.cpp LockFileManager.cpp LowLevelType.cpp - ManagedStatic.cpp MathExtras.cpp MemAlloc.cpp MemoryBuffer.cpp diff --git a/llvm/lib/Support/ManagedStatic.cpp b/llvm/lib/Support/ManagedStatic.cpp deleted file mode 100644 --- a/llvm/lib/Support/ManagedStatic.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file implements the ManagedStatic class and llvm_shutdown(). -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Config/config.h" -#include "llvm/Support/Threading.h" -#include -#include -using namespace llvm; - -static const ManagedStaticBase *StaticList = nullptr; - -static std::recursive_mutex *getManagedStaticMutex() { - static std::recursive_mutex m; - return &m; -} - -void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), - void (*Deleter)(void*)) const { - assert(Creator); - if (llvm_is_multithreaded()) { - std::lock_guard Lock(*getManagedStaticMutex()); - - if (!Ptr.load(std::memory_order_relaxed)) { - void *Tmp = Creator(); - - Ptr.store(Tmp, std::memory_order_release); - DeleterFn = Deleter; - - // Add to list of managed statics. - Next = StaticList; - StaticList = this; - } - } else { - assert(!Ptr && !DeleterFn && !Next && - "Partially initialized ManagedStatic!?"); - Ptr = Creator(); - DeleterFn = Deleter; - - // Add to list of managed statics. - Next = StaticList; - StaticList = this; - } -} - -void ManagedStaticBase::destroy() const { - assert(DeleterFn && "ManagedStatic not initialized correctly!"); - assert(StaticList == this && - "Not destroyed in reverse order of construction?"); - // Unlink from list. - StaticList = Next; - Next = nullptr; - - // Destroy memory. - DeleterFn(Ptr); - - // Cleanup. - Ptr = nullptr; - DeleterFn = nullptr; -} - -/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. -/// IMPORTANT: it's only safe to call llvm_shutdown() in single thread, -/// without any other threads executing LLVM APIs. -/// llvm_shutdown() should be the last use of LLVM APIs. -void llvm::llvm_shutdown() { - while (StaticList) - StaticList->destroy(); -} diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -56,7 +56,6 @@ LockFileManagerTest.cpp MatchersTest.cpp MD5Test.cpp - ManagedStatic.cpp MathExtrasTest.cpp MemoryBufferRefTest.cpp MemoryBufferTest.cpp @@ -127,7 +126,6 @@ endif() endif() -# ManagedStatic.cpp uses . target_link_libraries(SupportTests PRIVATE LLVMTestingSupport ${LLVM_PTHREAD_LIB}) if(NOT LLVM_INTEGRATED_CRT_ALLOC) diff --git a/llvm/unittests/Support/ManagedStatic.cpp b/llvm/unittests/Support/ManagedStatic.cpp deleted file mode 100644 --- a/llvm/unittests/Support/ManagedStatic.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//===- llvm/unittest/Support/ManagedStatic.cpp - ManagedStatic tests ------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/Allocator.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Config/config.h" -#ifdef HAVE_PTHREAD_H -#include -#endif - -#include "gtest/gtest.h" - -using namespace llvm; - -namespace { - -#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H) && \ - !__has_feature(memory_sanitizer) -namespace test1 { - llvm::ManagedStatic ms; - void *helper(void*) { - *ms; - return nullptr; - } - - // Valgrind's leak checker complains glibc's stack allocation. - // To appease valgrind, we provide our own stack for each thread. - void *allocate_stack(pthread_attr_t &a, size_t n = 65536) { - void *stack = safe_malloc(n); - pthread_attr_init(&a); -#if defined(__linux__) - pthread_attr_setstack(&a, stack, n); -#endif - return stack; - } -} - -TEST(Initialize, MultipleThreads) { - // Run this test under tsan: http://code.google.com/p/data-race-test/ - - pthread_attr_t a1, a2; - void *p1 = test1::allocate_stack(a1); - void *p2 = test1::allocate_stack(a2); - - pthread_t t1, t2; - pthread_create(&t1, &a1, test1::helper, nullptr); - pthread_create(&t2, &a2, test1::helper, nullptr); - pthread_join(t1, nullptr); - pthread_join(t2, nullptr); - free(p1); - free(p2); -} -#endif - -namespace NestedStatics { -static ManagedStatic Ms1; -struct Nest { - Nest() { - ++(*Ms1); - } - - ~Nest() { - assert(Ms1.isConstructed()); - ++(*Ms1); - } -}; -static ManagedStatic Ms2; - -TEST(ManagedStaticTest, NestedStatics) { - EXPECT_FALSE(Ms1.isConstructed()); - EXPECT_FALSE(Ms2.isConstructed()); - - *Ms2; - EXPECT_TRUE(Ms1.isConstructed()); - EXPECT_TRUE(Ms2.isConstructed()); -} -} // namespace NestedStatics - -namespace CustomCreatorDeletor { -struct CustomCreate { - static void *call() { - void *Mem = safe_malloc(sizeof(int)); - *((int *)Mem) = 42; - return Mem; - } -}; -struct CustomDelete { - static void call(void *P) { std::free(P); } -}; -static ManagedStatic Custom; -TEST(ManagedStaticTest, CustomCreatorDeletor) { - EXPECT_EQ(42, *Custom); -} -} // namespace CustomCreatorDeletor - -} // anonymous namespace diff --git a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn @@ -103,7 +103,6 @@ "MD5.cpp", "MSP430AttributeParser.cpp", "MSP430Attributes.cpp", - "ManagedStatic.cpp", "MathExtras.cpp", "MemAlloc.cpp", "MemoryBuffer.cpp", diff --git a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn @@ -58,7 +58,6 @@ "LinearPolyBaseTest.cpp", "LockFileManagerTest.cpp", "MD5Test.cpp", - "ManagedStatic.cpp", "MatchersTest.cpp", "MathExtrasTest.cpp", "MemoryBufferRefTest.cpp",