Restore support for static class initialization optimization.
authorPer Bothner <per@bothner.com>
Thu, 6 Dec 2001 23:12:55 +0000 (15:12 -0800)
committerPer Bothner <bothner@gcc.gnu.org>
Thu, 6 Dec 2001 23:12:55 +0000 (15:12 -0800)
From-SVN: r47735

gcc/java/ChangeLog
gcc/java/check-init.c
gcc/java/class.c
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/parse.y

index 5b06dde..e2d32fc 100644 (file)
@@ -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
index e8329c9..1db19b9 100644 (file)
@@ -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:
index 9700994..3d691bc 100644 (file)
@@ -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;
index 1cbd603..0b1e016 100644 (file)
@@ -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))
index 78ca165..f865d95 100644 (file)
@@ -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 ())
index 0ca0e3f..f286963 100644 (file)
@@ -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;
 
index 11318be..80c60fd 100644 (file)
@@ -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)