public inbox for java-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC/RFT] Remove CHAR_TYPE tree code.
@ 2006-01-27 22:40 Roger Sayle
  2006-01-28  0:07 ` Tom Tromey
  0 siblings, 1 reply; 5+ messages in thread
From: Roger Sayle @ 2006-01-27 22:40 UTC (permalink / raw)
  To: java-patches; +Cc: gcc-patches


The following patch to the java front-end is an attempt to reduce
the number of tree codes used in GCC.  The tree code CHAR_TYPE is
used to represent a form of integer type specific to the Java
front-end, but is defined in gcc/tree.def as expressions of these
types need to be folded, expanded and tree-ssa optimized by the
middle-end.

The reason that this tree code is a candidate for deprecation
is that only two trees with this tree code are ever created by
GCC, or more specifically gcj, that correspond to the trees
char_type_node and promoted_char_type_node in the java front-end,
and typically these trees are treated identically to the equivalent
INTEGER_TYPE trees.

It transpires that the middle-end never creates types from scratch,
and the java front-ends lang_hooks for signed_type, unsigned_type,
etc... always return an INTEGER_TYPE result for a CHAR_TYPE
argument.  Given that CHAR_TYPE is only used in a small handfull
of places in the Java front-end, its trivial to replace the
CHAR_TYPE processing with special case tests of the form
"type == char_type_node || type == promoted_char_type_node" in
the INTEGER_TYPE handling cases.

An alternate strategy might be to use one of the lang_flags on
INTEGER_TYPE nodes.  Admittedly, if the rest of GCC could handle
512 or 65536 unique tree codes this would be a non-issue, and
Java would be free to use a unique TREE_CODE to indicate these
specific trees, but alas tree codes are a rapidly dwindling
resource.

One benefit of the elimination of CHAR_TYPE from Java, is that
it permits a modest clean-up of the middle-end (and even other
front-ends) where we no longer have to explicitly treat CHAR_TYPE
just like INTEGER_TYPE.  This should be a very minor win on compiler
code size and compile-time.


Attached below are two patches.  The first placed "gcc_assert"s
throughout the java front-end to check that CHAR_TYPE implies
that the tree is either char_type_node or promoted_char_type_node.
This was bootstrapped and regression tested on i686-pc-linux-gnu
to confirm the "only two nodes" hypothesis above.  The second
patch completely removes the use of CHAR_TYPE from the java front
end, by creating char_type_node and promoted_char_type_node as
regular INTEGER_TYPE nodes, but testing for them explicitly when
required by name mangling, etc...  This second patch has the
possibility of further clean-ups, as char_type_node always has
a TYPE_PRECISION of 16, and promoted_char_type_node always has
a TYPE_PRECISION of 32, and the some of the few differences in
behaviour between CHAR_TYPE and INTEGER_TYPE may have been
unintentional.  However, this patch as written should have no
change in behaviour.


Thoughts?  I was wondering whether someone could test JACKS
and eclipse, etc... with one or both of the below patches to
confirm that CHAR_TYPE really doesn't have to be a unique
tree code.  The first patch is just for ease of mind, whilst
the second is the real proposed change for mainline.  As
mentioned above both have been bootstrapped and regression
tested against mainline with no new failures.

Thanks in advance,


2006-01-27  Roger Sayle  <roger@eyesopen.com>

	* jcf-write.c: Assert that the only CHAR_TYPE nodes are the trees
	char_type_node and promoted_char_type_node.
	* mangle.c (mangle_type): Likewise.
	* typeck.c (convert, promote_type,build_java_signature): Likewise.

Index: jcf-write.c
===================================================================
*** jcf-write.c	(revision 110176)
--- jcf-write.c	(working copy)
*************** adjust_typed_op (tree type, int max)
*** 882,887 ****
--- 882,888 ----
      case BOOLEAN_TYPE:
        return TYPE_PRECISION (type) == 32 || max < 5 ? 0 : 5;
      case CHAR_TYPE:
+       gcc_assert (type == char_type_node || type == promoted_char_type_node);
        return TYPE_PRECISION (type) == 32 || max < 6 ? 0 : 6;
      case INTEGER_TYPE:
        switch (TYPE_PRECISION (type))
Index: mangle.c
===================================================================
*** mangle.c	(revision 110176)
--- mangle.c	(working copy)
*************** mangle_type (tree type)
*** 243,249 ****
      {
        char code;
      case BOOLEAN_TYPE: code = 'b';  goto primitive;
!     case CHAR_TYPE:    code = 'w';  goto primitive;
      case VOID_TYPE:    code = 'v';  goto primitive;
      case INTEGER_TYPE:
        /* Get the original type instead of the arguments promoted type.
--- 243,251 ----
      {
        char code;
      case BOOLEAN_TYPE: code = 'b';  goto primitive;
!     case CHAR_TYPE:
!       gcc_assert (type == char_type_node || type == promoted_char_type_node);
!       code = 'w';  goto primitive;
      case VOID_TYPE:    code = 'v';  goto primitive;
      case INTEGER_TYPE:
        /* Get the original type instead of the arguments promoted type.
Index: typeck.c
===================================================================
*** typeck.c	(revision 110176)
--- typeck.c	(working copy)
*************** convert (tree type, tree expr)
*** 126,133 ****
      return error_mark_node;
    if (code == VOID_TYPE)
      return build1 (CONVERT_EXPR, type, expr);
!   if (code == BOOLEAN_TYPE || code ==  CHAR_TYPE)
      return fold_convert (type, expr);
    if (code == INTEGER_TYPE)
      {
        if ((really_constant_p (expr)
--- 126,138 ----
      return error_mark_node;
    if (code == VOID_TYPE)
      return build1 (CONVERT_EXPR, type, expr);
!   if (code == BOOLEAN_TYPE)
      return fold_convert (type, expr);
+   if (code ==  CHAR_TYPE)
+     {
+       gcc_assert (type == char_type_node || type == promoted_char_type_node);
+       return fold_convert (type, expr);
+     }
    if (code == INTEGER_TYPE)
      {
        if ((really_constant_p (expr)
*************** promote_type (tree type)
*** 432,437 ****
--- 437,443 ----
  	return promoted_boolean_type_node;
        goto handle_int;
      case CHAR_TYPE:
+       gcc_assert (type == char_type_node || type == promoted_char_type_node);
        if (type == char_type_node)
  	return promoted_char_type_node;
        goto handle_int;
*************** build_java_signature (tree type)
*** 605,611 ****
        switch (TREE_CODE (type))
  	{
  	case BOOLEAN_TYPE: sg[0] = 'Z';  goto native;
! 	case CHAR_TYPE:    sg[0] = 'C';  goto native;
  	case VOID_TYPE:    sg[0] = 'V';  goto native;
  	case INTEGER_TYPE:
  	  switch (TYPE_PRECISION (type))
--- 611,620 ----
        switch (TREE_CODE (type))
  	{
  	case BOOLEAN_TYPE: sg[0] = 'Z';  goto native;
! 	case CHAR_TYPE:
!           gcc_assert (type == char_type_node
! 		      || type == promoted_char_type_node);
!           sg[0] = 'C';  goto native;
  	case VOID_TYPE:    sg[0] = 'V';  goto native;
  	case INTEGER_TYPE:
  	  switch (TYPE_PRECISION (type))



2006-01-27  Roger Sayle  <roger@eyesopen.com>

	* decl.c (java_init_decl_processing): Create char_type_node as a
	regular INTEGER_TYPE node.
	* typeck.c (convert): No longer check for CHAR_TYPEs but instead
	test for char_type_node and promoted_char_type_node as special
	instances of INTEGER_TYPE tree codes.
	(promote_type,build_java_signature): Likewise.
	* jcf-write.c (adjust_typed_op): Likewise.
	* mangle.c (mangle_type): Likewise.
	* parse.y (do_unary_numeric_promotion): No longer handle CHAR_TYPE.
	* parse.h (JINTEGRAL_TYPE_P): Likewise.

Index: typeck.c
===================================================================
*** typeck.c	(revision 110176)
--- typeck.c	(working copy)
*************** convert (tree type, tree expr)
*** 126,135 ****
      return error_mark_node;
    if (code == VOID_TYPE)
      return build1 (CONVERT_EXPR, type, expr);
!   if (code == BOOLEAN_TYPE || code ==  CHAR_TYPE)
      return fold_convert (type, expr);
    if (code == INTEGER_TYPE)
      {
        if ((really_constant_p (expr)
  	   || (! flag_unsafe_math_optimizations
  	       && ! flag_emit_class_files))
--- 126,137 ----
      return error_mark_node;
    if (code == VOID_TYPE)
      return build1 (CONVERT_EXPR, type, expr);
!   if (code == BOOLEAN_TYPE)
      return fold_convert (type, expr);
    if (code == INTEGER_TYPE)
      {
+       if (type == char_type_node || type == promoted_char_type_node)
+ 	return fold_convert (type, expr);
        if ((really_constant_p (expr)
  	   || (! flag_unsafe_math_optimizations
  	       && ! flag_emit_class_files))
*************** promote_type (tree type)
*** 431,441 ****
        if (type == boolean_type_node)
  	return promoted_boolean_type_node;
        goto handle_int;
!     case CHAR_TYPE:
        if (type == char_type_node)
  	return promoted_char_type_node;
-       goto handle_int;
-     case INTEGER_TYPE:
      handle_int:
        if (TYPE_PRECISION (type) < TYPE_PRECISION (int_type_node))
  	{
--- 433,441 ----
        if (type == boolean_type_node)
  	return promoted_boolean_type_node;
        goto handle_int;
!     case INTEGER_TYPE:
        if (type == char_type_node)
  	return promoted_char_type_node;
      handle_int:
        if (TYPE_PRECISION (type) < TYPE_PRECISION (int_type_node))
  	{
*************** build_java_signature (tree type)
*** 605,613 ****
        switch (TREE_CODE (type))
  	{
  	case BOOLEAN_TYPE: sg[0] = 'Z';  goto native;
- 	case CHAR_TYPE:    sg[0] = 'C';  goto native;
  	case VOID_TYPE:    sg[0] = 'V';  goto native;
  	case INTEGER_TYPE:
  	  switch (TYPE_PRECISION (type))
  	    {
  	    case  8:       sg[0] = 'B';  goto native;
--- 605,617 ----
        switch (TREE_CODE (type))
  	{
  	case BOOLEAN_TYPE: sg[0] = 'Z';  goto native;
  	case VOID_TYPE:    sg[0] = 'V';  goto native;
  	case INTEGER_TYPE:
+           if (type == char_type_node || type == promoted_char_type_node)
+ 	    {
+ 	      sg[0] = 'C';
+ 	      goto native;
+ 	    }
  	  switch (TYPE_PRECISION (type))
  	    {
  	    case  8:       sg[0] = 'B';  goto native;
Index: parse.y
===================================================================
*** parse.y	(revision 110176)
--- parse.y	(working copy)
*************** static tree
*** 13328,13335 ****
  do_unary_numeric_promotion (tree arg)
  {
    tree type = TREE_TYPE (arg);
!   if ((TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
!       || TREE_CODE (type) == CHAR_TYPE)
      arg = convert (int_type_node, arg);
    return arg;
  }
--- 13328,13334 ----
  do_unary_numeric_promotion (tree arg)
  {
    tree type = TREE_TYPE (arg);
!   if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
      arg = convert (int_type_node, arg);
    return arg;
  }
Index: decl.c
===================================================================
*** decl.c	(revision 110176)
--- decl.c	(working copy)
*************** java_init_decl_processing (void)
*** 743,749 ****
       initializations of __FUNCTION__ and __PRETTY_FUNCTION__.  */
    short_array_type_node = build_prim_array_type (short_type_node, 200);
  #endif
!   char_type_node = make_node (CHAR_TYPE);
    TYPE_PRECISION (char_type_node) = 16;
    fixup_unsigned_type (char_type_node);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node));
--- 743,749 ----
       initializations of __FUNCTION__ and __PRETTY_FUNCTION__.  */
    short_array_type_node = build_prim_array_type (short_type_node, 200);
  #endif
!   char_type_node = make_node (INTEGER_TYPE);
    TYPE_PRECISION (char_type_node) = 16;
    fixup_unsigned_type (char_type_node);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node));
Index: jcf-write.c
===================================================================
*** jcf-write.c	(revision 110176)
--- jcf-write.c	(working copy)
*************** adjust_typed_op (tree type, int max)
*** 881,889 ****
      case RECORD_TYPE:   return 4;
      case BOOLEAN_TYPE:
        return TYPE_PRECISION (type) == 32 || max < 5 ? 0 : 5;
-     case CHAR_TYPE:
-       return TYPE_PRECISION (type) == 32 || max < 6 ? 0 : 6;
      case INTEGER_TYPE:
        switch (TYPE_PRECISION (type))
  	{
  	case  8:       return max < 5 ? 0 : 5;
--- 881,889 ----
      case RECORD_TYPE:   return 4;
      case BOOLEAN_TYPE:
        return TYPE_PRECISION (type) == 32 || max < 5 ? 0 : 5;
      case INTEGER_TYPE:
+       if (type == char_type_node || type == promoted_char_type_node)
+ 	return TYPE_PRECISION (type) == 32 || max < 6 ? 0 : 6;
        switch (TYPE_PRECISION (type))
  	{
  	case  8:       return max < 5 ? 0 : 5;
Index: mangle.c
===================================================================
*** mangle.c	(revision 110176)
--- mangle.c	(working copy)
*************** mangle_type (tree type)
*** 243,251 ****
      {
        char code;
      case BOOLEAN_TYPE: code = 'b';  goto primitive;
-     case CHAR_TYPE:    code = 'w';  goto primitive;
      case VOID_TYPE:    code = 'v';  goto primitive;
      case INTEGER_TYPE:
        /* Get the original type instead of the arguments promoted type.
  	 Avoid symbol name clashes. Should call a function to do that.
  	 FIXME.  */
--- 243,255 ----
      {
        char code;
      case BOOLEAN_TYPE: code = 'b';  goto primitive;
      case VOID_TYPE:    code = 'v';  goto primitive;
      case INTEGER_TYPE:
+       if (type == char_type_node || type == promoted_char_type_node)
+ 	{
+ 	  code = 'w';
+ 	  goto primitive;
+ 	}
        /* Get the original type instead of the arguments promoted type.
  	 Avoid symbol name clashes. Should call a function to do that.
  	 FIXME.  */
Index: parse.h
===================================================================
*** parse.h	(revision 110176)
--- parse.h	(working copy)
*************** extern void parse_error_context (tree cl
*** 196,203 ****
  /* Types classification, according to the JLS, section 4.2 */
  #define JFLOAT_TYPE_P(TYPE)      (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE)
  #define JINTEGRAL_TYPE_P(TYPE)   ((TYPE) 				   \
! 				  && (TREE_CODE ((TYPE)) == INTEGER_TYPE   \
! 				      || TREE_CODE ((TYPE)) == CHAR_TYPE))
  #define JNUMERIC_TYPE_P(TYPE)    ((TYPE)				\
  				  && (JFLOAT_TYPE_P ((TYPE))		\
  				      || JINTEGRAL_TYPE_P ((TYPE))))
--- 196,202 ----
  /* Types classification, according to the JLS, section 4.2 */
  #define JFLOAT_TYPE_P(TYPE)      (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE)
  #define JINTEGRAL_TYPE_P(TYPE)   ((TYPE) 				   \
! 				  && (TREE_CODE ((TYPE)) == INTEGER_TYPE))
  #define JNUMERIC_TYPE_P(TYPE)    ((TYPE)				\
  				  && (JFLOAT_TYPE_P ((TYPE))		\
  				      || JINTEGRAL_TYPE_P ((TYPE))))


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-02-04 18:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-27 22:40 [RFC/RFT] Remove CHAR_TYPE tree code Roger Sayle
2006-01-28  0:07 ` Tom Tromey
2006-01-28  7:02   ` Eric Botcazou
2006-02-04 18:36   ` [JAVA] Avoid use of CHAR_TYPE tree codes Roger Sayle
2006-02-04 18:45     ` Andrew Haley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).