1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[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.
This commit is contained in:
Benjamin Kramer 2020-03-28 18:47:26 +01:00
parent 888aa45564
commit 1c3423f774

View File

@ -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));
}