This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: gcj patch: class initialization optimization
- To: gcc-patches at gcc dot gnu dot org
- Subject: Re: gcj patch: class initialization optimization
- From: Anthony Green <green at cygnus dot com>
- Date: Sat, 19 Feb 2000 14:51:06 -0800
- CC: bryce at albatross dot co dot nz
- References: <200002140554.VAA05885@hoser.cygnus.com>
- Reply-to: green at redhat dot com
Here's my second attempt at the class initialization optimization
patch.
Bryce: this one passes your definite assignment test case.
2000-02-19 Anthony Green <green@cygnus.com>
* expr.c (build_class_init): Mark the decl to be ignored by
check_init.
* java-tree.h (DECL_BIT_INDEX): Move definition from check-init.c
* check-init.c: Move DECL_BIT_INDEX to java-tree.h
2000-02-13 Anthony Green <green@cygnus.com>
* class.c (init_test_hash_newfunc): New function.
(decl_hash): New function.
(decl_compare): New function.
* decl.c (emit_init_test_initialization): New function.
(complete_start_java_method): Traverse the init test hashtable,
calling emit_init_test_initialization.
(always_initialize_class_p): Define.
* expr.c (build_class_init): Use initialization tests when
emitting class initialization code.
(always_initialize_class_p): Declare.
* jcf-parse.c (parse_class_file): Set always_initialize_class_p to
1.
* java-tree.h: Include hash.h.
(DECL_FUNCTION_INIT_TEST_TABLE): Define.
(struct lang_decl): Add init_test_table field.
(init_test_hash_entry): Define.
Index: gcc/java/check-init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/check-init.c,v
retrieving revision 1.17
diff -i -r1.17 check-init.c
42,46d41
< /* For a local VAR_DECL, holds the index into a words bitstring that
< specifies if this decl is definitively assigned.
< A DECL_BIT_INDEX of -1 means we no longer care. */
< #define DECL_BIT_INDEX(DECL) DECL_FIELD_SIZE(DECL)
<
Index: gcc/java/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/class.c,v
retrieving revision 1.53
diff -i -r1.53 class.c
392c392
<
---
>
550a551,584
> static struct hash_entry *
> init_test_hash_newfunc (entry, table, string)
> struct hash_entry *entry;
> struct hash_table *table;
> hash_table_key string ATTRIBUTE_UNUSED;
> {
> struct init_test_hash_entry *ret = (struct init_test_hash_entry *) entry;
> if (ret == NULL)
> {
> ret = ((struct init_test_hash_entry *)
> hash_allocate (table, sizeof (struct init_test_hash_entry)));
> if (ret == NULL)
> return NULL;
> }
> ret->init_test_decl = 0;
> return (struct hash_entry *) ret;
> }
>
> static unsigned long
> decl_hash (k)
> hash_table_key k;
> {
> return (long) k;
> }
>
> static boolean
> decl_compare (k1, k2)
> hash_table_key k1;
> hash_table_key k2;
> {
> return ((char*) k1 == (char*) k2);
> }
>
>
569a604,608
>
> /* Initialize the static initializer test table. */
> hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
> init_test_hash_newfunc, decl_hash,
> decl_compare);
Index: gcc/java/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/decl.c,v
retrieving revision 1.46
diff -i -r1.46 decl.c
50a51,54
> /* Set to non-zero value in order to emit class initilization code
> before static field references. */
> extern int always_initialize_class_p;
>
1625a1630,1647
>
> /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE in order
> to emit initialization code for each test flag. */
>
> static boolean
> emit_init_test_initialization (entry, key)
> struct hash_entry *entry;
> hash_table_key key;
> {
> struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
> expand_decl (ite->init_test_decl);
>
> expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
> ite->init_test_decl, boolean_false_node));
>
> return true;
> }
>
1636a1659,1663
>
> /* Emit initialization code for test flags. */
> if (! always_initialize_class_p)
> hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
> emit_init_test_initialization, 0);
Index: gcc/java/expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/expr.c,v
retrieving revision 1.59
diff -i -r1.59 expr.c
85a86,89
> /* Set to non-zero value in order to emit class initilization code
> before static field references. */
> int always_initialize_class_p;
>
1493c1497,1498
< tree init;
---
> tree init, call;
> struct init_test_hash_entry *ite;
1496,1500c1501,1538
< init = build (CALL_EXPR, void_type_node,
< build_address_of (soft_initclass_node),
< build_tree_list (NULL_TREE, build_class_ref (clas)),
< NULL_TREE);
< TREE_SIDE_EFFECTS (init) = 1;
---
>
> if (always_initialize_class_p)
> {
> init = build (CALL_EXPR, void_type_node,
> build_address_of (soft_initclass_node),
> build_tree_list (NULL_TREE, build_class_ref (clas)),
> NULL_TREE);
> TREE_SIDE_EFFECTS (init) = 1;
> }
> else
> {
> ite = (struct init_test_hash_entry *)
> hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
> (const hash_table_key) clas,
> TRUE, NULL);
>
> if (ite->init_test_decl == 0)
> ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
> boolean_type_node);
> /* Tell the check-init code to ignore this decl. */
> DECL_BIT_INDEX(ite->init_test_decl) = -1;
>
> init = build (CALL_EXPR, void_type_node,
> build_address_of (soft_initclass_node),
> build_tree_list (NULL_TREE, build_class_ref (clas)),
> NULL_TREE);
> TREE_SIDE_EFFECTS (init) = 1;
> call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
> build (MODIFY_EXPR, boolean_type_node,
> ite->init_test_decl, boolean_true_node));
> TREE_SIDE_EFFECTS (call) = 1;
> init = build (COND_EXPR, void_type_node,
> build (EQ_EXPR, boolean_type_node,
> ite->init_test_decl, boolean_false_node),
> call, integer_zero_node);
> TREE_SIDE_EFFECTS (init) = 1;
> }
>
Index: gcc/java/java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.52
diff -i -r1.52 java-tree.h
27a28,29
> #include "hash.h"
>
370a373,378
> /* For each function decl, init_test_table contains a hash table whose
> entries are keyed on class names, and whose values are local
> boolean decls. The variables are intended to be TRUE when the
> class has been initialized in this function, and FALSE otherwise. */
> #define DECL_FUNCTION_INIT_TEST_TABLE(DECL) \
> (DECL_LANG_SPECIFIC(DECL)->init_test_table)
431a440,444
> /* For a local VAR_DECL, holds the index into a words bitstring that
> specifies if this decl is definitively assigned.
> A DECL_BIT_INDEX of -1 means we no longer care. */
> #define DECL_BIT_INDEX(DECL) DECL_FIELD_SIZE(DECL)
>
445a459,467
> struct hash_table init_test_table;
> /* Class initialization test variables. */
> };
>
> /* init_test_table hash table entry structure. */
> struct init_test_hash_entry
> {
> struct hash_entry root;
> tree init_test_decl;
446a469
>
Index: gcc/java/jcf-parse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-parse.c,v
retrieving revision 1.41
diff -i -r1.41 jcf-parse.c
59a60,63
> /* Set to non-zero value in order to emit class initilization code
> before static field references. */
> extern int always_initialize_class_p;
>
658a663,666
>
> /* Currently we always have to emit calls to _Jv_InitClass when
> compiling from class files. */
> always_initialize_class_p = 1;
--
Anthony Green Red Hat
Sunnyvale, California