From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14470 invoked by alias); 27 Jan 2006 22:40:38 -0000 Received: (qmail 14446 invoked by uid 22791); 27 Jan 2006 22:40:35 -0000 X-Spam-Check-By: sourceware.org Received: from eyesopen.com (HELO www.eyesopen.com) (208.41.78.163) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 27 Jan 2006 22:40:32 +0000 Received: from localhost (roger@localhost) by www.eyesopen.com (8.11.6/8.11.6) with ESMTP id k0RLo6x24365; Fri, 27 Jan 2006 14:50:06 -0700 Date: Fri, 27 Jan 2006 22:40:00 -0000 From: Roger Sayle To: java-patches@gcc.gnu.org cc: gcc-patches@gcc.gnu.org Subject: [RFC/RFT] Remove CHAR_TYPE tree code. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact java-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: java-patches-owner@gcc.gnu.org X-SW-Source: 2006-q1/txt/msg00114.txt.bz2 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 * 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 * 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