Skip to content

Commit e6dd4bd

Browse files
committed
[libc] Modular printf option (float only)
This adds LIBC_CONF_PRINTF_MODULAR, which causes floating point support (later, others) to be weakly linked into the implementation. __printf_modular becomes the main entry point of the implementaiton, an printf itself wraps __printf_modular. printf it also contains a BFD_RELOC_NONE relocation to bring in the float aspect. See issue #146159 for context.
1 parent e77a856 commit e6dd4bd

14 files changed

+216
-33
lines changed

libc/config/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
"LIBC_CONF_PRINTF_RUNTIME_DISPATCH": {
4646
"value": true,
4747
"doc": "Use dynamic dispatch for the output mechanism to reduce code size."
48+
},
49+
"LIBC_CONF_PRINTF_MODULAR": {
50+
"value": true,
51+
"doc": "Split printf implementation into modules that can be lazily linked in."
4852
}
4953
},
5054
"scanf": {

libc/docs/configure.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ to learn about the defaults for your platform and target.
4545
- ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_DYADIC_FLOAT``: Use dyadic float for faster and smaller but less accurate printf doubles.
4646
- ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_FLOAT320``: Use an alternative printf float implementation based on 320-bit floats
4747
- ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE``: Use large table for better printf long double performance.
48+
- ``LIBC_CONF_PRINTF_MODULAR``: Split printf implementation into modules that can be lazily linked in.
4849
- ``LIBC_CONF_PRINTF_RUNTIME_DISPATCH``: Use dynamic dispatch for the output mechanism to reduce code size.
4950
* **"pthread" options**
5051
- ``LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT``: Default number of spins before blocking if a mutex is in contention (default to 100).

libc/src/stdio/generic/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,15 @@ if(LLVM_LIBC_FULL_BUILD)
412412
)
413413
endif()
414414

415+
set(printf_srcs printf.cpp)
416+
if (LIBC_CONF_PRINTF_MODULAR)
417+
list(APPEND printf_srcs printf_modular.cpp)
418+
endif()
419+
415420
add_generic_entrypoint_object(
416421
printf
417422
SRCS
418-
printf.cpp
423+
${printf_srcs}
419424
HDRS
420425
../printf.h
421426
DEPENDS
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===-- Implementation of printf_modular-----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/printf.h"
10+
11+
#include "src/__support/File/file.h"
12+
#include "src/__support/arg_list.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/stdio/printf_core/vfprintf_internal.h"
15+
16+
#include "hdr/types/FILE.h"
17+
#include <stdarg.h>
18+
19+
#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
20+
#define PRINTF_STDOUT LIBC_NAMESPACE::stdout
21+
#else // LIBC_COPT_STDIO_USE_SYSTEM_FILE
22+
#define PRINTF_STDOUT ::stdout
23+
#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
24+
25+
namespace LIBC_NAMESPACE_DECL {
26+
27+
LLVM_LIBC_FUNCTION(int, __printf_modular,
28+
(const char *__restrict format, ...)) {
29+
va_list vlist;
30+
va_start(vlist, format);
31+
internal::ArgList args(vlist); // This holder class allows for easier copying
32+
// and pointer semantics, as well as handling
33+
// destruction automatically.
34+
va_end(vlist);
35+
int ret_val = printf_core::vfprintf_internal_modular(
36+
reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args);
37+
return ret_val;
38+
}
39+
40+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/printf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
namespace LIBC_NAMESPACE_DECL {
1616

1717
int printf(const char *__restrict format, ...);
18+
int __printf_modular(const char *__restrict format, ...);
1819

1920
} // namespace LIBC_NAMESPACE_DECL
2021

libc/src/stdio/printf_core/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ endif()
2828
if(LIBC_CONF_PRINTF_RUNTIME_DISPATCH)
2929
list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_RUNTIME_DISPATCH")
3030
endif()
31+
if(LIBC_CONF_PRINTF_MODULAR)
32+
list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_MODULAR")
33+
endif()
3134
if(printf_config_copts)
3235
list(PREPEND printf_config_copts "COMPILE_OPTIONS")
3336
endif()
@@ -112,10 +115,12 @@ add_header_library(
112115
libc.src.__support.StringUtil.error_to_string
113116
)
114117

115-
add_header_library(
118+
add_object_library(
116119
printf_main
117120
HDRS
118121
printf_main.h
122+
SRCS
123+
float_impl.cpp
119124
DEPENDS
120125
.parser
121126
.converter

libc/src/stdio/printf_core/float_dec_converter.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,11 +1122,23 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer<write_mode> *writer,
11221122
}
11231123
}
11241124

1125+
template <WriteMode write_mode>
1126+
LIBC_PRINTF_MODULAR_DECL int
1127+
convert_float_decimal(Writer<write_mode> *writer, const FormatSection &to_conv);
1128+
template <WriteMode write_mode>
1129+
LIBC_PRINTF_MODULAR_DECL int
1130+
convert_float_dec_exp(Writer<write_mode> *writer, const FormatSection &to_conv);
1131+
template <WriteMode write_mode>
1132+
LIBC_PRINTF_MODULAR_DECL int
1133+
convert_float_dec_auto(Writer<write_mode> *writer,
1134+
const FormatSection &to_conv);
1135+
1136+
#ifdef LIBC_PRINTF_DEFINE_MODULAR
11251137
// TODO: unify the float converters to remove the duplicated checks for inf/nan.
11261138

11271139
template <WriteMode write_mode>
1128-
LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
1129-
const FormatSection &to_conv) {
1140+
int convert_float_decimal(Writer<write_mode> *writer,
1141+
const FormatSection &to_conv) {
11301142
if (to_conv.length_modifier == LengthModifier::L) {
11311143
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
11321144
fputil::FPBits<long double> float_bits(float_raw);
@@ -1147,8 +1159,8 @@ LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
11471159
}
11481160

11491161
template <WriteMode write_mode>
1150-
LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
1151-
const FormatSection &to_conv) {
1162+
int convert_float_dec_exp(Writer<write_mode> *writer,
1163+
const FormatSection &to_conv) {
11521164
if (to_conv.length_modifier == LengthModifier::L) {
11531165
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
11541166
fputil::FPBits<long double> float_bits(float_raw);
@@ -1169,8 +1181,8 @@ LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
11691181
}
11701182

11711183
template <WriteMode write_mode>
1172-
LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
1173-
const FormatSection &to_conv) {
1184+
int convert_float_dec_auto(Writer<write_mode> *writer,
1185+
const FormatSection &to_conv) {
11741186
if (to_conv.length_modifier == LengthModifier::L) {
11751187
fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw;
11761188
fputil::FPBits<long double> float_bits(float_raw);
@@ -1189,6 +1201,7 @@ LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
11891201

11901202
return convert_inf_nan(writer, to_conv);
11911203
}
1204+
#endif
11921205

11931206
} // namespace printf_core
11941207
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/printf_core/float_dec_converter_limited.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -676,22 +676,34 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer<write_mode> *writer,
676676
}
677677

678678
template <WriteMode write_mode>
679-
LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
680-
const FormatSection &to_conv) {
679+
LIBC_PRINTF_MODULAR_DECL int convert_float_decimal(Writer<write_mode> *writer,
680+
const FormatSection &to_conv);
681+
template <WriteMode write_mode>
682+
LIBC_PRINTF_MODULAR_DECL int convert_float_dec_exp(Writer<write_mode> *writer,
683+
const FormatSection &to_conv);
684+
template <WriteMode write_mode>
685+
LIBC_PRINTF_MODULAR_DECL int convert_float_dec_auto(Writer<write_mode> *writer,
686+
const FormatSection &to_conv);
687+
688+
#ifdef LIBC_PRINTF_DEFINE_MODULAR
689+
template <WriteMode write_mode>
690+
int convert_float_decimal(Writer<write_mode> *writer,
691+
const FormatSection &to_conv) {
681692
return convert_float_outer(writer, to_conv, ConversionType::F);
682693
}
683694

684695
template <WriteMode write_mode>
685-
LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
686-
const FormatSection &to_conv) {
696+
int convert_float_dec_exp(Writer<write_mode> *writer,
697+
const FormatSection &to_conv) {
687698
return convert_float_outer(writer, to_conv, ConversionType::E);
688699
}
689700

690701
template <WriteMode write_mode>
691-
LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
692-
const FormatSection &to_conv) {
702+
int convert_float_dec_auto(Writer<write_mode> *writer,
703+
const FormatSection &to_conv) {
693704
return convert_float_outer(writer, to_conv, ConversionType::G);
694705
}
706+
#endif
695707

696708
} // namespace printf_core
697709
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/printf_core/float_hex_converter.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,13 @@ namespace LIBC_NAMESPACE_DECL {
2626
namespace printf_core {
2727

2828
template <WriteMode write_mode>
29-
LIBC_INLINE int convert_float_hex_exp(Writer<write_mode> *writer,
30-
const FormatSection &to_conv) {
29+
LIBC_PRINTF_MODULAR_DECL int convert_float_hex_exp(Writer<write_mode> *writer,
30+
const FormatSection &to_conv);
31+
32+
#ifdef LIBC_PRINTF_DEFINE_MODULAR
33+
template <WriteMode write_mode>
34+
int convert_float_hex_exp(Writer<write_mode> *writer,
35+
const FormatSection &to_conv) {
3136
using LDBits = fputil::FPBits<long double>;
3237
using StorageType = LDBits::StorageType;
3338

@@ -254,6 +259,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer<write_mode> *writer,
254259
}
255260
return WRITE_OK;
256261
}
262+
#endif
257263

258264
} // namespace printf_core
259265
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifdef LIBC_COPT_PRINTF_MODULAR
2+
#include "src/__support/arg_list.h"
3+
4+
#define LIBC_PRINTF_DEFINE_MODULAR
5+
#include "src/stdio/printf_core/float_dec_converter.h"
6+
#include "src/stdio/printf_core/float_hex_converter.h"
7+
#include "src/stdio/printf_core/parser.h"
8+
9+
namespace LIBC_NAMESPACE_DECL {
10+
namespace printf_core {
11+
template class Parser<internal::ArgList>;
12+
template class Parser<internal::DummyArgList<false>>;
13+
template class Parser<internal::DummyArgList<true>>;
14+
template class Parser<internal::StructArgList<false>>;
15+
template class Parser<internal::StructArgList<true>>;
16+
17+
#define INSTANTIATE_CONVERT_FN(NAME) \
18+
template int NAME<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>( \
19+
Writer<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW> * writer, \
20+
const FormatSection &to_conv); \
21+
template int NAME<WriteMode::FLUSH_TO_STREAM>( \
22+
Writer<WriteMode::FLUSH_TO_STREAM> * writer, \
23+
const FormatSection &to_conv); \
24+
template int NAME<WriteMode::RESIZE_AND_FILL_BUFF>( \
25+
Writer<WriteMode::RESIZE_AND_FILL_BUFF> * writer, \
26+
const FormatSection &to_conv); \
27+
template int NAME<WriteMode::RUNTIME_DISPATCH>( \
28+
Writer<WriteMode::RUNTIME_DISPATCH> * writer, \
29+
const FormatSection &to_conv)
30+
31+
INSTANTIATE_CONVERT_FN(convert_float_decimal);
32+
INSTANTIATE_CONVERT_FN(convert_float_dec_exp);
33+
INSTANTIATE_CONVERT_FN(convert_float_dec_auto);
34+
INSTANTIATE_CONVERT_FN(convert_float_hex_exp);
35+
36+
} // namespace printf_core
37+
} // namespace LIBC_NAMESPACE_DECL
38+
39+
// Bring this file into the link if __printf_float is referenced.
40+
extern "C" void __printf_float() {}
41+
#endif

0 commit comments

Comments
 (0)