diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-10-25 12:12:22 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-10-25 12:12:22 +0200 |
commit | af7169b4a70eb3f60555ced17a40780f70aaaa5c (patch) | |
tree | 1633c3306b7d538fb44b12d27ec299e8db0f35fa /include | |
parent | e1a7c97ac640701973eea000007fc8b9f9dd7126 (diff) |
clang/llvm 9 fix - do not eliminate a store to a fake "const"
This is *much* better (9 kbytes better) than dropping "*const"
optimization trick.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/libbb.h | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/include/libbb.h b/include/libbb.h index 111d1b790..05a560977 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -2153,12 +2153,32 @@ struct globals; * Magic prevents ptr_to_globals from going into rodata. * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */ extern struct globals *const ptr_to_globals; + +#if defined(__clang_major__) && __clang_major__ >= 9 +/* Clang/llvm drops assignment to "constant" storage. Silently. + * Needs serious convincing to not eliminate the store. + */ +static ALWAYS_INLINE void* not_const_pp(const void *p) +{ + void *pp; + __asm__ __volatile__( + "# forget that p points to const" + : /*outputs*/ "=r" (pp) + : /*inputs*/ "0" (p) + ); + return pp; +} +#else +static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } +#endif + /* At least gcc 3.4.6 on mipsel system needs optimization barrier */ #define barrier() __asm__ __volatile__("":::"memory") #define SET_PTR_TO_GLOBALS(x) do { \ - (*(struct globals**)&ptr_to_globals) = (void*)(x); \ + (*(struct globals**)not_const_pp(&ptr_to_globals)) = (void*)(x); \ barrier(); \ } while (0) + #define FREE_PTR_TO_GLOBALS() do { \ if (ENABLE_FEATURE_CLEAN_UP) { \ free(ptr_to_globals); \ |