Although it isn’t common for embedded applications to rely on C++ streams and locale, it does happen, and it appears that a lot of the code size introduced when locale is used can be traced back to facets. Facets encapsulate locale-dependent information. It looks like our implementation of locale.cpp (like GNU, from what I can tell) instantiates all facets on creation of the locale, even if a facet isn’t used during the runtime of the application.
Section 3.2.2 of the Technical Report on C++ Performance (https://www.open-std.org/jtc1/sc22/open/n3646.pdf) describes a different approach to this called lazy facet initialization in which use_facet() is modified to ensure that a facet is only created if it is referenced from the program (using templates), and this can drastically reduce the static size of a program that relies on locale. I ran a (very rough) simple experiment in which I removed unneeded facets from the locale with a test using streamstream (keeping ctype), and the static link contribution of locale.cpp dropped from 163K to just 3K.
It looks like this was proposed to GNU back in 2005 (tracked in 24881 – Lazy facet instantiation)
Has anyone attempted this in LLVM or does anyone have a plan to attempt this?