This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: [PATCH v2] Add __pure2 to __locale_ctype_ptr(_l)
Sebastian Huber wrote:
> Why don't we make
>
> const char *
> __locale_ctype_ptr (void)
> {
> return __get_current_locale ()->ctype_ptr;
> }
>
> inline?
>
> Why do we need the condition in:
>
> _ELIDABLE_INLINE struct __locale_t *
> __get_current_locale (void)
> {
> return _REENT->_locale ?: __get_global_locale ();
> }
>
> Can't we set _REENT->_locale to &__global_locale instead of NULL?
>
> Systems using __getreent() would probably benefit from a __pure2 attribute.
Absolutely there is no reason not to inline all this. GLIBC has to maintain
a consistent ABI because of dynamic linking but that's not relevant to newlib.
So for single-threaded we could do:
#define _REENT &_impure_data
_impure_ptr never changes so there is no need for the indirection - the name
is incorrect as it is in fact pure! Also we could avoid the 2nd unnecessary
indirection in _REENT->_locale->ctype_ptr by adding a _REENT->ctype_ptr
(we could do better still but that's a bit more involved). So the inlined
__locale_ctype_ptr would look like this on AArch64 (+8 is the ctype_ptr offset):
adrp x0, _impure_data+8
ldr x4, [x0, #:lo12:_impure_data+8]
For multi-threaded I'd expect a typical __getreent() implementation to be
inlined, just returning the pure thread pointer in a few instructions, so it's
as expensive as the single-threaded case.
All the typical compiler optimizations now apply automatically so you never
have to worry about expensive calls in trivial loops. In the worst case
(if there is an aliasing store or a function call) you need to reload the
ctype_ptr each iteration, but that's cheap compared to the current
__locale_ctype_ptr function.
Wilco