diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/java/ChangeLog | 27 | ||||
-rw-r--r-- | gcc/java/check-init.c | 27 | ||||
-rw-r--r-- | gcc/java/class.c | 9 | ||||
-rw-r--r-- | gcc/java/decl.c | 2 | ||||
-rw-r--r-- | gcc/java/expr.c | 2 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 14 | ||||
-rw-r--r-- | gcc/java/parse.y | 83 |
7 files changed, 93 insertions, 71 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 5b06dde..e2d32fc 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,30 @@ +2001-12-05 Per Bothner <per@bothner.com> + + Restore support for static class initialization optimization. + * java-tree.h (STATIC_CLASS_INIT_OPT_P): Re-enable. + * check-init.c (check_int): At end of BLOCK handle initialization + blocks, which used to be done in java_complete_expand_method but did + not handle the case where check_for_initialization might allocate + more than a word of bits. + * decl.c (lang_make_tree): The smic field is now a tree. + * expr.c (build_class_init): Set DECL_FUNCTION_INIT_TEST_CLASS field. + * java-tree.h (DECL_FUNCTION_INIT_TEST_TABLE): New macro. + + * parse.y (emit_test_initialization): Combine hash_lookup calls. + + * java-tree.h (DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND): + Change from a hash table to a list. + (struct_lang_decl): Change field 'smic' to match. + * class.c (add_method_1): Initialize + DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND to null list. + * parse.y (adjust_init_test_initialization): Removed - inlined into - + (java_expand_method_bodies): -here, since 'smic' is now a list. + (patch_invoke): Add to 'smic' list, instead of hash_lookup. + + * check-init.c (WORD_SIZE): Use BITS_PER_UNIT. + + * class.c (java_hash_compare_tree_node): Fix casts. + 2001-12-04 Per Bothner <per@bothner.com> * check-init.c: Handle definite unassignment to finals in addition diff --git a/gcc/java/check-init.c b/gcc/java/check-init.c index e8329c9..1db19b9 100644 --- a/gcc/java/check-init.c +++ b/gcc/java/check-init.c @@ -96,7 +96,7 @@ static tree wfl; #define INTERSECT(DST, SRC1, SRC2) \ INTERSECTN (DST, SRC1, SRC2, num_current_words) -#define WORD_SIZE ((unsigned int)(sizeof(word) * 8)) +#define WORD_SIZE ((unsigned int)(sizeof(word) * BITS_PER_UNIT)) static void check_bool_init PARAMS ((tree, words, words, words)); static void check_init PARAMS ((tree, words)); @@ -595,6 +595,24 @@ check_init (exp, before) SET_UNASSIGNED (tmp, i); } check_init (BLOCK_EXPR_BODY (exp), tmp); + + /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */ + for (decl = BLOCK_EXPR_DECLS (exp); + decl != NULL_TREE; decl = TREE_CHAIN (decl)) + { + if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl)) + { + int index = DECL_BIT_INDEX (decl); + tree fndecl = DECL_CONTEXT (decl); + if (fndecl && METHOD_STATIC (fndecl) + && (DECL_INITIAL (decl) == boolean_true_node + || (index >= 0 && ASSIGNED_P (tmp, index)))) + hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl), + DECL_FUNCTION_INIT_TEST_CLASS(decl), TRUE, NULL); + } + DECL_BIT_INDEX (decl) = -1; + } + num_current_locals = start_current_locals; start_current_locals = save_start_current_locals; if (tmp != before) @@ -603,13 +621,6 @@ check_init (exp, before) COPY (before, tmp); FREE_WORDS (tmp); } - - /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */ - for (decl = BLOCK_EXPR_DECLS (exp); - decl != NULL_TREE; decl = TREE_CHAIN (decl)) - { - DECL_BIT_INDEX (decl) = -1; - } } break; case LOOP_EXPR: diff --git a/gcc/java/class.c b/gcc/java/class.c index 9700994..3d691bc 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -656,7 +656,7 @@ java_hash_compare_tree_node (k1, k2) hash_table_key k1; hash_table_key k2; { - return ((char*) k1 == (char*) k2); + return ((tree) k1 == (tree) k2); } tree @@ -688,11 +688,8 @@ add_method_1 (handle_class, access_flags, name, function_type) init_test_hash_newfunc, java_hash_hash_tree_node, java_hash_compare_tree_node); - /* Initialize the static method invocation compound table */ - if (STATIC_CLASS_INIT_OPT_P ()) - hash_table_init (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl), - init_test_hash_newfunc, java_hash_hash_tree_node, - java_hash_compare_tree_node); + /* Initialize the static method invocation compound list */ + DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = NULL_TREE; TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class); TYPE_METHODS (handle_class) = fndecl; diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 1cbd603..0b1e016 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -1847,7 +1847,7 @@ lang_mark_tree (t) ggc_mark_tree (ld->inner_access); ggc_mark_tree_hash_table (&ld->init_test_table); ggc_mark_tree_hash_table (&ld->ict); - ggc_mark_tree_hash_table (&ld->smic); + ggc_mark_tree (ld->smic); } } else if (TYPE_P (t)) diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 78ca165..f865d95 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -1729,7 +1729,7 @@ build_class_init (clas, expr) MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (ite->init_test_decl); LOCAL_CLASS_INITIALIZATION_FLAG (ite->init_test_decl) = 1; DECL_CONTEXT (ite->init_test_decl) = current_function_decl; - + DECL_FUNCTION_INIT_TEST_CLASS (ite->init_test_decl) = clas; /* Tell the check-init code to ignore this decl when not optimizing class initialization. */ if (!STATIC_CLASS_INIT_OPT_P ()) diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 0ca0e3f..f286963 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -726,14 +726,17 @@ struct lang_identifier class has been initialized in this function, and FALSE otherwise. */ #define DECL_FUNCTION_INIT_TEST_TABLE(DECL) \ (DECL_LANG_SPECIFIC(DECL)->init_test_table) +/* If LOCAL_CLASS_INITIALIZATION_FLAG_P(decl), give class it initializes. */ +#define DECL_FUNCTION_INIT_TEST_CLASS(DECL) \ + (((struct lang_decl_var*)DECL_LANG_SPECIFIC(DECL))->slot_chain) /* For each static function decl, itc contains a hash table whose entries are keyed on class named that are definitively initialized in DECL. */ #define DECL_FUNCTION_INITIALIZED_CLASS_TABLE(DECL) \ (DECL_LANG_SPECIFIC(DECL)->ict) -/* For each static function call, smic contains contains a hash table - whose entries are keyed on the compound statement that encapsulate - the invocation. */ +/* A list of all the static method calls in the method DECL (if optimizing). + Actually each TREE_VALUE points to a COMPONT_EXPR that wraps the + invoation so we can later patch it. */ #define DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND(DECL) \ (DECL_LANG_SPECIFIC(DECL)->smic) /* The Number of Artificial Parameters (NAP) DECL contains. this$<n> @@ -888,7 +891,7 @@ struct lang_decl struct hash_table init_test_table; /* Class initialization test variables */ struct hash_table ict; /* Initialized (static) Class Table */ - struct hash_table smic; /* Static method invocation compound */ + tree smic; /* Static method invocation compound */ tree inner_access; /* The identifier of the access method used for invocation from inner classes */ int nap; /* Number of artificial parameters */ @@ -1604,8 +1607,7 @@ extern tree *type_map; /* True when we can perform static class initialization optimization */ #define STATIC_CLASS_INIT_OPT_P() \ - 0 /* ??? Temporarily turn off this optimization -PB */ -/* (flag_optimize_sci && (optimize >= 2) && ! flag_emit_class_files)*/ + (flag_optimize_sci && (optimize >= 2) && ! flag_emit_class_files) extern int java_error_count; diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 11318be..80c60fd 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -335,8 +335,6 @@ static tree maybe_build_class_init_for_field PARAMS ((tree, tree)); static bool attach_init_test_initialization_flags PARAMS ((struct hash_entry *, PTR)); -static bool adjust_init_test_initialization PARAMS ((struct hash_entry *, - PTR)); static bool emit_test_initialization PARAMS ((struct hash_entry *, PTR)); /* Number of error found so far. */ @@ -8017,21 +8015,16 @@ java_complete_expand_method (mdecl) static variables and see whether they're definitively assigned, in which case the type is remembered as definitively initialized in MDECL. */ - /* FIXME this doesn't work state is too short. if (STATIC_CLASS_INIT_OPT_P ()) { - hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl), - attach_initialized_static_class, (PTR)&state); - - / * Always register the context as properly initialized in + /* Always register the context as properly initialized in MDECL. This used with caution helps removing extra - initialization of self. * / + initialization of self. */ if (METHOD_STATIC (mdecl)) hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl), (hash_table_key) DECL_CONTEXT (mdecl), TRUE, NULL); } - */ } ctxp->explicit_constructor_p = 0; } @@ -8081,8 +8074,32 @@ java_expand_method_bodies (class) initialization based on which classes invoked static methods are definitely initializing. This should be flagged. */ if (STATIC_CLASS_INIT_OPT_P ()) - hash_traverse (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl), - adjust_init_test_initialization, NULL); + { + tree list = DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl); + for (; list != NULL_TREE; list = TREE_CHAIN (list)) + { + /* Executed for each statement calling a static function. + LIST is a TREE_LIST whose PURPOSE is the called function + and VALUE is a compound whose second operand can be patched + with static class initialization flag assignments. */ + + tree called_method = TREE_PURPOSE (list); + tree compound = TREE_VALUE (list); + tree assignment_compound_list + = build_tree_list (called_method, NULL); + + /* For each class definitely initialized in + CALLED_METHOD, fill ASSIGNMENT_COMPOUND with + assignment to the class initialization flag. */ + hash_traverse (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method), + emit_test_initialization, + assignment_compound_list); + + if (TREE_VALUE (assignment_compound_list)) + TREE_OPERAND (compound, 1) + = TREE_VALUE (assignment_compound_list); + } + } /* Prepare the function for RTL expansion */ start_complete_expand_method (decl); @@ -10691,10 +10708,10 @@ patch_invoke (patch, method, args) tree type = TREE_TYPE (patch); patch = build (COMPOUND_EXPR, type, save, empty_stmt_node); - list = build_tree_list (method, patch); + list = tree_cons (method, patch, + DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl)); - hash_lookup (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl), - (const hash_table_key) list, TRUE, NULL); + DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = list; patch = build (COMPOUND_EXPR, type, patch, save); } @@ -15974,32 +15991,6 @@ attach_init_test_initialization_flags (entry, ptr) return true; } -/* This function is called for each statement calling a static - function. ENTRY is a TREE_LIST whose PURPOSE is the called - function and VALUE is a compound whose second operand can be - patched with static class initialization flag assignments. */ - -static bool -adjust_init_test_initialization (entry, info) - struct hash_entry *entry; - PTR info ATTRIBUTE_UNUSED; -{ - tree list = (tree)(entry->key); - tree called_method = TREE_PURPOSE (list); - tree compound = TREE_VALUE (list); - tree assignment_compound_list = build_tree_list (called_method, NULL); - - /* For each class definitely initialized in CALLED_METHOD, fill - ASSIGNMENT_COMPOUND with assignment to the class initialization flag. */ - hash_traverse (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method), - emit_test_initialization, assignment_compound_list); - - if (TREE_VALUE (assignment_compound_list)) - TREE_OPERAND (compound, 1) = TREE_VALUE (assignment_compound_list); - - return true; -} - /* This function is called for each classes that is known definitely assigned when a given static method was called. This function augments a compound expression (INFO) storing all assignment to @@ -16016,21 +16007,15 @@ emit_test_initialization (entry, info) struct init_test_hash_entry *ite = (struct init_test_hash_entry *) hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), - entry->key, FALSE, NULL); + entry->key, + current_function_decl != TREE_PURPOSE (l), NULL); /* If we haven't found a flag and we're dealing with self registered with current_function_decl, then don't do anything. Self is always added as definitely initialized but this information is valid only if used outside the current function. */ if (! ite) - { - if (current_function_decl != TREE_PURPOSE (l)) - ite = (struct init_test_hash_entry *) - hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), - entry->key, TRUE, NULL); - else - return true; - } + return true; /* If we don't have a variable, create one and install it. */ if (! ite->init_test_decl) |