This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 ();
     }
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]