[llvm] d3b6e1f - [ADT] Automatically forward llvm::sort to array_pod_sort if safe
Benjamin Kramer via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 28 12:43:38 PDT 2020
Author: Benjamin Kramer
Date: 2020-03-28T20:20:14+01:00
New Revision: d3b6e1f1f93e196669645fd04ab597f8df7580d1
URL: https://github.com/llvm/llvm-project/commit/d3b6e1f1f93e196669645fd04ab597f8df7580d1
DIFF: https://github.com/llvm/llvm-project/commit/d3b6e1f1f93e196669645fd04ab597f8df7580d1.diff
LOG: [ADT] Automatically forward llvm::sort to array_pod_sort if safe
This is safe if the iterator type is a pointer and the comparator is
stateless. The enable_if pattern I'm adding here only uses
array_pod_sort for the default comparator (std::less).
Using array_pod_sort has a potential performance impact, but I didn't
notice anything when testing clang. Sorting doesn't seem to be on the
hot path anywhere in LLVM.
Shrinks Release+Asserts clang by 73k.
Added:
Modified:
llvm/include/llvm/ADT/STLExtras.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index e5620bedb0cd..a6619adc44b3 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1105,9 +1105,20 @@ inline void array_pod_sort(
reinterpret_cast<int (*)(const void *, const void *)>(Compare));
}
+namespace detail {
+template <typename T>
+// We can use qsort if the iterator type is a pointer and the underlying value
+// is trivially copyable.
+using sort_trivially_copyable = conjunction<
+ std::is_pointer<T>,
+ is_trivially_copyable<typename std::iterator_traits<T>::value_type>>;
+} // namespace detail
+
// Provide wrappers to std::sort which shuffle the elements before sorting
// to help uncover non-deterministic behavior (PR35135).
-template <typename IteratorTy>
+template <typename IteratorTy,
+ std::enable_if_t<!detail::sort_trivially_copyable<IteratorTy>::value,
+ int> = 0>
inline void sort(IteratorTy Start, IteratorTy End) {
#ifdef EXPENSIVE_CHECKS
detail::presortShuffle<IteratorTy>(Start, End);
@@ -1115,6 +1126,15 @@ inline void sort(IteratorTy Start, IteratorTy End) {
std::sort(Start, End);
}
+// Forward trivially copyable types to array_pod_sort. This avoids a large
+// amount of code bloat for a minor performance hit.
+template <typename IteratorTy,
+ std::enable_if_t<detail::sort_trivially_copyable<IteratorTy>::value,
+ int> = 0>
+inline void sort(IteratorTy Start, IteratorTy End) {
+ array_pod_sort(Start, End);
+}
+
template <typename Container> inline void sort(Container &&C) {
llvm::sort(adl_begin(C), adl_end(C));
}
More information about the llvm-commits
mailing list