This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] [PATCH] Java: tree_rest_of_compilation
- From: Jeff Sturm <jsturm at one-point dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 5 Oct 2003 14:07:04 -0400 (EDT)
- Subject: [tree-ssa] [PATCH] Java: tree_rest_of_compilation
1) Fixes testsuite failures I somehow missed during the recent merge
(java_expand_method_bodies expected its function body to start with BLOCK
node, build_jni_stub returns BIND_EXPR, abort).
2) Removes minor code duplication. The source compiler and bytecode
compiler had nearly identical code to patch function trees with class
initialization and monitorenter/monitorexit. With this patch the two
compilers behave exactly the same from genericization through
rest_of_compilation. Consequently, unit-at-a-time is now functioning for
the bytecode compiler as well.
3) Use tree_rest_of_compilation. There is a new, explicit genericization
pass (which only gimplifies for now) following the example from other
frontends. Full gimplification takes place in tree_r_o_c. Also
flag_disable_gimple is now ignored (it didn't work anyway).
Note the entire patch removes 127 lines of code from the frontend overall
(+96,-223).
Test suite results are still terrible:
=== libjava Summary ===
# of expected passes 3002
# of unexpected failures 53
# of expected failures 10
# of untested testcases 68
but now at least there are no regressions since pre-merge.
Tested on i686-pc-linux-gnu by rebuilding libjava. Full bootstrap
pending. OK to commit?
Jeff
2003-10-05 Jeff Sturm <jsturm@one-point.com>
* decl.c (cgraph.h): Include.
(tree-inline.h, tree-dump.h, tree-flow.h): Remove includes.
(end_java_method): Don't patch or expand tree.
Use finish_method.
(finish_method): New function.
(java_expand_body): Use tree_rest_of_compilation.
(java_expand_stmt): New function.
* java-gimplify.c (tree-dump.h): Include.
(java_genericize): New function.
(dump_java_tree): Declare. New function.
* java-tree.h (start_complete_expand_method): Remove declaration.
(finish_method, java_expand_stmt, java_genericize): Declare.
* lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Define.
* parse.y (tree-inline.h, tree-dump.h, tree-flow.h,
cgraph.h): Remove includes.
(start_complete_expand_method): Declare.
(source_end_java_method): Don't expand tree. Use finish_method.
Reset current_function_decl.
(java_expand_method_bodies): Don't patch tree for class
initialization or method synchronization.
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.128.2.23
diff -u -p -r1.128.2.23 decl.c
--- decl.c 3 Oct 2003 06:16:02 -0000 1.128.2.23
+++ decl.c 5 Oct 2003 16:30:29 -0000
@@ -44,9 +44,7 @@ The Free Software Foundation is independ
#include "java-except.h"
#include "ggc.h"
#include "timevar.h"
-#include "tree-inline.h"
-#include "tree-dump.h"
-#include "tree-flow.h"
+#include "cgraph.h"
#if defined (DEBUG_JAVA_BINDING_LEVELS)
extern void indent (void);
@@ -1859,45 +1857,6 @@ end_java_method (void)
{
tree fndecl = current_function_decl;
- if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl))
- && ! flag_emit_class_files)
- {
- if (METHOD_SYNCHRONIZED (fndecl))
- {
- /* Wrap function body with a monitorenter plus monitorexit cleanup. */
- tree enter, exit, lock;
- if (METHOD_STATIC (fndecl))
- lock = build_class_ref (DECL_CONTEXT (fndecl));
- else
- lock = DECL_ARGUMENTS (fndecl);
- BUILD_MONITOR_ENTER (enter, lock);
- BUILD_MONITOR_EXIT (exit, lock);
-
- {
- tree lock = build (COMPOUND_EXPR, void_type_node,
- enter,
- build (TRY_FINALLY_EXPR,
- void_type_node, *get_stmts (), exit));
- TREE_SIDE_EFFECTS (lock) = 1;
- *get_stmts () = lock;
- }
- }
-
- if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
- && ! DECL_CLINIT_P (fndecl)
- && ! CLASS_INTERFACE (TYPE_NAME (current_class)))
- {
- tree *stmts = get_stmts ();
- tree clas = DECL_CONTEXT (fndecl);
- tree 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;
- *stmts = build (COMPOUND_EXPR, void_type_node, init, *stmts);
- }
- }
-
/* pop out of function */
poplevel (1, 1, 0);
@@ -1906,109 +1865,70 @@ end_java_method (void)
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
- cfun->x_whole_function_mode_p = 1;
-
- /* PLEASE PLEASE PLEASE WORK ON USING TREE_REST_OF_COMPILATION! */
-
- gimplify_function_tree (fndecl);
- dump_function (TDI_gimple, fndecl);
-
- remove_useless_stmts_and_vars (&DECL_SAVED_TREE (fndecl), false);
- lower_eh_constructs (&DECL_SAVED_TREE (fndecl));
-
- if (optimize > 0 && !flag_disable_tree_ssa)
- optimize_function_tree (fndecl);
-
- if (flag_inline_trees)
- {
- timevar_push (TV_INTEGRATION);
- optimize_inline_calls (fndecl);
- timevar_pop (TV_INTEGRATION);
- dump_function (TDI_inlined, fndecl);
- }
-
- /* Generate function's code. */
- expand_expr_stmt (DECL_SAVED_TREE (fndecl));
-
- /* Generate rtl for function exit. */
- expand_function_end ();
-
- /* Run the optimizers and output assembler code for this function. */
- rest_of_compilation (fndecl);
+ finish_method (fndecl);
current_function_decl = NULL_TREE;
}
-/* Expand a function's body. */
+/* Prepare a method for expansion. */
void
-java_expand_body (tree fndecl)
+finish_method (tree fndecl)
{
- const char *saved_input_filename = input_filename;
- int saved_lineno = input_line;
- tree saved_tree, saved_initial;
-
- 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);
+ tree *tp = &DECL_SAVED_TREE (fndecl);
- if (! flag_emit_class_files && ! flag_emit_xref)
+ /* Wrap body of synchronized methods in a monitorenter,
+ plus monitorexit cleanup. */
+ if (METHOD_SYNCHRONIZED (fndecl))
{
- /* 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);
-
- /* This function is being processed in whole-function mode. */
- cfun->x_whole_function_mode_p = 1;
-
- if (! flag_disable_gimple)
- {
- remove_useless_stmts_and_vars (&DECL_SAVED_TREE (fndecl), false);
- lower_eh_constructs (&DECL_SAVED_TREE (fndecl));
-
- /* Run SSA optimizers if gimplify succeeded. */
- if (optimize > 0 && !flag_disable_tree_ssa)
- optimize_function_tree (fndecl);
- }
+ tree enter, exit, lock;
+ if (METHOD_STATIC (fndecl))
+ lock = build_class_ref (DECL_CONTEXT (fndecl));
+ else
+ lock = DECL_ARGUMENTS (fndecl);
+ BUILD_MONITOR_ENTER (enter, lock);
+ BUILD_MONITOR_EXIT (exit, lock);
+ *tp = build (COMPOUND_EXPR, void_type_node,
+ enter,
+ build (TRY_FINALLY_EXPR, void_type_node, *tp, exit));
+ }
- /* Generate the RTL for this function. */
- expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 1);
+ /* Prepend class initialization for static methods reachable from
+ other classes. */
+ if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
+ && ! DECL_CLINIT_P (fndecl)
+ && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
+ {
+ tree clas = DECL_CONTEXT (fndecl);
+ tree init = build (CALL_EXPR, void_type_node,
+ build_address_of (soft_initclass_node),
+ build_tree_list (NULL_TREE, build_class_ref (clas)),
+ NULL_TREE);
+ *tp = build (COMPOUND_EXPR, TREE_TYPE (*tp), init, *tp);
}
- /* Pop out of its parameters. FIXME: poplevel clobbers DECL_SAVED_TREE
- and DECL_INITIAL. Save/restore them so inlining works. */
- pushdecl_force_head (DECL_ARGUMENTS (fndecl));
- saved_tree = DECL_SAVED_TREE (fndecl);
- saved_initial = DECL_INITIAL (fndecl);
- poplevel (1, 0, 1);
- DECL_SAVED_TREE (fndecl) = saved_tree;
- DECL_INITIAL (fndecl) = saved_initial;
- BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+ /* Convert function tree to GENERIC prior to inlining. */
+ java_genericize (fndecl);
- if (! flag_emit_class_files && ! flag_emit_xref)
- {
- /* Generate RTL for function exit. */
- input_line = DECL_FUNCTION_LAST_LINE (fndecl);
- expand_function_end ();
+ /* In unit-at-a-time mode, defer inlining, expansion to the
+ cgraph optimizers. */
+ cgraph_finalize_function (fndecl, false);
+}
- /* Run the optimizers and output the assembler code
- for this function. */
- rest_of_compilation (fndecl);
- }
+/* Optimize and expand a function's entire body. */
- timevar_pop (TV_EXPAND);
+void
+java_expand_body (tree fndecl)
+{
+ tree_rest_of_compilation (fndecl, 0);
+}
- input_filename = saved_input_filename;
- input_line = saved_lineno;
+/* Expand a Java statement. */
- current_function_decl = NULL_TREE;
+void
+java_expand_stmt (tree t)
+{
+ expand_expr_stmt_value (t, 0, 0);
}
/* We pessimistically marked all methods and fields external until we
Index: java-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/java-gimplify.c,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 java-gimplify.c
--- java-gimplify.c 13 Aug 2003 02:40:39 -0000 1.1.2.4
+++ java-gimplify.c 5 Oct 2003 16:30:29 -0000
@@ -29,6 +29,7 @@ The Free Software Foundation is independ
#include "tm.h"
#include "tree.h"
#include "java-tree.h"
+#include "tree-dump.h"
#include "tree-simple.h"
#include "toplev.h"
@@ -41,6 +42,21 @@ static tree java_gimplify_try_expr (tree
static void cleanup_compound_expr (tree *);
static void cleanup_try_finally_expr (tree *);
+static void dump_java_tree (enum tree_dump_index, tree);
+
+/* Convert a Java tree to GENERIC. */
+
+void
+java_genericize (tree fndecl)
+{
+ dump_java_tree (TDI_original, fndecl);
+
+ /* Genericize with the gimplifier. */
+ gimplify_function_tree (fndecl);
+
+ dump_function (TDI_generic, fndecl);
+}
+
/* Gimplify a Java tree. */
int
@@ -279,5 +295,22 @@ cleanup_try_finally_expr (tree *expr_p)
{
*expr_p = TREE_OPERAND (*expr_p, 0);
return;
+ }
+}
+
+/* Dump a tree of some kind. This is a convenience wrapper for the
+ dump_* functions in tree-dump.c. */
+static void
+dump_java_tree (enum tree_dump_index phase, tree t)
+{
+ FILE *stream;
+ int flags;
+
+ stream = dump_begin (phase, &flags);
+ flags |= TDF_SLIM;
+ if (stream)
+ {
+ dump_node (t, flags, stream);
+ dump_end (phase, stream);
}
}
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.153.2.23
diff -u -p -r1.153.2.23 java-tree.h
--- java-tree.h 3 Oct 2003 06:16:03 -0000 1.153.2.23
+++ java-tree.h 5 Oct 2003 16:30:30 -0000
@@ -1298,8 +1298,9 @@ extern tree java_add_stmt (tree);
extern tree java_add_local_var (tree decl);
extern tree *get_stmts (void);
-extern void start_complete_expand_method (tree);
+extern void finish_method (tree);
extern void java_expand_body (tree);
+extern void java_expand_stmt (tree);
#define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL)
@@ -1775,6 +1776,7 @@ enum
extern tree build_expr_wfl PARAMS ((tree, const char *, int, int));
+extern void java_genericize PARAMS ((tree));
extern int java_gimplify_expr PARAMS ((tree *, tree *, tree *));
#endif /* ! GCC_JAVA_TREE_H */
Index: lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.103.2.19
diff -u -p -r1.103.2.19 lang.c
--- lang.c 3 Oct 2003 06:16:03 -0000 1.103.2.19
+++ lang.c 5 Oct 2003 16:30:30 -0000
@@ -265,6 +265,9 @@ struct language_function GTY(())
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION java_expand_body
+#undef LANG_HOOKS_RTL_EXPAND_STMT
+#define LANG_HOOKS_RTL_EXPAND_STMT java_expand_stmt
+
/* Each front end provides its own. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.387.2.33
diff -u -p -r1.387.2.33 parse.y
--- parse.y 3 Oct 2003 06:16:03 -0000 1.387.2.33
+++ parse.y 5 Oct 2003 16:30:34 -0000
@@ -70,10 +70,6 @@ definitions and other extensions. */
#include "except.h"
#include "ggc.h"
#include "debug.h"
-#include "tree-inline.h"
-#include "tree-dump.h"
-#include "tree-flow.h"
-#include "cgraph.h"
/* Local function prototypes */
static char *java_accstring_lookup (int);
@@ -144,6 +140,7 @@ 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 *);
@@ -7468,52 +7465,13 @@ source_end_java_method (void)
if (IS_EMPTY_STMT (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))))
BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
- /* We've generated all the trees for this function, and it has been
- patched. Dump it to a file if the user requested it. */
- dump_java_tree (TDI_original, fndecl);
-
if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
&& ! flag_emit_class_files
&& ! flag_emit_xref)
- {
- /* PLEASE PLEASE PLEASE WORK ON USING TREE_REST_OF_COMPILATION! */
- /* Convert function tree to GIMPLE. */
- if (!flag_disable_gimple)
- {
- /* Genericize with the gimplifier. */
- gimplify_function_tree (fndecl);
- dump_function (TDI_generic, fndecl);
-
- /* In unit-at-a-time mode, defer expansion to the
- cgraph optimizers. */
- if (DECL_SAVED_TREE (fndecl) && flag_unit_at_a_time)
- {
- cgraph_finalize_function (fndecl, false);
- current_function_decl = NULL_TREE;
- java_parser_context_restore_global ();
- return;
- }
-
- /* Inline suitable calls from this function. */
- if (flag_inline_trees)
- {
- timevar_push (TV_INTEGRATION);
- optimize_inline_calls (fndecl);
- timevar_pop (TV_INTEGRATION);
- dump_function (TDI_inlined, fndecl);
- if (!keep_function_tree_in_gimple_form (fndecl))
- gimplify_function_tree (fndecl);
- }
-
- /* Debugging dump after gimplification. */
- dump_function (TDI_gimple, fndecl);
- }
-
- /* Expand the function's body. */
- java_expand_body (fndecl);
- }
+ finish_method (fndecl);
java_parser_context_restore_global ();
+ current_function_decl = NULL_TREE;
}
/* Record EXPR in the current function block. Complements compound
@@ -8114,7 +8072,6 @@ java_expand_method_bodies (tree class)
for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
{
tree block;
- tree body;
if (! DECL_FUNCTION_BODY (decl))
continue;
@@ -8123,17 +8080,9 @@ java_expand_method_bodies (tree class)
block = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
- if (TREE_CODE (block) != BLOCK)
- abort ();
-
/* Save the function body for gimplify and 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
are definitely initializing. This should be flagged. */
@@ -8165,41 +8114,7 @@ java_expand_method_bodies (tree class)
}
}
- /* 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);
-
- body = build (COMPOUND_EXPR, void_type_node,
- enter,
- build (TRY_FINALLY_EXPR, void_type_node, body, exit));
- BLOCK_EXPR_BODY (block) = body;
- }
-
- /* Expand the the function body. */
+ /* Expand the function body. */
source_end_java_method ();
}
}