[PATCH][LTO] register char_type_node

Richard Guenther rguenther@suse.de
Fri Aug 14 15:23:00 GMT 2009


On Fri, 14 Aug 2009, Diego Novillo wrote:

> On Fri, Aug 14, 2009 at 10:42, Richard Guenther<rguenther@suse.de> wrote:
> 
> > Yeah.  I was wondering whether we shouldn't register all types
> > we preload the streamer cache with early - that would also make
> > us canonicalize to the integer type variants with the pretty names,
> > not this <unnamed-signed:8> crap I see everywhere around ...
> 
> Oh, good idea!  Yes, that would help quite a bit.

I am testing the following.  The 2nd hunk is the CONST_CAST2 issue - the
IL that is considered valid by the middle-end depends on alias set
compatibility of pointed-to types.  So we should follow the C frontend
here assigning const char * and char * the same alias set.  That
fixes the collect2 build.

Richard.

2009-08-14  Richard Guenther  <rguenther@suse.de>

	* lto-streamer.c (lto_get_common_nodes): Register the common
	types.
	* gimple.c (gimple_get_alias_set): Pointers with different
	qualifiers get the same alias set.

Index: gcc/lto-streamer.c
===================================================================
*** gcc/lto-streamer.c	(revision 150751)
--- gcc/lto-streamer.c	(working copy)
*************** lto_record_common_node (tree node, VEC(t
*** 686,692 ****
  }
  
  
! /* Generate a vector of common nodes. */
  
  static VEC(tree,heap) *
  lto_get_common_nodes (void)
--- 686,693 ----
  }
  
  
! /* Generate a vector of common nodes and register them in the gimple
!    type table as merge targets. */
  
  static VEC(tree,heap) *
  lto_get_common_nodes (void)
*************** lto_get_common_nodes (void)
*** 718,732 ****
    gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
    
    seen_nodes = pointer_set_create ();
!   
    for (i = 0; i < TI_MAX; i++)
!     lto_record_common_node (global_trees[i], &common_nodes, seen_nodes);
  
    for (i = 0; i < itk_none; i++)
!     lto_record_common_node (integer_types[i], &common_nodes, seen_nodes);
  
    for (i = 0; i < TYPE_KIND_LAST; i++)
!     lto_record_common_node (sizetype_tab[i], &common_nodes, seen_nodes);
  
    pointer_set_destroy (seen_nodes);
  
--- 719,753 ----
    gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
    
    seen_nodes = pointer_set_create ();
! 
!   /* char_type_node is special, we have to prefer merging the other
!      char variants into it because the middle-end has pointer comparisons
!      with it.  */
!   gimple_register_type (char_type_node);
! 
    for (i = 0; i < TI_MAX; i++)
!     {
!       tree t = global_trees[i];
!       if (t && TYPE_P (t))
! 	gimple_register_type (t);
!       lto_record_common_node (global_trees[i], &common_nodes, seen_nodes);
!     }
  
    for (i = 0; i < itk_none; i++)
!     {
!       tree t = integer_types[i];
!       if (t && TYPE_P (t))
! 	gimple_register_type (t);
!       lto_record_common_node (integer_types[i], &common_nodes, seen_nodes);
!     }
  
    for (i = 0; i < TYPE_KIND_LAST; i++)
!     {
!       tree t = sizetype_tab[i];
!       if (t && TYPE_P (t))
! 	gimple_register_type (t);
!       lto_record_common_node (sizetype_tab[i], &common_nodes, seen_nodes);
!     }
  
    pointer_set_destroy (seen_nodes);
  
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c	(revision 150751)
--- gcc/gimple.c	(working copy)
*************** gimple_get_alias_set (tree t)
*** 4153,4158 ****
--- 4153,4188 ----
        if (t1 != t)
  	return get_alias_set (t1);
      }
+   else if (POINTER_TYPE_P (t))
+     {
+       tree t1;
+ 
+       /* Unfortunately, there is no canonical form of a pointer type.
+ 	 In particular, if we have `typedef int I', then `int *', and
+ 	 `I *' are different types.  So, we have to pick a canonical
+ 	 representative.  We do this below.
+ 
+ 	 Technically, this approach is actually more conservative that
+ 	 it needs to be.  In particular, `const int *' and `int *'
+ 	 should be in different alias sets, according to the C and C++
+ 	 standard, since their types are not the same, and so,
+ 	 technically, an `int **' and `const int **' cannot point at
+ 	 the same thing.
+ 
+ 	 But, the standard is wrong.  In particular, this code is
+ 	 legal C++:
+ 
+ 	 int *ip;
+ 	 int **ipp = &ip;
+ 	 const int* const* cipp = ipp;
+ 	 And, it doesn't make sense for that to be legal unless you
+ 	 can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
+ 	 the pointed-to types.  This issue has been reported to the
+ 	 C++ committee.  */
+       t1 = build_type_no_quals (t);
+       if (t1 != t)
+ 	return get_alias_set (t1);
+     }
  
    return -1;
  }


More information about the Gcc-patches mailing list