Skip to content

Commit

Permalink
[libc] move non <bit> functions to math_extras (llvm#84818)
Browse files Browse the repository at this point in the history
As per TODOs added in

llvm@48b0bc8.
  • Loading branch information
nickdesaulniers authored Mar 12, 2024
1 parent 261e564 commit 0ebf511
Show file tree
Hide file tree
Showing 31 changed files with 154 additions and 139 deletions.
1 change: 1 addition & 0 deletions libc/src/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ add_header_library(
HDRS
math_extras.h
DEPENDS
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
libc.src.__support.macros.attributes
Expand Down
37 changes: 0 additions & 37 deletions libc/src/__support/CPP/bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,36 +239,6 @@ LIBC_INLINE constexpr To bit_or_static_cast(const From &from) {
}
}

// TODO: remove from 'bit.h' as it is not a standard function.
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_leading_zero(T value) {
return value == cpp::numeric_limits<T>::max() ? 0 : countl_one(value) + 1;
}

// TODO: remove from 'bit.h' as it is not a standard function.
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_leading_one(T value) {
return first_leading_zero(static_cast<T>(~value));
}

// TODO: remove from 'bit.h' as it is not a standard function.
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_trailing_zero(T value) {
return value == cpp::numeric_limits<T>::max()
? 0
: countr_zero(static_cast<T>(~value)) + 1;
}

// TODO: remove from 'bit.h' as it is not a standard function.
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_trailing_one(T value) {
return value == cpp::numeric_limits<T>::max() ? 0 : countr_zero(value) + 1;
}

/// Count number of 1's aka population count or Hamming weight.
///
/// Only unsigned integral types are allowed.
Expand All @@ -294,13 +264,6 @@ ADD_SPECIALIZATION(unsigned long long, __builtin_popcountll)
// TODO: 128b specializations?
#undef ADD_SPECIALIZATION

// TODO: remove from 'bit.h' as it is not a standard function.
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
count_zeros(T value) {
return popcount<T>(static_cast<T>(~value));
}

} // namespace LIBC_NAMESPACE::cpp

#endif // LLVM_LIBC_SRC___SUPPORT_CPP_BIT_H
37 changes: 36 additions & 1 deletion libc/src/__support/math_extras.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H

#include "src/__support/CPP/limits.h" // CHAR_BIT
#include "src/__support/CPP/bit.h" // countl_one, countr_zero
#include "src/__support/CPP/limits.h" // CHAR_BIT, numeric_limits
#include "src/__support/CPP/type_traits.h" // is_unsigned_v
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h" // LIBC_HAS_BUILTIN
Expand Down Expand Up @@ -226,6 +227,40 @@ sub_with_borrow<unsigned long long>(unsigned long long a, unsigned long long b,

#endif // LIBC_HAS_BUILTIN(__builtin_subc)

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_leading_zero(T value) {
return value == cpp::numeric_limits<T>::max() ? 0
: cpp::countl_one(value) + 1;
}

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_leading_one(T value) {
return first_leading_zero(static_cast<T>(~value));
}

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_trailing_zero(T value) {
return value == cpp::numeric_limits<T>::max()
? 0
: cpp::countr_zero(static_cast<T>(~value)) + 1;
}

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_trailing_one(T value) {
return value == cpp::numeric_limits<T>::max() ? 0
: cpp::countr_zero(value) + 1;
}

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
count_zeros(T value) {
return cpp::popcount<T>(static_cast<T>(~value));
}

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
46 changes: 27 additions & 19 deletions libc/src/stdbit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
function(declare_dependencies prefixes dependencies)
set(suffixes c s i l ll)
foreach(prefix ${prefixes})
foreach(suffix IN LISTS suffixes)
add_entrypoint_object(
stdc_${prefix}_u${suffix}
SRCS
stdc_${prefix}_u${suffix}.cpp
HDRS
stdc_${prefix}_u${suffix}.h
DEPENDS
${dependencies}
)
endforeach()
endforeach()
endfunction()


set(prefixes
leading_zeros
leading_ones
trailing_zeros
trailing_ones
first_leading_zero
first_leading_one
first_trailing_zero
first_trailing_one
count_zeros
count_ones
has_single_bit
bit_width
bit_floor
bit_ceil
)
set(suffixes c s i l ll)
foreach(prefix IN LISTS prefixes)
foreach(suffix IN LISTS suffixes)
add_entrypoint_object(
stdc_${prefix}_u${suffix}
SRCS
stdc_${prefix}_u${suffix}.cpp
HDRS
stdc_${prefix}_u${suffix}.h
DEPENDS
libc.src.__support.CPP.bit
)
endforeach()
endforeach()
declare_dependencies("${prefixes}" libc.src.__support.CPP.bit)
set(prefixes
first_leading_zero
first_leading_one
first_trailing_zero
first_trailing_one
count_zeros
)
declare_dependencies("${prefixes}" libc.src.__support.math_extras)
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_count_zeros_uc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_count_zeros_uc.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_uc, (unsigned char value)) {
return static_cast<unsigned>(cpp::count_zeros(value));
return static_cast<unsigned>(count_zeros(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_count_zeros_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_count_zeros_ui.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_ui, (unsigned value)) {
return static_cast<unsigned>(cpp::count_zeros(value));
return static_cast<unsigned>(count_zeros(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_count_zeros_ul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_count_zeros_ul.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_ul, (unsigned long value)) {
return static_cast<unsigned>(cpp::count_zeros(value));
return static_cast<unsigned>(count_zeros(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_count_zeros_ull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_count_zeros_ull.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_ull, (unsigned long long value)) {
return static_cast<unsigned>(cpp::count_zeros(value));
return static_cast<unsigned>(count_zeros(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_count_zeros_us.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_count_zeros_us.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_count_zeros_us, (unsigned short value)) {
return static_cast<unsigned>(cpp::count_zeros(value));
return static_cast<unsigned>(count_zeros(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_one_uc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_first_leading_one_uc.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_uc, (unsigned char value)) {
return static_cast<unsigned>(cpp::first_leading_one(value));
return static_cast<unsigned>(first_leading_one(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_one_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_first_leading_one_ui.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_ui, (unsigned value)) {
return static_cast<unsigned>(cpp::first_leading_one(value));
return static_cast<unsigned>(first_leading_one(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_one_ul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_first_leading_one_ul.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_ul, (unsigned long value)) {
return static_cast<unsigned>(cpp::first_leading_one(value));
return static_cast<unsigned>(first_leading_one(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_one_ull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

#include "src/stdbit/stdc_first_leading_one_ull.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_ull,
(unsigned long long value)) {
return static_cast<unsigned>(cpp::first_leading_one(value));
return static_cast<unsigned>(first_leading_one(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_one_us.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

#include "src/stdbit/stdc_first_leading_one_us.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_one_us,
(unsigned short value)) {
return static_cast<unsigned>(cpp::first_leading_one(value));
return static_cast<unsigned>(first_leading_one(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_zero_uc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

#include "src/stdbit/stdc_first_leading_zero_uc.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_uc,
(unsigned char value)) {
return static_cast<unsigned>(cpp::first_leading_zero(value));
return static_cast<unsigned>(first_leading_zero(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_zero_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

#include "src/stdbit/stdc_first_leading_zero_ui.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_ui, (unsigned value)) {
return static_cast<unsigned>(cpp::first_leading_zero(value));
return static_cast<unsigned>(first_leading_zero(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_zero_ul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

#include "src/stdbit/stdc_first_leading_zero_ul.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_ul,
(unsigned long value)) {
return static_cast<unsigned>(cpp::first_leading_zero(value));
return static_cast<unsigned>(first_leading_zero(value));
}

} // namespace LIBC_NAMESPACE
4 changes: 2 additions & 2 deletions libc/src/stdbit/stdc_first_leading_zero_ull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

#include "src/stdbit/stdc_first_leading_zero_ull.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(unsigned, stdc_first_leading_zero_ull,
(unsigned long long value)) {
return static_cast<unsigned>(cpp::first_leading_zero(value));
return static_cast<unsigned>(first_leading_zero(value));
}

} // namespace LIBC_NAMESPACE
Loading

0 comments on commit 0ebf511

Please sign in to comment.