This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Improve TBAA with unions


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?

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 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]