[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 4/7] exec: Use const alias for TARGET_PAGE_BITS_VARY
From: |
Alex Bennée |
Subject: |
Re: [PATCH v2 4/7] exec: Use const alias for TARGET_PAGE_BITS_VARY |
Date: |
Fri, 25 Oct 2019 15:28:04 +0100 |
User-agent: |
mu4e 1.3.5; emacs 27.0.50 |
Richard Henderson <address@hidden> writes:
> Using a variable that is declared "const" for this tells the
> compiler that it may read the value once and assume that it
> does not change across function calls.
>
> For target_page_size, this means we have only one assert per
> function, and one read of the variable.
>
> This reduces the size of qemu-system-aarch64 by 8k.
>
> Reviewed-by: Paolo Bonzini <address@hidden>
> Signed-off-by: Richard Henderson <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
> ---
> v2: Notice CONFIG_ATTRIBUTE_ALIAS, and work around Xcode 9 lossage.
> ---
> include/exec/cpu-all.h | 14 +++++++---
> exec-vary.c | 60 ++++++++++++++++++++++++++++++++++++------
> 2 files changed, 62 insertions(+), 12 deletions(-)
>
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 255bb186ac..76515dc8d9 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -210,10 +210,16 @@ static inline void stl_phys_notdirty(AddressSpace *as,
> hwaddr addr, uint32_t val
> /* page related stuff */
>
> #ifdef TARGET_PAGE_BITS_VARY
> -extern bool target_page_bits_decided;
> -extern int target_page_bits;
> -#define TARGET_PAGE_BITS ({ assert(target_page_bits_decided); \
> - target_page_bits; })
> +typedef struct {
> + bool decided;
> + int bits;
> +} TargetPageBits;
> +# if defined(CONFIG_ATTRIBUTE_ALIAS) || !defined(IN_EXEC_VARY)
> +extern const TargetPageBits target_page;
> +#else
> +extern TargetPageBits target_page;
> +# endif
> +#define TARGET_PAGE_BITS (assert(target_page.decided), target_page.bits)
> #else
> #define TARGET_PAGE_BITS_MIN TARGET_PAGE_BITS
> #endif
> diff --git a/exec-vary.c b/exec-vary.c
> index 48c0ab306c..e0befd502a 100644
> --- a/exec-vary.c
> +++ b/exec-vary.c
> @@ -19,11 +19,55 @@
>
> #include "qemu/osdep.h"
> #include "qemu-common.h"
> +
> +#define IN_EXEC_VARY 1
> +
> #include "exec/exec-all.h"
>
> #ifdef TARGET_PAGE_BITS_VARY
> -int target_page_bits;
> -bool target_page_bits_decided;
> +# ifdef CONFIG_ATTRIBUTE_ALIAS
> +/*
> + * We want to declare the "target_page" variable as const, which tells
> + * the compiler that it can cache any value that it reads across calls.
> + * This avoids multiple assertions and multiple reads within any one user.
> + *
> + * This works because we initialize the target_page data very early, in a
> + * location far removed from the functions that require the final results.
> + *
> + * This also requires that we have a non-constant symbol by which we can
> + * perform the actual initialization, and which forces the data to be
> + * allocated within writable memory. Thus "init_target_page", and we use
> + * that symbol exclusively in the two functions that initialize this value.
> + *
> + * The "target_page" symbol is created as an alias of "init_target_page".
> + */
> +static TargetPageBits init_target_page;
> +
> +/*
> + * Note that this is *not* a redundant decl, this is the definition of
> + * the "target_page" symbol. The syntax for this definition requires
> + * the use of the extern keyword. This seems to be a GCC bug in
> + * either the syntax for the alias attribute or in -Wredundant-decls.
> + *
> + * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91765
> + */
> +# pragma GCC diagnostic push
> +# pragma GCC diagnostic ignored "-Wredundant-decls"
> +
> +extern const TargetPageBits target_page
> + __attribute__((alias("init_target_page")));
> +
> +# pragma GCC diagnostic pop
> +# else
> +/*
> + * When aliases are not supported then we force two different declarations,
> + * by way of suppressing the header declaration with IN_EXEC_VARY.
> + * We assume that on such an old compiler, LTO cannot be used, and so the
> + * compiler cannot not detect the mismatched declarations, and all is well.
> + */
> +TargetPageBits target_page;
> +# define init_target_page target_page
> +# endif
> #endif
>
> bool set_preferred_target_page_bits(int bits)
> @@ -36,11 +80,11 @@ bool set_preferred_target_page_bits(int bits)
> */
> #ifdef TARGET_PAGE_BITS_VARY
> assert(bits >= TARGET_PAGE_BITS_MIN);
> - if (target_page_bits == 0 || target_page_bits > bits) {
> - if (target_page_bits_decided) {
> + if (init_target_page.bits == 0 || init_target_page.bits > bits) {
> + if (init_target_page.decided) {
> return false;
> }
> - target_page_bits = bits;
> + init_target_page.bits = bits;
> }
> #endif
> return true;
> @@ -49,9 +93,9 @@ bool set_preferred_target_page_bits(int bits)
> void finalize_target_page_bits(void)
> {
> #ifdef TARGET_PAGE_BITS_VARY
> - if (target_page_bits == 0) {
> - target_page_bits = TARGET_PAGE_BITS_MIN;
> + if (init_target_page.bits == 0) {
> + init_target_page.bits = TARGET_PAGE_BITS_MIN;
> }
> - target_page_bits_decided = true;
> + init_target_page.decided = true;
> #endif
> }
--
Alex Bennée
- Re: [PATCH v2 1/7] cpu: use ROUND_UP() to define xxx_PAGE_ALIGN, (continued)
- [PATCH v2 6/7] exec: Promote TARGET_PAGE_MASK to target_long, Richard Henderson, 2019/10/23
- [PATCH v2 5/7] exec: Restrict TARGET_PAGE_BITS_VARY assert to CONFIG_DEBUG_TCG, Richard Henderson, 2019/10/23
- [PATCH v2 7/7] exec: Cache TARGET_PAGE_MASK for TARGET_PAGE_BITS_VARY, Richard Henderson, 2019/10/23
- [PATCH v2 3/7] configure: Detect compiler support for __attribute__((alias)), Richard Henderson, 2019/10/23
- [PATCH v2 2/7] exec: Split out variable page size support to exec-vary.c, Richard Henderson, 2019/10/23
- [PATCH v2 4/7] exec: Use const alias for TARGET_PAGE_BITS_VARY, Richard Henderson, 2019/10/23
Re: [PATCH v2 0/7] exec: Improve code for TARGET_PAGE_BITS_VARY, no-reply, 2019/10/24
Re: [PATCH v2 0/7] exec: Improve code for TARGET_PAGE_BITS_VARY, Alex Bennée, 2019/10/25