From f6b6a7722e7ed5128c6ebc7de22fa93e242e57c1 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 24 Apr 2020 13:22:40 +0200 Subject: [PATCH] [ADT] Move allocate_buffer to MemAlloc.h and out of line There's an ABI breakage here if LLVM is compiled in C++14 without aligned allocation and a user tries to use the result with aligned allocation. If DenseMap or unique_function is used across that ABI boundary it will break (PR45413). Moving it out of line is a bit of a band-aid and LLVM doesn't really give ABI guarantees at this level, but given the number of complaints I've received over this it still seems worth fixing. --- include/llvm/ADT/DenseMap.h | 1 + include/llvm/ADT/FunctionExtras.h | 1 + include/llvm/Support/Compiler.h | 44 ------------------------------- include/llvm/Support/MemAlloc.h | 23 +++++++++++++++- lib/Support/CMakeLists.txt | 1 + lib/Support/MemAlloc.cpp | 33 +++++++++++++++++++++++ 6 files changed, 58 insertions(+), 45 deletions(-) create mode 100644 lib/Support/MemAlloc.cpp diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index d68f90ef68d..2a6f67c7fa2 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -18,6 +18,7 @@ #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemAlloc.h" #include "llvm/Support/ReverseIteration.h" #include "llvm/Support/type_traits.h" #include diff --git a/include/llvm/ADT/FunctionExtras.h b/include/llvm/ADT/FunctionExtras.h index 121aa527a5d..ad84bbc35b7 100644 --- a/include/llvm/ADT/FunctionExtras.h +++ b/include/llvm/ADT/FunctionExtras.h @@ -34,6 +34,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/Support/MemAlloc.h" #include "llvm/Support/type_traits.h" #include diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index a8356ccf812..cc64b54e31f 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -551,48 +551,4 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #define LLVM_ENABLE_EXCEPTIONS 1 #endif -#ifdef __cplusplus -namespace llvm { - -/// Allocate a buffer of memory with the given size and alignment. -/// -/// When the compiler supports aligned operator new, this will use it to to -/// handle even over-aligned allocations. -/// -/// However, this doesn't make any attempt to leverage the fancier techniques -/// like posix_memalign due to portability. It is mostly intended to allow -/// compatibility with platforms that, after aligned allocation was added, use -/// reduced default alignment. -inline void *allocate_buffer(size_t Size, size_t Alignment) { - return ::operator new(Size -#ifdef __cpp_aligned_new - , - std::align_val_t(Alignment) -#endif - ); -} - -/// Deallocate a buffer of memory with the given size and alignment. -/// -/// If supported, this will used the sized delete operator. Also if supported, -/// this will pass the alignment to the delete operator. -/// -/// The pointer must have been allocated with the corresponding new operator, -/// most likely using the above helper. -inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) { - ::operator delete(Ptr -#ifdef __cpp_sized_deallocation - , - Size -#endif -#ifdef __cpp_aligned_new - , - std::align_val_t(Alignment) -#endif - ); -} - -} // End namespace llvm - -#endif // __cplusplus #endif diff --git a/include/llvm/Support/MemAlloc.h b/include/llvm/Support/MemAlloc.h index 0e5869141fd..d6012bd5a69 100644 --- a/include/llvm/Support/MemAlloc.h +++ b/include/llvm/Support/MemAlloc.h @@ -62,5 +62,26 @@ LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) { return Result; } -} +/// Allocate a buffer of memory with the given size and alignment. +/// +/// When the compiler supports aligned operator new, this will use it to to +/// handle even over-aligned allocations. +/// +/// However, this doesn't make any attempt to leverage the fancier techniques +/// like posix_memalign due to portability. It is mostly intended to allow +/// compatibility with platforms that, after aligned allocation was added, use +/// reduced default alignment. +LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * +allocate_buffer(size_t Size, size_t Alignment); + +/// Deallocate a buffer of memory with the given size and alignment. +/// +/// If supported, this will used the sized delete operator. Also if supported, +/// this will pass the alignment to the delete operator. +/// +/// The pointer must have been allocated with the corresponding new operator, +/// most likely using the above helper. +void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment); + +} // namespace llvm #endif diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index 185aff780bd..9e81e464c68 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -115,6 +115,7 @@ add_llvm_component_library(LLVMSupport LowLevelType.cpp ManagedStatic.cpp MathExtras.cpp + MemAlloc.cpp MemoryBuffer.cpp MD5.cpp NativeFormatting.cpp diff --git a/lib/Support/MemAlloc.cpp b/lib/Support/MemAlloc.cpp new file mode 100644 index 00000000000..bc5a26dc721 --- /dev/null +++ b/lib/Support/MemAlloc.cpp @@ -0,0 +1,33 @@ +//===- MemAlloc.cpp - Memory allocation functions -------------------------===// +// +// 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/MemAlloc.h" + +// These are out of line to have __cpp_aligned_new not affect ABI. + +void *llvm::allocate_buffer(size_t Size, size_t Alignment) { + return ::operator new(Size +#ifdef __cpp_aligned_new + , + std::align_val_t(Alignment) +#endif + ); +} + +void llvm::deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) { + ::operator delete(Ptr +#ifdef __cpp_sized_deallocation + , + Size +#endif +#ifdef __cpp_aligned_new + , + std::align_val_t(Alignment) +#endif + ); +}