OSDN Git Service

* decl.c (java_expand_body): New function.
authorjsturm <jsturm@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Sep 2003 13:44:43 +0000 (13:44 +0000)
committerjsturm <jsturm@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Sep 2003 13:44:43 +0000 (13:44 +0000)
* expr.c (build_class_init): Set DECL_IGNORED_P.
* java-tree.h (start_complete_expand_method,
java_expand_body): Declare.
* jcf-parse.c (cgraph.h): Include.
(java_parse_file): Handle flag_unit_at_a_time.
* lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING,
LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Define.
(java_estimate_num_insns): Use walk_tree_without_duplicates.
(java_start_inlining): New function.
* parse.h (java_finish_classes): Declare.
* parse.y: Include cgraph.h.
(block): Don't special-case empty block production.
(craft_constructor): Set DECL_INLINE.
(source_end_java_method): Handle flag_unit_at_a_time.
Replace inline code with call to java_expand_body.
(start_complete_expand_method): Remove static modifier.
(java_expand_method_bodies): Patch function tree for
class initialization and/or synchronization as needed.
Don't begin RTL expansion yet.
(java_expand_classes): Check flag_unit_at_a_time before
calling finish_class.
(java_finish_classes): New function.
(java_complete_lhs): Ensure COMPOUND_EXPR has non-NULL type.
(patch_assignment): Set DECL_CONTEXT on temporary variable.
(emit_test_initialization): Set DECL_IGNORED_P.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71024 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/ChangeLog
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/jcf-parse.c
gcc/java/lang.c
gcc/java/parse.h
gcc/java/parse.y

index 4f0db4a..3b52536 100644 (file)
@@ -1,3 +1,32 @@
+2003-09-03  Jeff Sturm  <jsturm@one-point.com>
+
+       * decl.c (java_expand_body): New function.
+       * expr.c (build_class_init): Set DECL_IGNORED_P.
+       * java-tree.h (start_complete_expand_method,
+       java_expand_body): Declare.
+       * jcf-parse.c (cgraph.h): Include.
+       (java_parse_file): Handle flag_unit_at_a_time.
+       * lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING,
+       LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Define.
+       (java_estimate_num_insns): Use walk_tree_without_duplicates.
+       (java_start_inlining): New function.
+       * parse.h (java_finish_classes): Declare.
+       * parse.y: Include cgraph.h.
+       (block): Don't special-case empty block production.
+       (craft_constructor): Set DECL_INLINE.
+       (source_end_java_method): Handle flag_unit_at_a_time.
+       Replace inline code with call to java_expand_body.
+       (start_complete_expand_method): Remove static modifier.
+       (java_expand_method_bodies): Patch function tree for
+       class initialization and/or synchronization as needed.
+       Don't begin RTL expansion yet.
+       (java_expand_classes): Check flag_unit_at_a_time before
+       calling finish_class.
+       (java_finish_classes): New function.
+       (java_complete_lhs): Ensure COMPOUND_EXPR has non-NULL type.
+       (patch_assignment): Set DECL_CONTEXT on temporary variable.
+       (emit_test_initialization): Set DECL_IGNORED_P.
+
 2003-09-03  Roger Sayle  <roger@eyesopen.com>
 
        * builtins.c (enum builtin_type): Delete unused enumeration.
index c1cebd8..90978e4 100644 (file)
@@ -1811,6 +1811,59 @@ end_java_method (void)
   current_function_decl = NULL_TREE;
 }
 
+/* Expand a function's body.  */
+
+void
+java_expand_body (tree fndecl)
+{
+  const char *saved_input_filename = input_filename;
+  int saved_lineno = input_line;
+
+  current_function_decl = fndecl;
+  input_filename = DECL_SOURCE_FILE (fndecl);
+  input_line = DECL_SOURCE_LINE (fndecl);
+
+  timevar_push (TV_EXPAND);
+
+  /* Prepare the function for tree completion.  */
+  start_complete_expand_method (fndecl);
+
+  if (! flag_emit_class_files && ! flag_emit_xref)
+    {
+      /* Initialize the RTL code for the function.  */
+      init_function_start (fndecl);
+
+      /* Set up parameters and prepare for return, for the function.  */
+      expand_function_start (fndecl, 0);
+
+      /* Generate the RTL for this function.  */
+      expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 1);
+    }
+
+  /* Pop out of its parameters.  */
+  pushdecl_force_head (DECL_ARGUMENTS (fndecl));
+  poplevel (1, 0, 1);
+  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+
+  if (! flag_emit_class_files && ! flag_emit_xref)
+    {
+      /* Generate RTL for function exit.  */
+      input_line = DECL_FUNCTION_LAST_LINE (fndecl);
+      expand_function_end ();
+
+      /* Run the optimizers and output the assembler code
+        for this function.  */
+      rest_of_compilation (fndecl);
+    }
+
+  timevar_pop (TV_EXPAND);
+
+  input_filename = saved_input_filename;
+  input_line = saved_lineno;
+
+  current_function_decl = NULL_TREE;
+}
+
 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
 
 static void
index 7710008..1c7d501 100644 (file)
@@ -1710,6 +1710,8 @@ build_class_init (tree clas, tree expr)
              optimizing class initialization. */
          if (!STATIC_CLASS_INIT_OPT_P ())
            DECL_BIT_INDEX(*init_test_decl) = -1;
+         /* Don't emit any symbolic debugging info for this decl.  */
+         DECL_IGNORED_P (*init_test_decl) = 1;
        }
 
       init = build (CALL_EXPR, void_type_node,
index 0a7a542..69eb73c 100644 (file)
@@ -1297,6 +1297,9 @@ extern void compile_resource_file (const char *, const char *);
 extern void write_resource_constructor (void);
 extern void init_resource_processing (void);
 
+extern void start_complete_expand_method (tree);
+extern void java_expand_body (tree);
+
 
 #define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL)
 
index 2393927..f47dbe0 100644 (file)
@@ -42,6 +42,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "debug.h"
 #include "assert.h"
 #include "tm_p.h"
+#include "cgraph.h"
 
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
@@ -1119,6 +1120,13 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
   java_expand_classes ();
   if (!java_report_errors () && !flag_syntax_only)
     {
+      if (flag_unit_at_a_time)
+       {
+         cgraph_finalize_compilation_unit ();
+         cgraph_optimize ();
+         java_finish_classes ();
+       }
+
       emit_register_classes ();
       if (flag_indirect_dispatch)
        emit_offset_symbol_table ();
index 6bddf38..5ade4c0 100644 (file)
@@ -67,6 +67,7 @@ static bool java_dump_tree (void *, tree);
 static void dump_compound_expr (dump_info_p, tree);
 static bool java_decl_ok_for_sibcall (tree);
 static int java_estimate_num_insns (tree);
+static int java_start_inlining (tree);
 
 #ifndef TARGET_OBJECT_SUFFIX
 # define TARGET_OBJECT_SUFFIX ".o"
@@ -253,12 +254,18 @@ struct language_function GTY(())
 #undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
 #define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS java_estimate_num_insns
 
+#undef LANG_HOOKS_TREE_INLINING_START_INLINING
+#define LANG_HOOKS_TREE_INLINING_START_INLINING java_start_inlining
+
 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
 
 #undef LANG_HOOKS_DECL_OK_FOR_SIBCALL
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall
 
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION java_expand_body
+
 /* Each front end provides its own.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
@@ -1178,8 +1185,21 @@ static int
 java_estimate_num_insns (tree decl)
 {
   int num = 0;
-  walk_tree (&DECL_SAVED_TREE (decl), java_estimate_num_insns_1, &num, NULL);
+  walk_tree_without_duplicates (&DECL_SAVED_TREE (decl),
+                               java_estimate_num_insns_1, &num);
   return num;
 }
 
+/* Start inlining fn.  Called by the tree inliner via
+   lang_hooks.tree_inlining.cannot_inline_tree_fn.  */
+
+static int
+java_start_inlining (tree fn)
+{
+  /* A java function's body doesn't have a BLOCK structure suitable
+     for debug output until it is expanded.  Prevent inlining functions
+     that are not yet expanded.  */
+  return TREE_ASM_WRITTEN (fn) ? 1 : 0;
+}
+
 #include "gt-java-lang.h"
index df1fa56..0234108 100644 (file)
@@ -941,6 +941,7 @@ ATTRIBUTE_NORETURN
 #endif
 ;
 extern void java_expand_classes (void);
+extern void java_finish_classes (void);
 
 extern GTY(()) struct parser_ctxt *ctxp;
 extern GTY(()) struct parser_ctxt *ctxp_for_generation;
index a9f8d6e..8684537 100644 (file)
@@ -71,6 +71,7 @@ definitions and other extensions.  */
 #include "ggc.h"
 #include "debug.h"
 #include "tree-inline.h"
+#include "cgraph.h"
 
 /* Local function prototypes */
 static char *java_accstring_lookup (int);
@@ -141,7 +142,6 @@ static tree java_complete_tree (tree);
 static tree maybe_generate_pre_expand_clinit (tree);
 static int analyze_clinit_body (tree, tree);
 static int maybe_yank_clinit (tree);
-static void start_complete_expand_method (tree);
 static void java_complete_expand_method (tree);
 static void java_expand_method_bodies (tree);
 static int  unresolved_type_p (tree, tree *);
@@ -1352,14 +1352,8 @@ variable_initializers:
 
 /* 19.11 Production from 14: Blocks and Statements  */
 block:
-       OCB_TK CCB_TK
-               {
-                 /* Store the location of the `}' when doing xrefs */
-                 if (current_function_decl && flag_emit_xref)
-                   DECL_END_SOURCE_LINE (current_function_decl) =
-                     EXPR_WFL_ADD_COL ($2.location, 1);
-                 $$ = empty_stmt_node;
-               }
+       block_begin block_end
+               { $$ = $2; }
 |      block_begin block_statements block_end
                { $$ = $3; }
 ;
@@ -5405,6 +5399,7 @@ craft_constructor (tree class_decl, tree args)
   /* Now, mark the artificial parameters. */
   DECL_FUNCTION_NAP (decl) = artificial;
   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
+  DECL_INLINE (decl) = 1;
   return decl;
 }
 
@@ -7476,30 +7471,20 @@ source_end_java_method (void)
      patched.  Dump it to a file if the user requested it.  */
   dump_java_tree (TDI_original, fndecl);
 
-  java_optimize_inline (fndecl);
-
-  /* Generate function's code */
-  if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
-      && ! flag_emit_class_files
-      && ! flag_emit_xref)
-    expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
-
-  /* pop out of its parameters */
-  pushdecl_force_head (DECL_ARGUMENTS (fndecl));
-  poplevel (1, 0, 1);
-  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
-
-  /* Generate rtl for function exit.  */
-  if (! flag_emit_class_files && ! flag_emit_xref)
+  /* In unit-at-a-time mode, don't expand the method yet.  */
+  if (DECL_SAVED_TREE (fndecl) && flag_unit_at_a_time)
     {
-      input_line = DECL_FUNCTION_LAST_LINE (fndecl);
-      expand_function_end ();
-
-      /* Run the optimizers and output assembler code for this function. */
-      rest_of_compilation (fndecl);
+      cgraph_finalize_function (fndecl, DECL_SAVED_TREE (fndecl));
+      current_function_decl = NULL_TREE;
+      java_parser_context_restore_global ();
+      return;
     }
 
-  current_function_decl = NULL_TREE;
+  java_optimize_inline (fndecl);
+
+  /* Expand the function's body.  */
+  java_expand_body (fndecl);
+
   java_parser_context_restore_global ();
 }
 
@@ -7969,7 +7954,7 @@ maybe_yank_clinit (tree mdecl)
 /* Install the argument from MDECL. Suitable to completion and
    expansion of mdecl's body.  */
 
-static void
+void
 start_complete_expand_method (tree mdecl)
 {
   tree tem;
@@ -8112,15 +8097,26 @@ java_expand_method_bodies (tree class)
   tree decl;
   for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
     {
-      if (!DECL_FUNCTION_BODY (decl))
+      tree block;
+      tree body;
+
+      if (! DECL_FUNCTION_BODY (decl))
        continue;
 
       current_function_decl = decl;
 
-      /* Save the function for inlining.  */
-      if (flag_inline_trees)
-       DECL_SAVED_TREE (decl) =
-         BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
+      block = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
+
+      if (TREE_CODE (block) != BLOCK)
+       abort ();
+
+      /* Save the function body for inlining.  */
+      DECL_SAVED_TREE (decl) = block;
+
+      body = BLOCK_EXPR_BODY (block);
+
+      if (TREE_TYPE (body) == NULL_TREE)
+       abort ();
 
       /* It's time to assign the variable flagging static class
         initialization based on which classes invoked static methods
@@ -8153,15 +8149,41 @@ java_expand_method_bodies (tree class)
            }
        }
 
-      /* Prepare the function for RTL expansion */
-      start_complete_expand_method (decl);
+      /* Prepend class initialization to static methods.  */
+      if (METHOD_STATIC (decl) && ! METHOD_PRIVATE (decl)
+         && ! flag_emit_class_files
+         && ! DECL_CLINIT_P (decl)
+         && ! CLASS_INTERFACE (TYPE_NAME (class)))
+       {
+         tree init = build (CALL_EXPR, void_type_node,
+                            build_address_of (soft_initclass_node),
+                            build_tree_list (NULL_TREE,
+                                             build_class_ref (class)),
+                            NULL_TREE);
+         TREE_SIDE_EFFECTS (init) = 1;
+         body = build (COMPOUND_EXPR, TREE_TYPE (body), init, body);
+         BLOCK_EXPR_BODY (block) = body;
+       }
+
+      /* Wrap synchronized method bodies in a monitorenter
+        plus monitorexit cleanup.  */
+      if (METHOD_SYNCHRONIZED (decl) && ! flag_emit_class_files)
+       {
+         tree enter, exit, lock;
+         if (METHOD_STATIC (decl))
+           lock = build_class_ref (class);
+         else
+           lock = DECL_ARGUMENTS (decl);
+         BUILD_MONITOR_ENTER (enter, lock);
+         BUILD_MONITOR_EXIT (exit, lock);
 
-      /* Expand function start, generate initialization flag
-        assignment, and handle synchronized methods. */
-      complete_start_java_method (decl);
+         body = build (COMPOUND_EXPR, void_type_node,
+                       enter,
+                       build (TRY_FINALLY_EXPR, void_type_node, body, exit));
+         BLOCK_EXPR_BODY (block) = body;
+       }
 
-      /* Expand the rest of the function body and terminate
-         expansion. */
+      /* Expand the the function body.  */
       source_end_java_method ();
     }
 }
@@ -9124,12 +9146,30 @@ java_expand_classes (void)
          else if (! flag_syntax_only)
            {
              java_expand_method_bodies (current_class);
-             finish_class ();
+             if (!flag_unit_at_a_time)
+               finish_class ();
            }
        }
     }
 }
 
+void
+java_finish_classes (void)
+{
+  static struct parser_ctxt *cur_ctxp = NULL;
+  for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
+    {
+      tree current;
+      ctxp = cur_ctxp;
+      for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
+       {
+         current_class = TREE_TYPE (current);
+         outgoing_cpool = TYPE_CPOOL (current_class);
+         finish_class ();
+       }
+    }
+}
+
 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
    a tree list node containing RIGHT. Fore coming RIGHTs will be
    chained to this hook. LOCATION contains the location of the
@@ -11659,6 +11699,8 @@ java_complete_lhs (tree node)
                      && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
                    unreachable_stmt_error (*ptr);
                }
+             if (TREE_TYPE (*ptr) == NULL_TREE)
+               TREE_TYPE (*ptr) = void_type_node;
              ptr = next;
            }
          *ptr = java_complete_tree (*ptr);
@@ -12889,6 +12931,7 @@ patch_assignment (tree node, tree wfl_op1)
            tree block = build (BLOCK, TREE_TYPE (new_rhs), NULL);
            tree assignment 
              = build (MODIFY_EXPR, TREE_TYPE (new_rhs), tmp, fold (new_rhs));
+           DECL_CONTEXT (tmp) = current_function_decl;
            BLOCK_VARS (block) = tmp;
            BLOCK_EXPR_BODY (block) 
              = build (COMPOUND_EXPR, TREE_TYPE (new_rhs), assignment, tmp);
@@ -16221,6 +16264,8 @@ emit_test_initialization (void **entry_p, void *info)
       LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
       DECL_CONTEXT (decl) = current_function_decl;
       DECL_INITIAL (decl) = boolean_true_node;
+      /* Don't emit any symbolic debugging info for this decl.  */
+      DECL_IGNORED_P (decl) = 1;
 
       /* The trick is to find the right context for it. */
       block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));