[libcxx-commits] [PATCH] D128215: [libc++] Reduces std::to_chars instantiations.

Mark de Wever via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 20 09:38:17 PDT 2022


Mordante created this revision.
Herald added a project: All.
Mordante requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

Instead of instantiating all functions called by std::to_chars for the
integral types only instantiate them for 32 and 64 bit integral types.
This results in a smaller binary when using different types.

In an example using the types: signed char, short, int, long, long long,
unsigned char, unsigned short, unsigned int, unsigned long, and
unsigned long long this saved 2792 bytes of code size. For libc++.so.1
is saves 688 bytes of code size (64-bit Linux).

This was discovered while investigating a solution for #52709.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128215

Files:
  libcxx/include/charconv
  libcxx/include/type_traits


Index: libcxx/include/type_traits
===================================================================
--- libcxx/include/type_traits
+++ libcxx/include/type_traits
@@ -517,6 +517,7 @@
 #include <__type_traits/void_t.h>
 #include <__utility/declval.h>
 #include <cstddef>
+#include <cstdint>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -1020,6 +1021,28 @@
 }
 #endif
 
+template <class _Tp>
+using __make_32_64_or_128_bit_t = typename conditional<
+    is_signed<_Tp>::value,
+    typename conditional<
+        sizeof(_Tp) <= sizeof(int32_t), int32_t,
+        typename conditional<sizeof(_Tp) <= sizeof(int64_t), int64_t,
+#ifndef _LIBCPP_HAS_NO_INT128
+                             typename conditional<sizeof(_Tp) <= sizeof(__int128_t), __int128_t, void>::type
+#else
+                             void
+#endif
+                             >::type>::type,
+    typename conditional<
+        sizeof(_Tp) <= sizeof(uint32_t), uint32_t,
+        typename conditional<sizeof(_Tp) <= sizeof(uint64_t), uint64_t,
+#ifndef _LIBCPP_HAS_NO_INT128
+                             typename conditional<sizeof(_Tp) <= sizeof(__uint128_t), __uint128_t, void>::type
+#else
+                             void
+#endif
+                             >::type>::type>::type;
+
 #if _LIBCPP_STD_VER > 17
 // Let COND_RES(X, Y) be:
 template <class _Tp, class _Up>
Index: libcxx/include/charconv
===================================================================
--- libcxx/include/charconv
+++ libcxx/include/charconv
@@ -487,16 +487,20 @@
 inline _LIBCPP_HIDE_FROM_ABI to_chars_result
 to_chars(char* __first, char* __last, _Tp __value)
 {
-    return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>());
+  using __type = __make_32_64_or_128_bit_t<_Tp>;
+  static_assert(!is_same<__type, void>::value || sizeof(_Tp) > sizeof(int64_t), "unsupported integral type used in to_chars");
+  return __to_chars_itoa(__first, __last, static_cast<__type>(__value), is_signed<_Tp>());
 }
 
 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
 inline _LIBCPP_HIDE_FROM_ABI to_chars_result
 to_chars(char* __first, char* __last, _Tp __value, int __base)
 {
-    _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
-    return __to_chars_integral(__first, __last, __value, __base,
-                               is_signed<_Tp>());
+  _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
+
+  using __type = __make_32_64_or_128_bit_t<_Tp>;
+  static_assert(!is_same<__type, void>::value || sizeof(_Tp) > sizeof(int64_t), "unsupported integral type used in to_chars");
+  return __to_chars_integral(__first, __last, static_cast<__type>(__value), __base, is_signed<_Tp>());
 }
 
 template <typename _It, typename _Tp, typename _Fn, typename... _Ts>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128215.438431.patch
Type: text/x-patch
Size: 2822 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220620/c196544c/attachment.bin>


More information about the libcxx-commits mailing list