aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/ChangeLog27
-rw-r--r--gcc/java/check-init.c27
-rw-r--r--gcc/java/class.c9
-rw-r--r--gcc/java/decl.c2
-rw-r--r--gcc/java/expr.c2
-rw-r--r--gcc/java/java-tree.h14
-rw-r--r--gcc/java/parse.y83
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)