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]

Aliasing safety patch


This came from discussions about the aliasing patch and makes it
conservative for language that don't handle aliasing:

Fri Jun  2 19:31:03 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* alias.c (struct alias_set_entry): New field has_zero_child.
	(mem_in_disjoint_alias_sets_p): Return 0 if set in either ase.
	(get_alias_set): If language-dependent routine set TYPE_ALIAS_SET,
	do nothing.
	Call record_component_aliases for aggregate types.
	(record_alias_subset): Set has_zero_child.
	(record_component_aliases, case ARRAY_TYPE): Do nothing if
	TYPE_NONALIASES_COMPONENT.
	(record_component_aliases, case RECORD_TYPE): Test
	DECL_NONADDRESSABLE_P.
	* c-decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead
	of TREE_ADDRESSABLE.
	* calls.c (initialize_argument_information): Only test
	TYPE_TRANSPARENT_UNION for UNION_TYPE.
	* function.c (assign_parms): Likewise.
	* integrate.c (function_cannot_inline_p): Likewise.
	* stor-layout.c (finish_record_layout): Don't call
	record_component_aliases.
	* tree.h (struct tree_int_cst): Use struct tree_common.
	(struct tree_real_cst, struct tree_string): Likewise.
	(struct tree_complex, struct tree_identifier): Likewise.
	(struct tree_list, struct tree_vec, struct tree_exp): Likewise.
	(struct tree_block, struct tree_type, struct tree_decl): Likewise.
	(TYPE_TRANSPARENT_UNION): Use UNION_TYPE_CHECK.
	(TYPE_NONALIASES_COMPONENT): New macro.
	(TYPE_AMBIENT_BOUNDEDNESS): Use FUNCTION_TYPE_CHECK.
	(DECL_NONADDRESSABLE_P): New macro.
	(struct tree_decl): Reorder bits for clarity of how many left;
	add non_adressable.
	* cp/cp-tree.h: Use struct tree_common instead of a char array.
	* cp/decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead
	of TREE_ADDRESSABLE.

*** alias.c	2000/06/01 16:18:18	1.84
--- alias.c	2000/06/02 23:12:35
*************** typedef struct alias_set_entry
*** 80,83 ****
--- 80,87 ----
       `int', `double', `float', and `struct S'.  */
    splay_tree children;
+ 
+   /* Nonzero if would have a child of zero: this effectively makes this
+      alias set the same as alias set zero.  */
+   int has_zero_child;
  } *alias_set_entry;
  
*************** mems_in_disjoint_alias_sets_p (mem1, mem
*** 244,255 ****
    /* See if the first alias set is a subset of the second.  */
    ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
!   if (ase != 0 && splay_tree_lookup (ase->children,
! 				     (splay_tree_key) MEM_ALIAS_SET (mem2)))
      return  0;
  
    /* Now do the same, but with the alias sets reversed.  */
    ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
!   if (ase != 0 && splay_tree_lookup (ase->children,
! 				     (splay_tree_key) MEM_ALIAS_SET (mem1)))
      return  0;
  
--- 248,263 ----
    /* See if the first alias set is a subset of the second.  */
    ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
!   if (ase != 0
!       && (ase->has_zero_child
! 	  || splay_tree_lookup (ase->children,
! 				(splay_tree_key) MEM_ALIAS_SET (mem2))))
      return  0;
  
    /* Now do the same, but with the alias sets reversed.  */
    ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
!   if (ase != 0
!       && (ase->has_zero_child
! 	  || splay_tree_lookup (ase->children,
! 				(splay_tree_key) MEM_ALIAS_SET (mem1))))
      return  0;
  
*************** get_alias_set (t)
*** 413,417 ****
    if (lang_get_alias_set != 0
        && (set = (*lang_get_alias_set) (t)) != -1)
!     ;
    /* There are no objects of FUNCTION_TYPE, so there's no point in
       using up an alias set for them.  (There are, of course, pointers
--- 421,430 ----
    if (lang_get_alias_set != 0
        && (set = (*lang_get_alias_set) (t)) != -1)
!     {
!       /* If the alias set is now known, we are done.  */
!       if (TYPE_ALIAS_SET_KNOWN_P (t))
! 	return TYPE_ALIAS_SET (t);
!     }
! 
    /* There are no objects of FUNCTION_TYPE, so there's no point in
       using up an alias set for them.  (There are, of course, pointers
*************** get_alias_set (t)
*** 424,427 ****
--- 437,446 ----
  
    TYPE_ALIAS_SET (t) = set;
+ 
+   /* If this is an aggregate type, we must record any component aliasing
+      information.  */
+   if (AGGREGATE_TYPE_P (t))
+     record_component_aliases (t);
+ 
    return set;
  }
*************** record_alias_subset (superset, subset)
*** 474,490 ****
  
      }
  
!   subset_entry = get_alias_set_entry (subset);
  
!   /* If there is an entry for the subset, enter all of its children
!      (if they are not already present) as children of the SUPERSET.  */
!   if (subset_entry) 
!     splay_tree_foreach (subset_entry->children,
! 			insert_subset_children,
! 			superset_entry->children);
! 
!   /* Enter the SUBSET itself as a child of the SUPERSET.  */
!   splay_tree_insert (superset_entry->children, 
! 		     (splay_tree_key) subset, 0);
  }
  
--- 493,517 ----
  
      }
+ 
+   if (subset == 0)
+     superset_entry->has_zero_child = 1;
+   else
+     {
+       subset_entry = get_alias_set_entry (subset);
+       /* If there is an entry for the subset, enter all of its children
+ 	 (if they are not already present) as children of the SUPERSET.  */
+       if (subset_entry) 
+ 	{
+ 	  if (subset_entry->has_zero_child)
+ 	    superset_entry->has_zero_child = 1;
  
! 	  splay_tree_foreach (subset_entry->children, insert_subset_children,
! 			      superset_entry->children);
! 	}
  
!       /* Enter the SUBSET itself as a child of the SUPERSET.  */
!       splay_tree_insert (superset_entry->children, 
! 			 (splay_tree_key) subset, 0);
!     }
  }
  
*************** record_component_aliases (type)
*** 500,504 ****
  {
    HOST_WIDE_INT superset = get_alias_set (type);
-   HOST_WIDE_INT subset;
    tree field;
  
--- 527,530 ----
*************** record_component_aliases (type)
*** 509,515 ****
      {
      case ARRAY_TYPE:
!       subset = get_alias_set (TREE_TYPE (type));
!       if (subset != 0)
! 	record_alias_subset (superset, subset);
        break;
  
--- 535,540 ----
      {
      case ARRAY_TYPE:
!       if (! TYPE_NONALIASED_COMPONENT (type))
! 	record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
        break;
  
*************** record_component_aliases (type)
*** 518,526 ****
      case QUAL_UNION_TYPE:
        for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
! 	{
! 	  subset = get_alias_set (TREE_TYPE (field));
! 	  if (TREE_ADDRESSABLE (field) && subset != 0 && subset != superset)
! 	    record_alias_subset (superset, subset);
! 	}
        break;
  
--- 543,548 ----
      case QUAL_UNION_TYPE:
        for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
! 	if (! DECL_NONADDRESSABLE_P (field))
! 	  record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
        break;
  
*** c-decl.c	2000/06/01 09:44:37	1.115
--- c-decl.c	2000/06/02 23:12:50
*************** grokdeclarator (declarator, declspecs, d
*** 4700,4704 ****
  	  }
  	decl = build_decl (FIELD_DECL, declarator, type);
! 	TREE_ADDRESSABLE (decl) = ! bitfield;
  	if (size_varies)
  	  C_DECL_VARIABLE_SIZE (decl) = 1;
--- 4700,4705 ----
  	  }
  	decl = build_decl (FIELD_DECL, declarator, type);
! 	DECL_NONADDRESSABLE_P (decl) = bitfield;
! 
  	if (size_varies)
  	  C_DECL_VARIABLE_SIZE (decl) = 1;
*** calls.c	2000/05/31 18:36:03	1.139
--- calls.c	2000/06/02 23:13:06
*************** initialize_argument_information (num_act
*** 1110,1114 ****
  	 pass the first field of the union.  We have already verified that
  	 the modes are the same.  */
!       if (TYPE_TRANSPARENT_UNION (type))
  	type = TREE_TYPE (TYPE_FIELDS (type));
  
--- 1110,1114 ----
  	 pass the first field of the union.  We have already verified that
  	 the modes are the same.  */
!       if (TREE_CODE (type) == UNION_TYPE && TYPE_TRANSPARENT_UNION (type))
  	type = TREE_TYPE (TYPE_FIELDS (type));
  
*** function.c	2000/05/31 18:36:03	1.202
--- function.c	2000/06/02 23:13:33
*************** assign_parms (fndecl)
*** 4232,4236 ****
  	 verified that the modes are the same.  */
        if (DECL_TRANSPARENT_UNION (parm)
! 	  || TYPE_TRANSPARENT_UNION (passed_type))
  	passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
  
--- 4232,4237 ----
  	 verified that the modes are the same.  */
        if (DECL_TRANSPARENT_UNION (parm)
! 	  || (TREE_CODE (passed_type) == UNION_TYPE
! 	      && TYPE_TRANSPARENT_UNION (passed_type)))
  	passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
  
*** integrate.c	2000/06/01 01:12:19	1.108
--- integrate.c	2000/06/02 23:13:43
*************** function_cannot_inline_p (fndecl)
*** 202,206 ****
        if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
  	return N_("function with varying-size parameter cannot be inline");
!       else if (TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
  	return N_("function with transparent unit parameter cannot be inline");
      }
--- 202,207 ----
        if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
  	return N_("function with varying-size parameter cannot be inline");
!       else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
! 	       && TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
  	return N_("function with transparent unit parameter cannot be inline");
      }
*** stor-layout.c	2000/05/31 18:36:05	1.76
--- stor-layout.c	2000/06/02 23:13:49
*************** finish_record_layout (rli)
*** 1174,1180 ****
      }
  
-   /* Show any alias subsetting we need.  */
-   record_component_aliases (rli->t);
- 
    /* Clean up.  */
    free (rli);
--- 1174,1177 ----
*** tree.h	2000/05/31 20:53:37	1.175
--- tree.h	2000/06/02 23:14:04
*************** extern void tree_class_check_failed PARA
*** 672,676 ****
  struct tree_int_cst
  {
!   char common[sizeof (struct tree_common)];
    struct rtx_def *rtl;	/* acts as link to register transfer language
  			   (rtl) info */
--- 672,676 ----
  struct tree_int_cst
  {
!   struct tree_common common;
    struct rtx_def *rtl;	/* acts as link to register transfer language
  			   (rtl) info */
*************** struct tree_int_cst
*** 696,700 ****
  struct tree_real_cst
  {
!   char common[sizeof (struct tree_common)];
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
--- 696,700 ----
  struct tree_real_cst
  {
!   struct tree_common common;
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
*************** struct tree_real_cst
*** 708,712 ****
  struct tree_string
  {
!   char common[sizeof (struct tree_common)];
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
--- 708,712 ----
  struct tree_string
  {
!   struct tree_common common;
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
*************** struct tree_string
*** 721,725 ****
  struct tree_complex
  {
!   char common[sizeof (struct tree_common)];
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
--- 721,725 ----
  struct tree_complex
  {
!   struct tree_common common;
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
*************** struct tree_complex
*** 735,739 ****
  struct tree_identifier
  {
!   char common[sizeof (struct tree_common)];
    int length;
    char *pointer;
--- 735,739 ----
  struct tree_identifier
  {
!   struct tree_common common;
    int length;
    char *pointer;
*************** struct tree_identifier
*** 746,750 ****
  struct tree_list
  {
!   char common[sizeof (struct tree_common)];
    union tree_node *purpose;
    union tree_node *value;
--- 746,750 ----
  struct tree_list
  {
!   struct tree_common common;
    union tree_node *purpose;
    union tree_node *value;
*************** struct tree_list
*** 758,762 ****
  struct tree_vec
  {
!   char common[sizeof (struct tree_common)];
    int length;
    union tree_node *a[1];
--- 758,762 ----
  struct tree_vec
  {
!   struct tree_common common;
    int length;
    union tree_node *a[1];
*************** struct tree_vec
*** 814,818 ****
  struct tree_exp
  {
!   char common[sizeof (struct tree_common)];
    int complexity;
    union tree_node *operands[1];
--- 814,818 ----
  struct tree_exp
  {
!   struct tree_common common;
    int complexity;
    union tree_node *operands[1];
*************** struct tree_exp
*** 840,844 ****
  struct tree_block
  {
!   char common[sizeof (struct tree_common)];
  
    unsigned handler_block_flag : 1;
--- 840,844 ----
  struct tree_block
  {
!   struct tree_common common;
  
    unsigned handler_block_flag : 1;
*************** struct tree_block
*** 1008,1017 ****
  /* Indicates that objects of this type must be initialized by calling a
     function when they are created.  */
! #define TYPE_NEEDS_CONSTRUCTING(NODE) (TYPE_CHECK (NODE)->type.needs_constructing_flag)
  
  /* Indicates that objects of this type (a UNION_TYPE), should be passed
     the same way that the first union alternative would be passed.  */
! #define TYPE_TRANSPARENT_UNION(NODE) (TYPE_CHECK (NODE)->type.transparent_union_flag)
  
  /* Indicated that objects of this type should be laid out in as
     compact a way as possible.  */
--- 1008,1024 ----
  /* Indicates that objects of this type must be initialized by calling a
     function when they are created.  */
! #define TYPE_NEEDS_CONSTRUCTING(NODE) \
!   (TYPE_CHECK (NODE)->type.needs_constructing_flag)
  
  /* Indicates that objects of this type (a UNION_TYPE), should be passed
     the same way that the first union alternative would be passed.  */
! #define TYPE_TRANSPARENT_UNION(NODE)  \
!   (UNION_TYPE_CHECK (NODE)->type.transparent_union_flag)
  
+ /* For an ARRAY_TYPE, indicates that it is not permitted to
+    take the address of a component of the type.  */
+ #define TYPE_NONALIASED_COMPONENT(NODE) \
+   (ARRAY_TYPE_CHECK (NODE)->type.transparent_union_flag)
+ 
  /* Indicated that objects of this type should be laid out in as
     compact a way as possible.  */
*************** struct tree_block
*** 1071,1076 ****
     useful for choosing default boundedness of function arguments for
     non-prototype function decls and for varargs/stdarg lists.  */
! 
! #define TYPE_AMBIENT_BOUNDEDNESS(TYPE) (TYPE_CHECK (TYPE)->type.transparent_union_flag)
  
  #define MAX_POINTER_DEPTH 2
--- 1078,1083 ----
     useful for choosing default boundedness of function arguments for
     non-prototype function decls and for varargs/stdarg lists.  */
! #define TYPE_AMBIENT_BOUNDEDNESS(TYPE) \
!   (FUNCTION_TYPE_CHECK (TYPE)->type.transparent_union_flag)
  
  #define MAX_POINTER_DEPTH 2
*************** struct tree_block
*** 1079,1083 ****
  struct tree_type
  {
!   char common[sizeof (struct tree_common)];
    union tree_node *values;
    union tree_node *size;
--- 1086,1090 ----
  struct tree_type
  {
!   struct tree_common common;
    union tree_node *values;
    union tree_node *size;
*************** struct tree_type
*** 1523,1526 ****
--- 1530,1538 ----
  #define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
  
+ /* Used in a FIELD_DECL to indicate that we cannot form the address of
+    this component.  */
+ #define DECL_NONADDRESSABLE_P(NODE) \
+   (FIELD_DECL_CHECK (NODE)->decl.non_addressable)
+ 
  /* Used to indicate an alias set for the memory pointed to by this
     particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have
*************** struct tree_type
*** 1545,1549 ****
  struct tree_decl
  {
!   char common[sizeof (struct tree_common)];
    const char *filename;
    int linenum;
--- 1557,1561 ----
  struct tree_decl
  {
!   struct tree_common common;
    const char *filename;
    int linenum;
*************** struct tree_decl
*** 1576,1582 ****
    unsigned malloc_flag : 1;
    unsigned no_limit_stack : 1;
-   unsigned pure_flag : 1;
    ENUM_BITFIELD(built_in_class) built_in_class : 2;
    unsigned pointer_depth : 2;
  
    unsigned lang_flag_0 : 1;
--- 1588,1597 ----
    unsigned malloc_flag : 1;
    unsigned no_limit_stack : 1;
    ENUM_BITFIELD(built_in_class) built_in_class : 2;
+ 
+   unsigned pure_flag : 1;
    unsigned pointer_depth : 2;
+   unsigned non_addressable : 1;
+   /* Four unused bits.  */
  
    unsigned lang_flag_0 : 1;
*** cp/cp-tree.h	2000/06/02 05:45:34	1.469
--- cp/cp-tree.h	2000/06/02 23:14:26
*************** typedef struct 
*** 300,304 ****
  typedef struct 
  {
!   char common[sizeof (struct tree_common)];
    HOST_WIDE_INT index;
    HOST_WIDE_INT level;
--- 300,304 ----
  typedef struct 
  {
!   struct tree_common common;
    HOST_WIDE_INT index;
    HOST_WIDE_INT level;
*************** typedef struct 
*** 309,313 ****
  typedef struct ptrmem_cst
  {
!   char common[sizeof (struct tree_common)];
    /* This isn't used, but the middle-end expects all constants to have 
       this field.  */
--- 309,313 ----
  typedef struct ptrmem_cst
  {
!   struct tree_common common;
    /* This isn't used, but the middle-end expects all constants to have 
       this field.  */
*************** typedef struct ptrmem_cst
*** 352,356 ****
  struct tree_binding
  {
!   char common[sizeof (struct tree_common)];
    union {
      tree scope;
--- 352,356 ----
  struct tree_binding
  {
!   struct tree_common common;
    union {
      tree scope;
*************** struct tree_binding
*** 375,379 ****
  struct tree_overload
  {
!   char common[sizeof (struct tree_common)];
    tree function;
  };
--- 375,379 ----
  struct tree_overload
  {
!   struct tree_common common;
    tree function;
  };
*************** struct tree_overload
*** 392,396 ****
  struct tree_wrapper
  {
!   char common[sizeof (struct tree_common)];
    union {
      void *ptr;
--- 392,396 ----
  struct tree_wrapper
  {
!   struct tree_common common;
    union {
      void *ptr;
*************** struct tree_wrapper
*** 403,407 ****
  struct tree_srcloc
  {
!   char common[sizeof (struct tree_common)];
    const char *filename;
    int linenum;
--- 403,407 ----
  struct tree_srcloc
  {
!   struct tree_common common;
    const char *filename;
    int linenum;
*** cp/decl.c	2000/06/02 19:38:35	1.622
--- cp/decl.c	2000/06/02 23:15:15
*************** grokdeclarator (declarator, declspecs, d
*** 11597,11601 ****
  	      {
  		decl = build_decl (FIELD_DECL, declarator, type);
! 		TREE_ADDRESSABLE (decl) = ! bitfield;
  		if (RIDBIT_SETP (RID_MUTABLE, specbits))
  		  {
--- 11597,11601 ----
  	      {
  		decl = build_decl (FIELD_DECL, declarator, type);
! 		DECL_NONADDRESSABLE_P (decl) = bitfield;
  		if (RIDBIT_SETP (RID_MUTABLE, specbits))
  		  {

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