This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Improve TBAA with unions
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, jason at redhat dot com
- Date: Tue, 24 May 2016 11:14:58 +0200 (CEST)
- Subject: Re: [PATCH] Improve TBAA with unions
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 11 dot 1605181258160 dot 18037 at t29 dot fhfr dot qr>
On Wed, 18 May 2016, Richard Biener wrote:
>
> The following adjusts get_alias_set beahvior when applied to
> union accesses to use the union alias-set rather than alias-set
> zero. This is in line with behavior from the alias oracle
> which (bogously) circumvents alias-set zero with looking at
> the alias-sets of the base object. Thus for
>
> union U { int i; float f; };
>
> float
> foo (union U *u, double *p)
> {
> u->f = 1.;
> *p = 0;
> return u->f;
> }
>
> the langhooks ensured u->f has alias-set zero and thus disambiguation
> against *p was not allowed. Still the alias-oracle did the disambiguation
> by using the alias set of the union here (I think optimizing the
> return to return 1. is valid).
>
> We have a good place in the middle-end to apply such rules which
> is component_uses_parent_alias_set_from - this is where I move
> the logic that is duplicated in various frontends.
>
> The Java and Ada frontends do not allow union type punning (LTO does),
> so this patch may eventually pessimize them. I don't care anything
> about Java but Ada folks might want to chime in.
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
>
> Ok for trunk?
Ping.
Thanks,
Richard.
> Thanks,
> Richard.
>
> 2016-05-18 Richard Biener <rguenther@suse.de>
>
> * alias.c (component_uses_parent_alias_set_from): Handle
> type punning through union accesses by using the union alias set.
> * gimple.c (gimple_get_alias_set): Remove union type punning case.
>
> c-family/
> * c-common.c (c_common_get_alias_set): Remove union type punning case.
>
> fortran/
> * f95-lang.c (LANG_HOOKS_GET_ALIAS_SET): Remove (un-)define.
> (gfc_get_alias_set): Remove.
>
>
> Index: trunk/gcc/alias.c
> ===================================================================
> *** trunk.orig/gcc/alias.c 2016-05-18 11:15:41.744792403 +0200
> --- trunk/gcc/alias.c 2016-05-18 11:31:40.139709782 +0200
> *************** component_uses_parent_alias_set_from (co
> *** 619,624 ****
> --- 619,632 ----
> case COMPONENT_REF:
> if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)))
> found = t;
> + /* Permit type-punning when accessing a union, provided the access
> + is directly through the union. For example, this code does not
> + permit taking the address of a union member and then storing
> + through it. Even the type-punning allowed here is a GCC
> + extension, albeit a common and useful one; the C standard says
> + that such accesses have implementation-defined behavior. */
> + else if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
> + found = t;
> break;
>
> case ARRAY_REF:
> Index: trunk/gcc/c-family/c-common.c
> ===================================================================
> *** trunk.orig/gcc/c-family/c-common.c 2016-05-18 11:15:41.744792403 +0200
> --- trunk/gcc/c-family/c-common.c 2016-05-18 11:31:40.143709828 +0200
> *************** static GTY(()) hash_table<c_type_hasher>
> *** 4734,4741 ****
> alias_set_type
> c_common_get_alias_set (tree t)
> {
> - tree u;
> -
> /* For VLAs, use the alias set of the element type rather than the
> default of alias set 0 for types compared structurally. */
> if (TYPE_P (t) && TYPE_STRUCTURAL_EQUALITY_P (t))
> --- 4734,4739 ----
> *************** c_common_get_alias_set (tree t)
> *** 4745,4763 ****
> return -1;
> }
>
> - /* Permit type-punning when accessing a union, provided the access
> - is directly through the union. For example, this code does not
> - permit taking the address of a union member and then storing
> - through it. Even the type-punning allowed here is a GCC
> - extension, albeit a common and useful one; the C standard says
> - that such accesses have implementation-defined behavior. */
> - for (u = t;
> - TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
> - u = TREE_OPERAND (u, 0))
> - if (TREE_CODE (u) == COMPONENT_REF
> - && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
> - return 0;
> -
> /* That's all the expressions we handle specially. */
> if (!TYPE_P (t))
> return -1;
> --- 4743,4748 ----
> Index: trunk/gcc/fortran/f95-lang.c
> ===================================================================
> *** trunk.orig/gcc/fortran/f95-lang.c 2016-05-18 11:15:41.744792403 +0200
> --- trunk/gcc/fortran/f95-lang.c 2016-05-18 11:31:48.623806334 +0200
> *************** static bool global_bindings_p (void);
> *** 74,80 ****
> static bool gfc_init (void);
> static void gfc_finish (void);
> static void gfc_be_parse_file (void);
> - static alias_set_type gfc_get_alias_set (tree);
> static void gfc_init_ts (void);
> static tree gfc_builtin_function (tree);
>
> --- 74,79 ----
> *************** static const struct attribute_spec gfc_a
> *** 110,116 ****
> #undef LANG_HOOKS_MARK_ADDRESSABLE
> #undef LANG_HOOKS_TYPE_FOR_MODE
> #undef LANG_HOOKS_TYPE_FOR_SIZE
> - #undef LANG_HOOKS_GET_ALIAS_SET
> #undef LANG_HOOKS_INIT_TS
> #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
> #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
> --- 109,114 ----
> *************** static const struct attribute_spec gfc_a
> *** 142,148 ****
> #define LANG_HOOKS_PARSE_FILE gfc_be_parse_file
> #define LANG_HOOKS_TYPE_FOR_MODE gfc_type_for_mode
> #define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size
> - #define LANG_HOOKS_GET_ALIAS_SET gfc_get_alias_set
> #define LANG_HOOKS_INIT_TS gfc_init_ts
> #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE gfc_omp_privatize_by_reference
> #define LANG_HOOKS_OMP_PREDETERMINED_SHARING gfc_omp_predetermined_sharing
> --- 140,145 ----
> *************** gfc_init_decl_processing (void)
> *** 503,526 ****
> }
>
>
> - /* Return the typed-based alias set for T, which may be an expression
> - or a type. Return -1 if we don't do anything special. */
> -
> - static alias_set_type
> - gfc_get_alias_set (tree t)
> - {
> - tree u;
> -
> - /* Permit type-punning when accessing an EQUIVALENCEd variable or
> - mixed type entry master's return value. */
> - for (u = t; handled_component_p (u); u = TREE_OPERAND (u, 0))
> - if (TREE_CODE (u) == COMPONENT_REF
> - && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
> - return 0;
> -
> - return -1;
> - }
> -
> /* Builtin function initialization. */
>
> static tree
> --- 500,505 ----
> Index: trunk/gcc/gimple.c
> ===================================================================
> *** trunk.orig/gcc/gimple.c 2016-05-18 11:15:41.744792403 +0200
> --- trunk/gcc/gimple.c 2016-05-18 11:31:40.143709828 +0200
> *************** gimple_signed_type (tree type)
> *** 2396,2416 ****
> alias_set_type
> gimple_get_alias_set (tree t)
> {
> - tree u;
> -
> - /* Permit type-punning when accessing a union, provided the access
> - is directly through the union. For example, this code does not
> - permit taking the address of a union member and then storing
> - through it. Even the type-punning allowed here is a GCC
> - extension, albeit a common and useful one; the C standard says
> - that such accesses have implementation-defined behavior. */
> - for (u = t;
> - TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
> - u = TREE_OPERAND (u, 0))
> - if (TREE_CODE (u) == COMPONENT_REF
> - && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
> - return 0;
> -
> /* That's all the expressions we handle specially. */
> if (!TYPE_P (t))
> return -1;
> --- 2396,2401 ----
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)