From 3461794a686ce3b3489d9de817d505f0675f4f13 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 8 Nov 2021 09:31:29 +0000 Subject: [PATCH] Changed ifunc resolver for _jr_resolv to use the `static const` initialiser in the new macro-based constant expression xsubi endianess resolver. The ifunc resolver always had resolved the correct function at compile-time and consists of a single `jmp` into it, this doesn"t change anything but make it consistent with the constant expression resolver"s methods (which do matter for that one.) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This behaviour is reversible. See `src/rng/crand.c" for the preprocessor flag based options (although this one should make no different in codegen at all.) Fortune for rngxx's current commit: Future small blessing − 末小吉 --- src/rng/crand.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/rng/crand.c b/src/rng/crand.c index 7574a5b..245eac4 100644 --- a/src/rng/crand.c +++ b/src/rng/crand.c @@ -44,8 +44,9 @@ inline static unsigned short* IFUNC_IMPL(_jr_st_resolv, high) (jr_xsub_t* restri return state->xsubi+1; } -inline static __attribute__((gnu_inline, const)) int _resv_is_high() +inline static __attribute__((artificial, always_inline, gnu_inline, const)) int _resv_is_high() { + // This being `static const` initialised makes this function be seen as a proper constant expression. Nothing is leaked on to the stack of the caller and the function is replaced with a single `lea`. static const struct jr_state chk = { .st.xsubl = JR_MAX, }; @@ -62,8 +63,17 @@ inline static unsigned short* IFUNC_RESOLVER(_jr_st_resolv) (jr_xsub_t* restrict // The ifunc `_jr_st_resolv()` is essentially (almost) the same as a symbol-aliased constexpr function. // Ain't that neat? +#ifdef _RNGXX_JR_RESOLV_IFUNC_OLD_STACKDYN_CHECK + // The old, dynamic stack alloc of the struct, instead of putting it in global r/o data struct jr_state chk = {0}; - chk.st.xsubh = JR_MAX; + chk.st.xsubl = JR_MAX; +#else + // The new, static const alloc of the struct, puts the value in at compile-time. Better optimisation opportunities. + // NOTE: Both stratergies make the ifunc resolve its target at compile-time, there is no difference in this ifunc resolver between the two. However, in `_resv_is_high()`, the old (this) stratergy prevents it being recognised as a constant-expression and stack-allocates the useless memory in the function's (macro-expanded) caller. Causing a spill of useless instructions that the new method changes to one `lea'. + static const struct jr_state chk = { + .st.xsubl = JR_MAX, + }; +#endif return chk.st._xsub ? & IFUNC_NAME(_jr_st_resolv, high) : & IFUNC_NAME(_jr_st_resolv, low);