Skip to content

[libc] move non <bit> functions to math_extras #84818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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