================
@@ -0,0 +1,68 @@
+.. _modular_format:
+
+======================
+Modular format strings
+======================
+
+Introduction
+============
+
+Several C standard library functions (most notably, ``printf`` and ``scanf``),
+present a large amount of related features to the caller configured via a
+format string. This benefits code size at the caller, since format strings are
+typically quite dense, and the equivalent of many individual calls can be
+performed with only one. Overall this is a benefit, since to a function calls
+typically outnumber the one definition of that function.
+
+However, the implementations of various libc features gated behind aspects of
+those format strings can be large enough that they completely swamp the
+programs that call them. Floating point and errno conversion in particular can
+involve large tables which may be wholly dead. However, due to the format
+string structure, this code is dead in a way previously invisible to the
+compiler.
+
+To address this, an clang attribute was introduced: ``modular_format(<impl_fn>,
+<impl_name>, <aspects>...)``. This adds to the semantics of the existing
+``format`` attribute (which must also be present, if implicitly.) The first
+argument is a symbol naming a modular version of the implementation; this
+version only weakly refers to "aspects" of the implementation that may not be
+necessary for certain format strings. The second argument is general
+"implementation name" string, and the remaining arguments are a list of handled
+aspects of the format string. When the compiler sees that a given call only
+needs a fixed set of aspects of the implementation, it may redirect the call to
+the implementation function and emit a series of relocations to symbols named
+``<impl_name>_<aspect>``. These in turn bring the needed aspects of the call
+into the link. The default entrypoints fall the modular ones, except they bring
+in every possible implementation aspect.
+
+Mechanism
+=========
+
+This functionality is currently gated behind ``LIBC_COPT_PRINTF_MODULAR``. When
+set, the ``printf``-family functions gain modular variants, and the regular
+variants are modified to call them and emit NONE relocations against all
+implementation aspects. 
+
+The implementation aspects are defined in headers using the
+``LIBC_PRINTF_MODULE((<decl>), { <body> })`` macro. If
+``LIBC_COPT_PRINTF_MODULAR`` is not defined, then this macro makes these
+``LIBC_INLINE`` definitions as per usual. Otherwise, for normal usage, these
+become weak declarations, which causes any references to the module to become
+weak. The implementations are moved to a dedicated impl file for groups of
+modules. These define the aspect symbol and the module impls by defining
+``LIBC_PRINTF_DEFINE_MODULES`` before including the header. This causes the to
+be brought into the link exactly when the aspect symbol is referenced.
+
+Template functions present a special complication: the implementation must
+instantiate them for any value that may be used. Since the purpose of the
+templates is to implement a fixed interface, the possible arguments should
+always be fixed and finite. Accordingly, libc contains def files to enumerate
+possible arguments and provide handling for each. Templates are instantiated in
+the headers whenever ``LIBC_PRINTF_DEFINE_MODULES`` is defined.
+
+The aspect naming system provides independent evolution between the libc and
+compiler via a simple agreement protocol. The libc may report that it requires
+decisions for aspects unknown to the compiler; in such cases, the compiler must
+summarily report that the aspect is required for any given call. The compiler
+will also not provide support for any aspects not requested by the libc, even
+if it could opine on them.
----------------
michaelrj-google wrote:

nit: The phrasing in this paragraph is more flowery than I'd expect for a 
technical document.

https://github.com/llvm/llvm-project/pull/147426
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to