Add lang hook for suppressing type hashing and related cleanups

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Fri Mar 19 14:36:00 GMT 2004


Ada doesn't want type hashing to be done, but suppressed it using a debug
hack.  This adds a language hook that provides a clean way of doing it.

I also took this opportunity to clean up some old comments and obsolete code
and to fix more small bugs visible by inspection in code related to this.

Tested on x84-64-linux.

2004-03-19  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* langhooks-def.h (LANG_HOOKS_HASH_TYPES): New macro and hook.
	* langhooks.h (struct lang_hooks_for_types): New field hash_types.
	* tree.c (debug_no_type_hash): Deleted.
	(type_hash_canon): Abort if passed a variant.
	Check lang_hooks.types.hash_types.
	(build_type_no_quals): Copy mode of POINTER_TYPE and REFERENCE_TYPE.
	(build_array_type): Remove unnecessary allocation of pointer type.
	(build_complex_type): Properly qualify resulting type.

	* ada/decl.c (debug_no_type_hash): Remove.
	(gnat_to_gnu_entity, case E_Array_Type): Don't set and clear it.
	* ada/misc.c (LANG_HOOK_HASH_TYPE): Redefine.

*** langhooks-def.h	3 Mar 2004 11:25:48 -0000	1.74
--- langhooks-def.h	19 Mar 2004 02:53:43 -0000
*************** extern tree lhd_make_node (enum tree_cod
*** 223,226 ****
--- 223,227 ----
  #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
  #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
+ #define LANG_HOOKS_HASH_TYPES		true
  
  #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
*************** extern tree lhd_make_node (enum tree_cod
*** 233,237 ****
    LANG_HOOKS_TYPE_PROMOTES_TO, \
    LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
!   LANG_HOOKS_INCOMPLETE_TYPE_ERROR \
  }
  
--- 234,239 ----
    LANG_HOOKS_TYPE_PROMOTES_TO, \
    LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
!   LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
!   LANG_HOOKS_HASH_TYPES \
  }
  
*** langhooks.h	12 Feb 2004 21:42:24 -0000	1.80
--- langhooks.h	19 Mar 2004 02:53:46 -0000
*************** struct lang_hooks_for_types
*** 152,155 ****
--- 152,160 ----
       invalid.  */
    void (*incomplete_type_error) (tree value, tree type);
+ 
+   /* Nonzero if types that are identical are to be hashed so that only
+      one copy is kept.  If a language requires unique types for each
+      user-specified type, such as Ada, this should be set to TRUE.  */
+   bool hash_types;
  };
  
*** tree.c	18 Mar 2004 21:19:56 -0000	1.356
--- tree.c	19 Mar 2004 02:53:53 -0000
*************** type_hash_add (hashval_t hashcode, tree 
*** 3219,3233 ****
  /* Given TYPE, and HASHCODE its hash code, return the canonical
     object for an identical type if one already exists.
!    Otherwise, return TYPE, and record it as the canonical object
!    if it is a permanent object.
  
     To use this function, first create a type of the sort you want.
     Then compute its hash code from the fields of the type that
     make it different from other similar types.
!    Then call this function and use the value.
!    This function frees the type you pass in if it is a duplicate.  */
! 
! /* Set to 1 to debug without canonicalization.  Never set by program.  */
! int debug_no_type_hash = 0;
  
  tree
--- 3219,3228 ----
  /* Given TYPE, and HASHCODE its hash code, return the canonical
     object for an identical type if one already exists.
!    Otherwise, return TYPE, and record it as the canonical object.
  
     To use this function, first create a type of the sort you want.
     Then compute its hash code from the fields of the type that
     make it different from other similar types.
!    Then call this function and use the value.  */
  
  tree
*************** type_hash_canon (unsigned int hashcode, 
*** 3236,3240 ****
    tree t1;
  
!   if (debug_no_type_hash)
      return type;
  
--- 3231,3240 ----
    tree t1;
  
!   /* The hash table only contains main variants, so ensure that's what we're
!      being passed.  */
!   if (TYPE_MAIN_VARIANT (type) != type)
!     abort ();
! 
!   if (!lang_hooks.types.hash_types)
      return type;
  
*************** build_type_no_quals (tree t)
*** 3932,3938 ****
      {
      case POINTER_TYPE:
!       return build_pointer_type (build_type_no_quals (TREE_TYPE (t)));
      case REFERENCE_TYPE:
!       return build_reference_type (build_type_no_quals (TREE_TYPE (t)));
      default:
        return TYPE_MAIN_VARIANT (t);
--- 3932,3941 ----
      {
      case POINTER_TYPE:
!       return build_pointer_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
! 					  TYPE_MODE (t));
      case REFERENCE_TYPE:
!       return
! 	build_reference_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
! 				       TYPE_MODE (t));
      default:
        return TYPE_MAIN_VARIANT (t);
*************** build_array_type (tree elt_type, tree in
*** 4027,4035 ****
      }
  
-   /* Make sure TYPE_POINTER_TO (elt_type) is filled in.  */
-   build_pointer_type (elt_type);
- 
-   /* Allocate the array after the pointer type,
-      in case we free it in type_hash_canon.  */
    t = make_node (ARRAY_TYPE);
    TREE_TYPE (t) = elt_type;
--- 4030,4033 ----
*************** build_array_type (tree elt_type, tree in
*** 4037,4043 ****
  
    if (index_type == 0)
!     {
!       return t;
!     }
  
    hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
--- 4035,4039 ----
  
    if (index_type == 0)
!     return t;
  
    hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
*************** build_function_type (tree value_type, tr
*** 4088,4092 ****
    TYPE_ARG_TYPES (t) = arg_types;
  
!   /* If we already have such a type, use the old one and free this one.  */
    hashcode = iterative_hash_object (TYPE_HASH (value_type), hashcode);
    hashcode = type_hash_list (arg_types, hashcode);
--- 4084,4088 ----
    TYPE_ARG_TYPES (t) = arg_types;
  
!   /* If we already have such a type, use the old one.  */
    hashcode = iterative_hash_object (TYPE_HASH (value_type), hashcode);
    hashcode = type_hash_list (arg_types, hashcode);
*************** build_method_type_directly (tree basetyp
*** 4150,4159 ****
    TYPE_ARG_TYPES (t) = argtypes;
  
!   /* If we already have such a type, use the old one and free this one.
!      Note that it also frees up the above cons cell if found.  */
    hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
    hashcode = iterative_hash_object (TYPE_HASH (rettype), hashcode);
    hashcode = type_hash_list (argtypes, hashcode);
- 
    t = type_hash_canon (hashcode, t);
  
--- 4146,4153 ----
    TYPE_ARG_TYPES (t) = argtypes;
  
!   /* If we already have such a type, use the old one.  */
    hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
    hashcode = iterative_hash_object (TYPE_HASH (rettype), hashcode);
    hashcode = type_hash_list (argtypes, hashcode);
    t = type_hash_canon (hashcode, t);
  
*************** build_offset_type (tree basetype, tree t
*** 4196,4200 ****
    TREE_TYPE (t) = type;
  
!   /* If we already have such a type, use the old one and free this one.  */
    hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
    hashcode = iterative_hash_object (TYPE_HASH (type), hashcode);
--- 4190,4194 ----
    TREE_TYPE (t) = type;
  
!   /* If we already have such a type, use the old one.  */
    hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
    hashcode = iterative_hash_object (TYPE_HASH (type), hashcode);
*************** build_complex_type (tree component_type)
*** 4219,4225 ****
  
    TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
-   set_type_quals (t, TYPE_QUALS (component_type));
  
!   /* If we already have such a type, use the old one and free this one.  */
    hashcode = iterative_hash_object (TYPE_HASH (component_type), 0);
    t = type_hash_canon (hashcode, t);
--- 4213,4218 ----
  
    TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
  
!   /* If we already have such a type, use the old one.  */
    hashcode = iterative_hash_object (TYPE_HASH (component_type), 0);
    t = type_hash_canon (hashcode, t);
*************** build_complex_type (tree component_type)
*** 4263,4267 ****
      }
  
!   return t;
  }
  
--- 4256,4260 ----
      }
  
!   return build_qualified_type (t, TYPE_QUALS (component_type));
  }
  
  
*** ada/decl.c	19 Mar 2004 11:37:31 -0000	1.63.2.43
--- ada/decl.c	19 Mar 2004 13:13:43 -0000
***************
*** 53,59 ****
  #include "gigi.h"
  
- /* Setting this to 1 suppresses hashing of types.  */
- extern int debug_no_type_hash;
- 
  /* Provide default values for the macros controlling stack checking.
     This is copied from GCC's expr.h.  */
--- 53,56 ----
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 1929,1937 ****
  				     TYPE_SIZE (gnu_type));
  
- 	  /* We don't want any array types shared for two reasons: first,
- 	     we want to keep differently-named types distinct; second,
- 	     setting TYPE_MULTI_ARRAY_TYPE of one type can clobber
- 	     another.  */
- 	  debug_no_type_hash = 1;
  	  for (index = array_dim - 1; index >= 0; index --)
  	    {
--- 1926,1929 ----
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 2006,2010 ****
  	    }
  
- 	  debug_no_type_hash = 0;
  	  TYPE_CONVENTION_FORTRAN_P (gnu_type)
  	    = (Convention (gnat_entity) == Convention_Fortran);
--- 1998,2001 ----
*** ada/misc.c	20 Feb 2004 10:28:02 -0000	1.44.2.33
--- ada/misc.c	19 Mar 2004 13:13:50 -0000
*************** static void internal_error_function	(con
*** 102,106 ****
  static void gnat_adjust_rli		(record_layout_info);
  
! /* Structure giving our language-specific hooks.  */
  
  #undef  LANG_HOOKS_NAME
--- 102,106 ----
  static void gnat_adjust_rli		(record_layout_info);
  
! /* Definitions for our language-specific hooks.  */
  
  #undef  LANG_HOOKS_NAME
*************** static void gnat_adjust_rli		(record_lay
*** 119,123 ****
  #define LANG_HOOKS_PARSE_FILE		gnat_parse_file
  #undef LANG_HOOKS_HONOR_READONLY
! #define LANG_HOOKS_HONOR_READONLY	1
  #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
  #define LANG_HOOKS_FINISH_INCOMPLETE_DECL gnat_finish_incomplete_decl
--- 119,125 ----
  #define LANG_HOOKS_PARSE_FILE		gnat_parse_file
  #undef LANG_HOOKS_HONOR_READONLY
! #define LANG_HOOKS_HONOR_READONLY	true
! #undef LANG_HOOKS_HASH_TYPES
! #define LANG_HOOKS_HASH_TYPES		false
  #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
  #define LANG_HOOKS_FINISH_INCOMPLETE_DECL gnat_finish_incomplete_decl



More information about the Gcc-patches mailing list