[libc-commits] [libc] [libc][printf] Break out floating point support behind weak symbols (PR #120612)
Daniel Thornburgh via libc-commits
libc-commits at lists.llvm.org
Thu Dec 19 09:56:31 PST 2024
https://github.com/mysterymath created https://github.com/llvm/llvm-project/pull/120612
This is a draft implementation of https://discourse.llvm.org/t/rfc-printf-code-size-optimization/83146.
When LIBC_COPT_PRINTF_SPLIT is set, the floating-point functionality in `printf` is broken out into a family of weak functions that are only brought into the link if `__printf_float` is referenced. A later compiler change will cause the compiler to emit this symbol based on an analysis of the format string.
TODO:
- Finish hooking up and documenting LIBC_COPT_PRINTF_SPLIT
- Split printf entry functions into split and non-split versions
- Annotate declaration with attribute that refers to split version.
- Make non-split version summarily pull in all implementation functions.
>From ccbb6faee338e7cd9c93615cfaf666e61ce685e8 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Mon, 16 Dec 2024 16:42:58 -0800
Subject: [PATCH 01/11] Break float out of printf (with no way to bring it back
in)
---
.../stdio/printf_core/float_dec_converter.cpp | 2 ++
.../stdio/printf_core/float_dec_converter.h | 21 +++++++++++++------
libc/src/stdio/printf_core/printf_config.h | 10 +++++++++
3 files changed, 27 insertions(+), 6 deletions(-)
create mode 100644 libc/src/stdio/printf_core/float_dec_converter.cpp
diff --git a/libc/src/stdio/printf_core/float_dec_converter.cpp b/libc/src/stdio/printf_core/float_dec_converter.cpp
new file mode 100644
index 00000000000000..0b4b74c0ce8bd1
--- /dev/null
+++ b/libc/src/stdio/printf_core/float_dec_converter.cpp
@@ -0,0 +1,2 @@
+#define LIBC_PRINTF_DEFINE_SPLIT
+#include "src/stdio/printf_core/float_dec_converter_impl.h"
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h
index d93457fcafd7f9..e30a2fec834f5f 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -1106,9 +1106,10 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer,
}
}
+#ifdef LIBC_PRINTF_DEFINE_SPLIT
// TODO: unify the float converters to remove the duplicated checks for inf/nan.
-LIBC_INLINE int convert_float_decimal(Writer *writer,
- const FormatSection &to_conv) {
+LIBC_PRINTF_SPLIT_FUNCTION int
+convert_float_decimal(Writer *writer, const FormatSection &to_conv) {
if (to_conv.length_modifier == LengthModifier::L) {
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
fputil::FPBits<long double> float_bits(float_raw);
@@ -1128,8 +1129,8 @@ LIBC_INLINE int convert_float_decimal(Writer *writer,
return convert_inf_nan(writer, to_conv);
}
-LIBC_INLINE int convert_float_dec_exp(Writer *writer,
- const FormatSection &to_conv) {
+LIBC_PRINTF_SPLIT_FUNCTION int
+convert_float_dec_exp(Writer *writer, const FormatSection &to_conv) {
if (to_conv.length_modifier == LengthModifier::L) {
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
fputil::FPBits<long double> float_bits(float_raw);
@@ -1149,8 +1150,8 @@ LIBC_INLINE int convert_float_dec_exp(Writer *writer,
return convert_inf_nan(writer, to_conv);
}
-LIBC_INLINE int convert_float_dec_auto(Writer *writer,
- const FormatSection &to_conv) {
+LIBC_PRINTF_SPLIT_FUNCTION int
+convert_float_dec_auto(Writer *writer, const FormatSection &to_conv) {
if (to_conv.length_modifier == LengthModifier::L) {
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
fputil::FPBits<long double> float_bits(float_raw);
@@ -1169,6 +1170,14 @@ LIBC_INLINE int convert_float_dec_auto(Writer *writer,
return convert_inf_nan(writer, to_conv);
}
+#else
+[[gnu::weak]] int convert_float_decimal(Writer *writer,
+ const FormatSection &to_conv);
+[[gnu::weak]] int convert_float_dec_exp(Writer *writer,
+ const FormatSection &to_conv);
+[[gnu::weak]] int convert_float_dec_auto(Writer *writer,
+ const FormatSection &to_conv);
+#endif
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/printf_core/printf_config.h b/libc/src/stdio/printf_core/printf_config.h
index 8a48abdd170eca..c37e0bb767803b 100644
--- a/libc/src/stdio/printf_core/printf_config.h
+++ b/libc/src/stdio/printf_core/printf_config.h
@@ -48,4 +48,14 @@
// LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
+#ifdef LIBC_COPT_PRINTF_SPLIT
+// Split printf function definitions must be strong and non-inline.
+#define LIBC_PRINTF_SPLIT_FUNCTION
+#else
+// Function definitions that could be split but are not must be inline in
+// headers.
+#define LIBC_PRINTF_SPLIT_FUNCTION LIBC_INLINE
+#define LIBC_PRINTF_DEFINE_SPLIT
+#endif
+
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PRINTF_CONFIG_H
>From f20628e656cd53c5b83e4fa451763965ac9b644f Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Tue, 17 Dec 2024 11:15:30 -0800
Subject: [PATCH 02/11] Add CMake forwarding (not hooked upt to config
---
libc/src/stdio/printf_core/CMakeLists.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index 9eaffe2f7ed621..8c6064cd1544b0 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -22,6 +22,9 @@ endif()
if(LIBC_CONF_PRINTF_DISABLE_STRERROR)
list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_DISABLE_STRERROR")
endif()
+if(LIBC_CONF_PRINTF_SPLIT)
+ list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_SPLIT")
+endif()
if(printf_config_copts)
list(PREPEND printf_config_copts "COMPILE_OPTIONS")
endif()
>From f0e99b1426360502696ab0e1bb62b6d105ed5105 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Tue, 17 Dec 2024 11:18:41 -0800
Subject: [PATCH 03/11] Add object library for float_dec_converter
---
libc/src/stdio/printf_core/CMakeLists.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index 8c6064cd1544b0..140878ba0350d8 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -113,6 +113,27 @@ add_object_library(
libc.src.__support.StringUtil.error_to_string
)
+if(LIBC_CONF_PRINTF_SPLIT)
+add_object_library(
+ float_dec_converter
+ SRCS
+ float_dec_converter.cpp
+ HDRS
+ float_dec_converter.h
+ DEPENDS
+ .core_structs
+ .printf_config
+ .writer
+ libc.src.__support.big_int
+ libc.src.__support.CPP.string_view
+ libc.src.__support.float_to_string
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.integer_to_string
+ libc.src.__support.libc_assert
+)
+endif()
+
add_object_library(
printf_main
SRCS
>From 7bf95ace9f0b90a9916b9a3863d35b3199924c45 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Tue, 17 Dec 2024 11:21:03 -0800
Subject: [PATCH 04/11] Let's just use a list instead
---
libc/src/stdio/printf_core/CMakeLists.txt | 28 +++++------------------
1 file changed, 6 insertions(+), 22 deletions(-)
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index 140878ba0350d8..bf26717dab552d 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -76,10 +76,15 @@ add_object_library(
libc.src.string.memory_utils.inline_memset
)
+set(printf_converter_srcs converter.cpp)
+if(LIBC_CONF_PRINTF_SPLIT)
+ list(APPEND printf_converter_srcs float_dec_converter.cpp)
+endif()
+
add_object_library(
converter
SRCS
- converter.cpp
+ ${printf_converter_srcs}
HDRS
converter.h
converter_atlas.h
@@ -113,27 +118,6 @@ add_object_library(
libc.src.__support.StringUtil.error_to_string
)
-if(LIBC_CONF_PRINTF_SPLIT)
-add_object_library(
- float_dec_converter
- SRCS
- float_dec_converter.cpp
- HDRS
- float_dec_converter.h
- DEPENDS
- .core_structs
- .printf_config
- .writer
- libc.src.__support.big_int
- libc.src.__support.CPP.string_view
- libc.src.__support.float_to_string
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.integer_to_string
- libc.src.__support.libc_assert
-)
-endif()
-
add_object_library(
printf_main
SRCS
>From 8020767e24dd39f60d06f2d2763774bfa2b9ff28 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Tue, 17 Dec 2024 13:10:06 -0800
Subject: [PATCH 05/11] Add dummy functions to bring things in
---
libc/src/stdio/printf_core/CMakeLists.txt | 4 +++-
libc/src/stdio/printf_core/float_dec_converter.cpp | 5 ++++-
libc/src/stdio/printf_core/float_dec_converter.h | 3 +++
libc/src/stdio/printf_core/split_float.cpp | 7 +++++++
4 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 libc/src/stdio/printf_core/split_float.cpp
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index bf26717dab552d..2b8cb49fedb521 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -78,7 +78,9 @@ add_object_library(
set(printf_converter_srcs converter.cpp)
if(LIBC_CONF_PRINTF_SPLIT)
- list(APPEND printf_converter_srcs float_dec_converter.cpp)
+ list(APPEND printf_converter_srcs
+ float_dec_converter.cpp
+ split_float.cpp)
endif()
add_object_library(
diff --git a/libc/src/stdio/printf_core/float_dec_converter.cpp b/libc/src/stdio/printf_core/float_dec_converter.cpp
index 0b4b74c0ce8bd1..21726da5c14e7d 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.cpp
+++ b/libc/src/stdio/printf_core/float_dec_converter.cpp
@@ -1,2 +1,5 @@
#define LIBC_PRINTF_DEFINE_SPLIT
-#include "src/stdio/printf_core/float_dec_converter_impl.h"
+#include "src/stdio/printf_core/float_dec_converter.h"
+
+// Define trivial function that can be used to bring this file into the link.
+void __libc_printf_float_dec_converter() {}
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h
index e30a2fec834f5f..a5e4574c879957 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -1182,4 +1182,7 @@ convert_float_dec_auto(Writer *writer, const FormatSection &to_conv) {
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
+// Call this function to bring a split implementation into the link.
+extern "C" void __libc_printf_float_dec_converter();
+
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
diff --git a/libc/src/stdio/printf_core/split_float.cpp b/libc/src/stdio/printf_core/split_float.cpp
new file mode 100644
index 00000000000000..a265983cb9d14a
--- /dev/null
+++ b/libc/src/stdio/printf_core/split_float.cpp
@@ -0,0 +1,7 @@
+#include "src/stdio/printf_core/float_dec_converter.h"
+
+// Bring this file into the link if __printf_float is referenced.
+void __printf_float() {
+ // Bring the printf floating point implementation into the link.
+ __libc_printf_float_dec_converter();
+}
>From 4d54f34a1a591bf6e18499e052295afcdccb4956 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Wed, 18 Dec 2024 13:41:37 -0800
Subject: [PATCH 06/11] Break out hex float too; finishes converter fns
---
libc/src/stdio/printf_core/CMakeLists.txt | 1 +
libc/src/stdio/printf_core/float_hex_converter.cpp | 5 +++++
libc/src/stdio/printf_core/float_hex_converter.h | 12 ++++++++++--
libc/src/stdio/printf_core/split_float.cpp | 2 ++
4 files changed, 18 insertions(+), 2 deletions(-)
create mode 100644 libc/src/stdio/printf_core/float_hex_converter.cpp
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index 2b8cb49fedb521..ad69ad047e0ed9 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -80,6 +80,7 @@ set(printf_converter_srcs converter.cpp)
if(LIBC_CONF_PRINTF_SPLIT)
list(APPEND printf_converter_srcs
float_dec_converter.cpp
+ float_hex_converter.cpp
split_float.cpp)
endif()
diff --git a/libc/src/stdio/printf_core/float_hex_converter.cpp b/libc/src/stdio/printf_core/float_hex_converter.cpp
new file mode 100644
index 00000000000000..cdb28356fe48c1
--- /dev/null
+++ b/libc/src/stdio/printf_core/float_hex_converter.cpp
@@ -0,0 +1,5 @@
+#define LIBC_PRINTF_DEFINE_SPLIT
+#include "src/stdio/printf_core/float_hex_converter.h"
+
+// Define trivial function that can be used to bring this file into the link.
+void __libc_printf_float_hex_converter() {}
diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h
index b264b5cf207283..3fe550252a4541 100644
--- a/libc/src/stdio/printf_core/float_hex_converter.h
+++ b/libc/src/stdio/printf_core/float_hex_converter.h
@@ -25,8 +25,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-LIBC_INLINE int convert_float_hex_exp(Writer *writer,
- const FormatSection &to_conv) {
+#ifdef LIBC_PRINTF_DEFINE_SPLIT
+LIBC_PRINTF_SPLIT_FUNCTION int
+convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
using LDBits = fputil::FPBits<long double>;
using StorageType = LDBits::StorageType;
@@ -253,8 +254,15 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer,
}
return WRITE_OK;
}
+#else
+[[gnu::weak]] int convert_float_hex_exp(Writer *writer,
+ const FormatSection &to_conv);
+#endif
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
+// Call this function to bring a split implementation into the link.
+extern "C" void __libc_printf_float_hex_converter();
+
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_HEX_CONVERTER_H
diff --git a/libc/src/stdio/printf_core/split_float.cpp b/libc/src/stdio/printf_core/split_float.cpp
index a265983cb9d14a..3dc5d7aa03c27a 100644
--- a/libc/src/stdio/printf_core/split_float.cpp
+++ b/libc/src/stdio/printf_core/split_float.cpp
@@ -1,7 +1,9 @@
#include "src/stdio/printf_core/float_dec_converter.h"
+#include "src/stdio/printf_core/float_hex_converter.h"
// Bring this file into the link if __printf_float is referenced.
void __printf_float() {
// Bring the printf floating point implementation into the link.
__libc_printf_float_dec_converter();
+ __libc_printf_float_hex_converter();
}
>From 5b4f2a5e304c0c9fb0fe160bd39b1debbdffb03a Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Wed, 18 Dec 2024 15:25:48 -0800
Subject: [PATCH 07/11] Break out arg val writing
---
libc/src/stdio/printf_core/parser.h | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/libc/src/stdio/printf_core/parser.h b/libc/src/stdio/printf_core/parser.h
index acbbaa25b1c9da..0030fdfcc98a23 100644
--- a/libc/src/stdio/printf_core/parser.h
+++ b/libc/src/stdio/printf_core/parser.h
@@ -235,11 +235,7 @@ template <typename ArgProvider> class Parser {
case ('A'):
case ('g'):
case ('G'):
- if (lm != LengthModifier::L) {
- WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, double, conv_index);
- } else {
- WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long double, conv_index);
- }
+ write_float_arg_val(section, lm, conv_index);
break;
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
@@ -297,6 +293,14 @@ template <typename ArgProvider> class Parser {
return section;
}
+#ifdef LIBC_PRINTF_DEFINE_SPLIT
+ void write_float_arg_val(FormatSection §ion, LengthModifier lm,
+ size_t conv_index);
+#else
+ [[gnu::weak]] void write_float_arg_val(FormatSection §ion, LengthModifier lm,
+ size_t conv_index);
+#endif
+
private:
// parse_flags parses the flags inside a format string. It assumes that
// str[*local_pos] is inside a format specifier, and parses any flags it
@@ -680,6 +684,19 @@ template <typename ArgProvider> class Parser {
#endif // LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
};
+#ifdef LIBC_PRINTF_DEFINE_SPLIT
+template <typename ArgParser>
+LIBC_PRINTF_SPLIT_FUNCTION void Parser<ArgParser>::write_float_arg_val(FormatSection §ion,
+ LengthModifier lm,
+ size_t conv_index) {
+ if (lm != LengthModifier::L) {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, double, conv_index);
+ } else {
+ WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long double, conv_index);
+ }
+}
+#endif
+
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
>From 577b204a7684b2fd358798737268b5b6caf64a88 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Wed, 18 Dec 2024 15:47:50 -0800
Subject: [PATCH 08/11] Refactor split attributes
---
.../stdio/printf_core/float_dec_converter.h | 20 +++++++++----------
.../stdio/printf_core/float_hex_converter.h | 10 +++++-----
libc/src/stdio/printf_core/parser.h | 10 ++--------
libc/src/stdio/printf_core/printf_config.h | 9 ++++-----
4 files changed, 21 insertions(+), 28 deletions(-)
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h
index a5e4574c879957..0e5cdb6904f953 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -1106,9 +1106,16 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer,
}
}
+LIBC_PRINTF_SPLIT_DECL int convert_float_decimal(Writer *writer,
+ const FormatSection &to_conv);
+LIBC_PRINTF_SPLIT_DECL int convert_float_dec_exp(Writer *writer,
+ const FormatSection &to_conv);
+LIBC_PRINTF_SPLIT_DECL int convert_float_dec_auto(Writer *writer,
+ const FormatSection &to_conv);
+
#ifdef LIBC_PRINTF_DEFINE_SPLIT
// TODO: unify the float converters to remove the duplicated checks for inf/nan.
-LIBC_PRINTF_SPLIT_FUNCTION int
+LIBC_PRINTF_SPLIT_DEFN int
convert_float_decimal(Writer *writer, const FormatSection &to_conv) {
if (to_conv.length_modifier == LengthModifier::L) {
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
@@ -1129,7 +1136,7 @@ convert_float_decimal(Writer *writer, const FormatSection &to_conv) {
return convert_inf_nan(writer, to_conv);
}
-LIBC_PRINTF_SPLIT_FUNCTION int
+LIBC_PRINTF_SPLIT_DEFN int
convert_float_dec_exp(Writer *writer, const FormatSection &to_conv) {
if (to_conv.length_modifier == LengthModifier::L) {
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
@@ -1150,7 +1157,7 @@ convert_float_dec_exp(Writer *writer, const FormatSection &to_conv) {
return convert_inf_nan(writer, to_conv);
}
-LIBC_PRINTF_SPLIT_FUNCTION int
+LIBC_PRINTF_SPLIT_DEFN int
convert_float_dec_auto(Writer *writer, const FormatSection &to_conv) {
if (to_conv.length_modifier == LengthModifier::L) {
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
@@ -1170,13 +1177,6 @@ convert_float_dec_auto(Writer *writer, const FormatSection &to_conv) {
return convert_inf_nan(writer, to_conv);
}
-#else
-[[gnu::weak]] int convert_float_decimal(Writer *writer,
- const FormatSection &to_conv);
-[[gnu::weak]] int convert_float_dec_exp(Writer *writer,
- const FormatSection &to_conv);
-[[gnu::weak]] int convert_float_dec_auto(Writer *writer,
- const FormatSection &to_conv);
#endif
} // namespace printf_core
diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h
index 3fe550252a4541..6d018aa0ecaaed 100644
--- a/libc/src/stdio/printf_core/float_hex_converter.h
+++ b/libc/src/stdio/printf_core/float_hex_converter.h
@@ -25,9 +25,12 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
+LIBC_PRINTF_SPLIT_DECL int convert_float_hex_exp(Writer *writer,
+ const FormatSection &to_conv);
+
#ifdef LIBC_PRINTF_DEFINE_SPLIT
-LIBC_PRINTF_SPLIT_FUNCTION int
-convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
+LIBC_PRINTF_SPLIT_DEFN int convert_float_hex_exp(Writer *writer,
+ const FormatSection &to_conv) {
using LDBits = fputil::FPBits<long double>;
using StorageType = LDBits::StorageType;
@@ -254,9 +257,6 @@ convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
}
return WRITE_OK;
}
-#else
-[[gnu::weak]] int convert_float_hex_exp(Writer *writer,
- const FormatSection &to_conv);
#endif
} // namespace printf_core
diff --git a/libc/src/stdio/printf_core/parser.h b/libc/src/stdio/printf_core/parser.h
index 0030fdfcc98a23..89b8d65e8d988c 100644
--- a/libc/src/stdio/printf_core/parser.h
+++ b/libc/src/stdio/printf_core/parser.h
@@ -293,13 +293,7 @@ template <typename ArgProvider> class Parser {
return section;
}
-#ifdef LIBC_PRINTF_DEFINE_SPLIT
- void write_float_arg_val(FormatSection §ion, LengthModifier lm,
- size_t conv_index);
-#else
- [[gnu::weak]] void write_float_arg_val(FormatSection §ion, LengthModifier lm,
- size_t conv_index);
-#endif
+ LIBC_PRINTF_SPLIT_DECL void write_float_arg_val(FormatSection §ion, LengthModifier lm, size_t conv_index);
private:
// parse_flags parses the flags inside a format string. It assumes that
@@ -686,7 +680,7 @@ template <typename ArgProvider> class Parser {
#ifdef LIBC_PRINTF_DEFINE_SPLIT
template <typename ArgParser>
-LIBC_PRINTF_SPLIT_FUNCTION void Parser<ArgParser>::write_float_arg_val(FormatSection §ion,
+LIBC_PRINTF_SPLIT_DEFN void Parser<ArgParser>::write_float_arg_val(FormatSection §ion,
LengthModifier lm,
size_t conv_index) {
if (lm != LengthModifier::L) {
diff --git a/libc/src/stdio/printf_core/printf_config.h b/libc/src/stdio/printf_core/printf_config.h
index c37e0bb767803b..4cfca8de919d5c 100644
--- a/libc/src/stdio/printf_core/printf_config.h
+++ b/libc/src/stdio/printf_core/printf_config.h
@@ -49,12 +49,11 @@
// LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
#ifdef LIBC_COPT_PRINTF_SPLIT
-// Split printf function definitions must be strong and non-inline.
-#define LIBC_PRINTF_SPLIT_FUNCTION
+#define LIBC_PRINTF_SPLIT_DECL [[gnu::weak]]
+#define LIBC_PRINTF_SPLIT_DEFN
#else
-// Function definitions that could be split but are not must be inline in
-// headers.
-#define LIBC_PRINTF_SPLIT_FUNCTION LIBC_INLINE
+#define LIBC_PRINTF_SPLIT_DECL
+#define LIBC_PRINTF_SPLIT_DEFN LIBC_INLINE
#define LIBC_PRINTF_DEFINE_SPLIT
#endif
>From 1d7eb904cbd1faff2c6ea896c7d0e6a7447399aa Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Wed, 18 Dec 2024 15:50:35 -0800
Subject: [PATCH 09/11] Refactor float splitting
---
libc/src/stdio/printf_core/CMakeLists.txt | 5 +----
libc/src/stdio/printf_core/float_dec_converter.cpp | 5 -----
libc/src/stdio/printf_core/float_dec_converter.h | 3 ---
libc/src/stdio/printf_core/float_hex_converter.cpp | 5 -----
libc/src/stdio/printf_core/float_hex_converter.h | 3 ---
libc/src/stdio/printf_core/split_float.cpp | 8 +++-----
6 files changed, 4 insertions(+), 25 deletions(-)
delete mode 100644 libc/src/stdio/printf_core/float_dec_converter.cpp
delete mode 100644 libc/src/stdio/printf_core/float_hex_converter.cpp
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index ad69ad047e0ed9..7866c004246fc3 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -78,10 +78,7 @@ add_object_library(
set(printf_converter_srcs converter.cpp)
if(LIBC_CONF_PRINTF_SPLIT)
- list(APPEND printf_converter_srcs
- float_dec_converter.cpp
- float_hex_converter.cpp
- split_float.cpp)
+ list(APPEND printf_converter_srcs split_float.cpp)
endif()
add_object_library(
diff --git a/libc/src/stdio/printf_core/float_dec_converter.cpp b/libc/src/stdio/printf_core/float_dec_converter.cpp
deleted file mode 100644
index 21726da5c14e7d..00000000000000
--- a/libc/src/stdio/printf_core/float_dec_converter.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#define LIBC_PRINTF_DEFINE_SPLIT
-#include "src/stdio/printf_core/float_dec_converter.h"
-
-// Define trivial function that can be used to bring this file into the link.
-void __libc_printf_float_dec_converter() {}
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h
index 0e5cdb6904f953..5265f71499a42e 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -1182,7 +1182,4 @@ convert_float_dec_auto(Writer *writer, const FormatSection &to_conv) {
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
-// Call this function to bring a split implementation into the link.
-extern "C" void __libc_printf_float_dec_converter();
-
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_DEC_CONVERTER_H
diff --git a/libc/src/stdio/printf_core/float_hex_converter.cpp b/libc/src/stdio/printf_core/float_hex_converter.cpp
deleted file mode 100644
index cdb28356fe48c1..00000000000000
--- a/libc/src/stdio/printf_core/float_hex_converter.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#define LIBC_PRINTF_DEFINE_SPLIT
-#include "src/stdio/printf_core/float_hex_converter.h"
-
-// Define trivial function that can be used to bring this file into the link.
-void __libc_printf_float_hex_converter() {}
diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h
index 6d018aa0ecaaed..b017888021e04b 100644
--- a/libc/src/stdio/printf_core/float_hex_converter.h
+++ b/libc/src/stdio/printf_core/float_hex_converter.h
@@ -262,7 +262,4 @@ LIBC_PRINTF_SPLIT_DEFN int convert_float_hex_exp(Writer *writer,
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
-// Call this function to bring a split implementation into the link.
-extern "C" void __libc_printf_float_hex_converter();
-
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_HEX_CONVERTER_H
diff --git a/libc/src/stdio/printf_core/split_float.cpp b/libc/src/stdio/printf_core/split_float.cpp
index 3dc5d7aa03c27a..3bf4af80d95af0 100644
--- a/libc/src/stdio/printf_core/split_float.cpp
+++ b/libc/src/stdio/printf_core/split_float.cpp
@@ -1,9 +1,7 @@
+#define LIBC_PRINTF_DEFINE_SPLIT
#include "src/stdio/printf_core/float_dec_converter.h"
#include "src/stdio/printf_core/float_hex_converter.h"
+#include "src/stdio/printf_core/parser.h"
// Bring this file into the link if __printf_float is referenced.
-void __printf_float() {
- // Bring the printf floating point implementation into the link.
- __libc_printf_float_dec_converter();
- __libc_printf_float_hex_converter();
-}
+void __printf_float() {}
>From 6c9d596fc987161580ce8abbdb5613509012058f Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Wed, 18 Dec 2024 16:03:56 -0800
Subject: [PATCH 10/11] Break out float_type_desc
---
libc/src/stdio/printf_core/parser.h | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/libc/src/stdio/printf_core/parser.h b/libc/src/stdio/printf_core/parser.h
index 89b8d65e8d988c..d2cd60e8480bef 100644
--- a/libc/src/stdio/printf_core/parser.h
+++ b/libc/src/stdio/printf_core/parser.h
@@ -294,6 +294,7 @@ template <typename ArgProvider> class Parser {
}
LIBC_PRINTF_SPLIT_DECL void write_float_arg_val(FormatSection §ion, LengthModifier lm, size_t conv_index);
+ LIBC_PRINTF_SPLIT_DECL TypeDesc float_type_desc(LengthModifier lm);
private:
// parse_flags parses the flags inside a format string. It assumes that
@@ -626,10 +627,7 @@ template <typename ArgProvider> class Parser {
case ('A'):
case ('g'):
case ('G'):
- if (lm != LengthModifier::L)
- conv_size = type_desc_from_type<double>();
- else
- conv_size = type_desc_from_type<long double>();
+ return float_type_desc(lm);
break;
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
@@ -680,15 +678,24 @@ template <typename ArgProvider> class Parser {
#ifdef LIBC_PRINTF_DEFINE_SPLIT
template <typename ArgParser>
-LIBC_PRINTF_SPLIT_DEFN void Parser<ArgParser>::write_float_arg_val(FormatSection §ion,
- LengthModifier lm,
- size_t conv_index) {
+LIBC_PRINTF_SPLIT_DEFN void
+Parser<ArgParser>::write_float_arg_val(FormatSection §ion,
+ LengthModifier lm, size_t conv_index) {
if (lm != LengthModifier::L) {
WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, double, conv_index);
} else {
WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, long double, conv_index);
}
}
+
+template <typename ArgParser>
+LIBC_PRINTF_SPLIT_DEFN TypeDesc
+Parser<ArgParser>::float_type_desc(LengthModifier lm) {
+ if (lm != LengthModifier::L)
+ return type_desc_from_type<double>();
+ else
+ return type_desc_from_type<long double>();
+}
#endif
} // namespace printf_core
>From add704ac282b5b3e5fd1455d3f914e8491accb17 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Thu, 19 Dec 2024 09:03:36 -0800
Subject: [PATCH 11/11] Break out remaining type desc stuffs
---
libc/src/stdio/printf_core/parser.h | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/libc/src/stdio/printf_core/parser.h b/libc/src/stdio/printf_core/parser.h
index d2cd60e8480bef..3ac677e5d05575 100644
--- a/libc/src/stdio/printf_core/parser.h
+++ b/libc/src/stdio/printf_core/parser.h
@@ -295,6 +295,7 @@ template <typename ArgProvider> class Parser {
LIBC_PRINTF_SPLIT_DECL void write_float_arg_val(FormatSection §ion, LengthModifier lm, size_t conv_index);
LIBC_PRINTF_SPLIT_DECL TypeDesc float_type_desc(LengthModifier lm);
+ LIBC_PRINTF_SPLIT_DECL bool advance_arg_if_float(TypeDesc cur_type_desc);
private:
// parse_flags parses the flags inside a format string. It assumes that
@@ -471,10 +472,8 @@ template <typename ArgProvider> class Parser {
args_cur.template next_var<uint64_t>();
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
// Floating point numbers are stored separately from the other arguments.
- else if (cur_type_desc == type_desc_from_type<double>())
- args_cur.template next_var<double>();
- else if (cur_type_desc == type_desc_from_type<long double>())
- args_cur.template next_var<long double>();
+ else if (advance_arg_if_float(cur_type_desc))
+ ;
#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
// Floating point numbers may be stored separately from the other
@@ -696,6 +695,18 @@ Parser<ArgParser>::float_type_desc(LengthModifier lm) {
else
return type_desc_from_type<long double>();
}
+
+template <typename ArgParser>
+LIBC_PRINTF_SPLIT_DEFN bool
+Parser<ArgParser>::advance_arg_if_float(TypeDesc cur_type_desc) {
+ if (cur_type_desc == type_desc_from_type<double>())
+ args_cur.template next_var<double>();
+ else if (cur_type_desc == type_desc_from_type<long double>())
+ args_cur.template next_var<long double>();
+ else
+ return false;
+ return true;
+}
#endif
} // namespace printf_core
More information about the libc-commits
mailing list