This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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] Gimplifying Java


Following is my first attempt to merge the gcj source frontend with the
tree-ssa infrastructure.

It's not quite finished.  Specific shortcomings of this patch:

1) It introduces three testsuite regressions, none of which appear to be
related to the frontend.  The libjava.compile/OperatorBenchmark.java
failure is caused by folding after gimplify as described in this thread:

http://gcc.gnu.org/ml/gcc/2003-06/msg00617.html

The other two are apparently caused by wrong code generated in the
out-of-SSA pass (insert_copy_on_edge intializes a local variable to an
unitialized temporary).

I can probably fix the first failure drawing upon several good ideas from
the mailing list.  The out of SSA pass is still beyond my comprehension,
though I wonder if this isn't related to one of the known shortcomings,
such as live range overlapping.  (I do have a test case.)

2) Tree inlining is ineffective.  I suspect this is because gcj builds all
nonvirtual calls indirectly, i.e. with ADDR_EXPR.

3) The static class initialization optimization is completely broken, and
disabled in the patch.  I found that this optimization constructs a
COMPOUND_EXPR tree with an identical tree node on both branches, driving
gimplify into an infinite loop.  (The same bug causes mainline to emit
certain basic blocks twice.)

4) Debug information is incomplete.  EXPR_WITH_FILE_LOCATION nodes is
transformed into TREE_FILENAME/TREE_LINENO annotations, good enough to
single-step most methods, however backtraces are frequently incorrect.

With the possible exception of 1) these should be straightforward to fix.
Regardless, the patched compiler is good enough to build the runtime and
complete the testsuite with only the regressions mentioned above.  I've
also built and run some nontrivial Java applications with it.

Most of the conversion is handled in java_simplify_expr, however there are
other changes due to certain trees that are not acceptable to gimplify
even though they are accepted by the RTL expanders.  For example,
LOOP_EXPR nodes with trailing empty statements cause an incorrect CFG to
be constructed, breaking copy/constant propogation.  Also, the new passes
attempt to build an assignment for void type SAVE_EXPR nodes, breaking in
RTL expansion.  In another case a pointer node is passed as the
condition operand of a COND_EXPR, so rewrite_into_ssa propagates a
'1' into the 'then' branch as if it were a boolean operand.  Though these
may be bugs, the frontend could stand to be a little less sloppy when
building trees anyway.  (Does a void SAVE_EXPR ever make sense?)

Tested on i686-pc-linux-gnu with only the three regressions mentioned
above.

Jeff

2003-06-11  Jeff Sturm  <jsturm@one-point.com>

	* Make-lang.in (JAVA_OBJS): Add java-simplify.o.

	* decl.c (java_init_decl_processing): Initialize size_type_node.
	(complete_start_java_method): Update DECL_SAVED_TREE.
	(java_optimize_inline): Remove.

	* expr.c (always_initialize_class_p): Initialize to 1.
	(build_instanceof): Build proper boolean condition.
	(build_class_init): Set DECL_INITIAL for init_test_decl.
	(force_evaluation_order): Don't save_expr a void expr node.

	* java-simplify.c: New file.

	* java-tree.h (java_simplify_expr): Declare.

	* lang.c (java_tree_inlining_walk_subtrees): Remove declaration.
	(flag_optimize_sci): Initialize to 0.
	(LANG_HOOKS_TREE_INLINING_WALK_SUBTREES): Remove define.
	(LANG_HOOKS_SIMPLIFY_EXPR): Add define.
	(java_tree_inlining_walk_subtrees): Remove function.

	* parse.y (source_end_java_method): Set cfun->x_whole_function_mode_p.
	Gimplify. optimize tree before expanding.  Update comments.
	(java_expand_method_bodies): Always save DECL_SAVED_TREE.
	(patch_invoke): Don't save_expr force_evaluation_order result.
	(patch_assignment): Use simpler compound expression.
	(patch_if_else_statement): Don't optimize constant condition nodes.


Index: Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Make-lang.in,v
retrieving revision 1.88.2.10
diff -u -p -r1.88.2.10 Make-lang.in
--- Make-lang.in	7 May 2003 13:32:56 -0000	1.88.2.10
+++ Make-lang.in	11 Jun 2003 22:57:45 -0000
@@ -110,7 +110,8 @@ JAVA_OBJS = java/parse.o java/class.o ja
   java/zextract.o java/jcf-io.o java/jcf-parse.o java/mangle.o \
   java/mangle_name.o java/builtins.o java/resource.o \
   java/jcf-write.o java/buffer.o java/check-init.o java/jcf-depend.o \
-  java/jcf-path.o java/xref.o java/boehm.o java/java-tree-inline.o mkdeps.o
+  java/jcf-path.o java/xref.o java/boehm.o java/java-tree-inline.o \
+  java/java-simplify.o mkdeps.o

 GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
   java/zextract.o version.o mkdeps.o errors.o ggc-none.o
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.128.2.15
diff -u -p -r1.128.2.15 decl.c
--- decl.c	3 Jun 2003 16:52:07 -0000	1.128.2.15
+++ decl.c	11 Jun 2003 22:57:45 -0000
@@ -435,7 +435,10 @@ java_init_decl_processing (void)
   pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
 			unsigned_long_type_node));

-  set_sizetype (make_unsigned_type (POINTER_SIZE));
+  /* This is not a java type, however tree-dfa requires a definition for
+     size_type_node.  */
+  size_type_node = make_unsigned_type (POINTER_SIZE);
+  set_sizetype (size_type_node);

   /* Define these next since types below may used them.  */
   integer_type_node = java_type_for_size (INT_TYPE_SIZE, 0);
@@ -1728,6 +1731,11 @@ complete_start_java_method (tree fndecl)
 			build (TRY_FINALLY_EXPR, void_type_node, body, exit));
 	  TREE_SIDE_EFFECTS (lock) = 1;
 	  BLOCK_EXPR_BODY (function_body) = lock;
+
+	  /* If we previously saved the tree for inlining,
+	     update that too.  */
+	  if (DECL_SAVED_TREE (fndecl) != NULL_TREE)
+	    DECL_SAVED_TREE (fndecl) = lock;
 	}
     }
 }
@@ -1830,17 +1838,6 @@ dump_function (enum tree_dump_index phas
     }
 }

-void java_optimize_inline (tree fndecl)
-{
-  if (flag_inline_trees)
-    {
-      timevar_push (TV_INTEGRATION);
-      optimize_inline_calls (fndecl);
-      timevar_pop (TV_INTEGRATION);
-      dump_function (TDI_inlined, fndecl);
-    }
-}
-
 /* We pessimistically marked all methods and fields external until we
    knew what set of classes we were planning to compile.  Now mark those
    associated with CLASS to be generated locally as not external.  */
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.147.2.13
diff -u -p -r1.147.2.13 expr.c
--- expr.c	7 May 2003 13:32:57 -0000	1.147.2.13
+++ expr.c	11 Jun 2003 22:57:45 -0000
@@ -94,7 +94,8 @@ tree dtable_ident = NULL_TREE;

 /* Set to nonzero value in order to emit class initialization code
    before static field references.  */
-int always_initialize_class_p;
+/* FIXME: Make this work with gimplify.  */
+int always_initialize_class_p = 1;

 /* We store the stack state in two places:
    Within a basic block, we use the quick_stack, which is a
@@ -1224,7 +1225,8 @@ build_instanceof (tree value, tree type)
     {
       tree save = save_expr (value);
       expr = build (COND_EXPR, itype,
-		    save,
+		    build (NE_EXPR, boolean_type_node,
+			   save, null_pointer_node),
 		    build (EQ_EXPR, itype,
 			   build_get_class (save),
 			   build_class_ref (type)),
@@ -1710,6 +1712,7 @@ build_class_init (tree clas, tree expr)
              optimizing class initialization. */
 	  if (!STATIC_CLASS_INIT_OPT_P ())
 	    DECL_BIT_INDEX(*init_test_decl) = -1;
+	  DECL_INITIAL (*init_test_decl) = integer_zero_node;
 	}

       init = build (CALL_EXPR, void_type_node,
@@ -3370,7 +3373,9 @@ force_evaluation_order (tree node)

       if (cmp)
 	{
-	  cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
+	  cmp = build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
+	  if (TREE_TYPE (cmp) != void_type_node)
+	    cmp = save_expr (cmp);
 	  CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
 	  TREE_SIDE_EFFECTS (cmp) = 1;
 	  node = cmp;
Index: java-simplify.c
===================================================================
RCS file: java-simplify.c
diff -N java-simplify.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java-simplify.c	11 Jun 2003 22:57:45 -0000
@@ -0,0 +1,313 @@
+/* Java(TM) language-specific simplification routines.
+
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "java-tree.h"
+#include "tree-simple.h"
+#include "toplev.h"
+
+static tree java_simplify_labeled_block_expr (tree);
+static tree java_simplify_exit_block_expr (tree);
+static tree java_simplify_case_expr (tree);
+static tree java_simplify_default_expr (tree);
+static tree java_simplify_block (tree);
+static tree java_simplify_new_array_init (tree);
+static tree java_simplify_try_expr (tree);
+
+static void cleanup_compound_expr (tree *);
+static void cleanup_try_finally_expr (tree *);
+
+/* Simplify a Java tree.  */
+
+int
+java_simplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
+		    tree *post_p ATTRIBUTE_UNUSED)
+{
+  switch (TREE_CODE (*expr_p))
+    {
+    case BLOCK:
+      *expr_p = java_simplify_block (*expr_p);
+      return 1;
+
+    case LABELED_BLOCK_EXPR:
+      *expr_p = java_simplify_labeled_block_expr (*expr_p);
+      return 1;
+
+    case EXIT_BLOCK_EXPR:
+      *expr_p = java_simplify_exit_block_expr (*expr_p);
+      return 1;
+
+    case EXPR_WITH_FILE_LOCATION:
+      {
+	tree wfl = *expr_p;
+	*expr_p = EXPR_WFL_NODE (wfl);
+	annotate_with_file_line (*expr_p, EXPR_WFL_FILENAME (wfl),
+				 EXPR_WFL_LINENO (wfl));
+      }
+      return 1;
+
+    case CASE_EXPR:
+      *expr_p = java_simplify_case_expr (*expr_p);
+      return 1;
+
+    case DEFAULT_EXPR:
+      *expr_p = java_simplify_default_expr (*expr_p);
+      return 1;
+
+    case NEW_ARRAY_INIT:
+      *expr_p = java_simplify_new_array_init (*expr_p);
+      return 1;
+
+    case TRY_EXPR:
+      *expr_p = java_simplify_try_expr (*expr_p);
+      return 1;
+
+    case JAVA_CATCH_EXPR:
+      *expr_p = TREE_OPERAND (*expr_p, 0);
+      return 1;
+
+    case JAVA_EXC_OBJ_EXPR:
+      *expr_p = build_exception_object_ref (TREE_TYPE (*expr_p));
+      return 1;
+
+    /* These should already be lowered before we get here.  */
+    case URSHIFT_EXPR:
+    case COMPARE_EXPR:
+    case COMPARE_L_EXPR:
+    case COMPARE_G_EXPR:
+    case UNARY_PLUS_EXPR:
+    case NEW_ARRAY_EXPR:
+    case NEW_ANONYMOUS_ARRAY_EXPR:
+    case NEW_CLASS_EXPR:
+    case THIS_EXPR:
+    case SYNCHRONIZED_EXPR:
+    case CONDITIONAL_EXPR:
+    case INSTANCEOF_EXPR:
+    case CLASS_LITERAL:
+      abort ();
+
+    case COMPOUND_EXPR:
+      cleanup_compound_expr (expr_p);
+      return 0;
+
+    case TRY_FINALLY_EXPR:
+      cleanup_try_finally_expr (expr_p);
+      return 0;
+
+    default:
+      return 0;
+    }
+}
+
+/* Simplify LABELED_BLOCK_EXPR.  */
+
+static tree
+java_simplify_labeled_block_expr (tree expr)
+{
+  tree body = LABELED_BLOCK_BODY (expr);
+  tree label = build (LABEL_EXPR, void_type_node, LABELED_BLOCK_LABEL (expr));
+  if (body != NULL_TREE)
+    {
+      tree labeled_body = build (COMPOUND_EXPR, void_type_node, body, label);
+      return labeled_body;
+    }
+  else
+    return label;
+}
+
+static tree
+java_simplify_exit_block_expr (tree expr)
+{
+  tree label = TREE_OPERAND (expr, 0);
+  if (TREE_CODE (label) == LABEL_EXPR)
+    label = TREE_OPERAND (label, 0);
+  else if (TREE_CODE (label) == LABELED_BLOCK_EXPR)
+    label = LABELED_BLOCK_LABEL (label);
+  DECL_CONTEXT (label) = current_function_decl;
+  return build1 (GOTO_EXPR, void_type_node, label);
+}
+
+static tree
+java_simplify_case_expr (tree expr)
+{
+  tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+  DECL_CONTEXT (label) = current_function_decl;
+  return build (CASE_LABEL_EXPR, void_type_node,
+		TREE_OPERAND (expr, 0), NULL_TREE, label);
+}
+
+static tree
+java_simplify_default_expr (tree expr ATTRIBUTE_UNUSED)
+{
+  tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+  DECL_CONTEXT (label) = current_function_decl;
+  return build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE, label);
+}
+
+/* Simplify BLOCK into a BIND_EXPR.  */
+
+static tree
+java_simplify_block (tree block)
+{
+  tree decls = BLOCK_VARS (block);
+  tree body = BLOCK_EXPR_BODY (block);
+  tree bind;
+
+  /* Don't bother with empty blocks.  */
+  if (IS_EMPTY_STMT (body))
+    return body;
+
+  bind = build (BIND_EXPR, TREE_TYPE (block), decls, body, block);
+
+  gimple_push_bind_expr (bind);
+  simplify_stmt (&BIND_EXPR_BODY (bind));
+  gimple_pop_bind_expr ();
+
+  return bind;
+}
+
+/* Simplify a NEW_ARRAY_INIT node into array/element assignments.  */
+
+static tree
+java_simplify_new_array_init (tree exp)
+{
+  tree array_type = TREE_TYPE (TREE_TYPE (exp));
+  tree data_field = lookup_field (&array_type, get_identifier ("data"));
+  tree element_type = TYPE_ARRAY_ELEMENT (array_type);
+  HOST_WIDE_INT ilength = java_array_type_length (array_type);
+  tree length = build_int_2 (ilength, 0);
+  tree init = TREE_OPERAND (exp, 0);
+  tree values = CONSTRUCTOR_ELTS (init);
+
+  tree array_ptr_type = build_pointer_type (array_type);
+  tree block = build (BLOCK, array_ptr_type, NULL_TREE);
+  tree tmp = build_decl (VAR_DECL, get_identifier ("<tmp>"), array_ptr_type);
+  tree array = build_decl (VAR_DECL, get_identifier ("<array>"), array_ptr_type);
+  tree body = build (MODIFY_EXPR, array_ptr_type, tmp,
+		     build_new_array (element_type, length));
+
+  int index = 0;
+
+  /* FIXME: try to allocate array statically?  */
+  while (values != NULL_TREE)
+    {
+      /* FIXME: Should use build_java_arrayaccess here, but avoid
+	 bounds checking.  */
+      tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),
+			build_java_indirect_ref (array_type, tmp, 0),
+			data_field);
+      tree assignment = build (MODIFY_EXPR, element_type,
+  			       build (ARRAY_REF, element_type, lhs,
+				      build_int_2 (index++, 0)),
+			       TREE_VALUE (values));
+      body = build (COMPOUND_EXPR, element_type, body, assignment);
+      values = TREE_CHAIN (values);
+    }
+
+  body = build (COMPOUND_EXPR, array_ptr_type, body,
+		build (MODIFY_EXPR, array_ptr_type, array, tmp));
+  TREE_CHAIN (tmp) = array;
+  BLOCK_VARS (block) = tmp;
+  BLOCK_EXPR_BODY (block) = body;
+  return java_simplify_block (block);
+}
+
+static tree
+java_simplify_try_expr (tree try_expr)
+{
+  tree body = TREE_OPERAND (try_expr, 0);
+  tree handler = TREE_OPERAND (try_expr, 1);
+  tree catch = NULL_TREE;
+
+  /* Build a CATCH_EXPR for each handler.  */
+  while (handler)
+    {
+      tree java_catch = TREE_OPERAND (handler, 0);
+      tree expr = build (CATCH_EXPR, void_type_node,
+			 TREE_TYPE (TREE_TYPE (BLOCK_EXPR_DECLS (java_catch))),
+			 handler);
+      if (catch)
+	catch = build (COMPOUND_EXPR, void_type_node, catch, expr);
+      else
+	catch = expr;
+      handler = TREE_CHAIN (handler);
+    }
+  return build (TRY_CATCH_EXPR, void_type_node, body, catch);
+}
+
+/* Ensure that every COMPOUND_EXPR has a type.  Also purge any
+   COMPOUND_EXPR with one or more empty statements.  */
+
+static void
+cleanup_compound_expr (tree *expr_p)
+{
+  if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == COMPOUND_EXPR)
+    cleanup_compound_expr (&TREE_OPERAND (*expr_p, 0));
+  if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == COMPOUND_EXPR)
+    cleanup_compound_expr (&TREE_OPERAND (*expr_p, 1));
+
+  if (TREE_OPERAND (*expr_p, 0) == NULL_TREE
+      || IS_EMPTY_STMT (TREE_OPERAND (*expr_p, 0)))
+    {
+      *expr_p = TREE_OPERAND (*expr_p, 1);
+      return;
+    }
+  if (TREE_OPERAND (*expr_p, 1) == NULL_TREE
+      || IS_EMPTY_STMT (TREE_OPERAND (*expr_p, 1)))
+    {
+      *expr_p = TREE_OPERAND (*expr_p, 0);
+      return;
+    }
+
+  if (TREE_TYPE (*expr_p) == NULL_TREE)
+    {
+      tree last = TREE_OPERAND (*expr_p, 1);
+      TREE_TYPE (*expr_p) = TREE_TYPE (last);
+    }
+}
+
+/* Ensure that every TRY_FINALLY_EXPR has at least one non-empty
+   statement in both its try and finally blocks.  */
+
+static void
+cleanup_try_finally_expr (tree *expr_p)
+{
+  if (TREE_OPERAND (*expr_p, 0) == NULL_TREE
+      || IS_EMPTY_STMT (TREE_OPERAND (*expr_p, 0)))
+    {
+      *expr_p = TREE_OPERAND (*expr_p, 1);
+      return;
+    }
+  if (TREE_OPERAND (*expr_p, 1) == NULL_TREE
+      || IS_EMPTY_STMT (TREE_OPERAND (*expr_p, 1)))
+    {
+      *expr_p = TREE_OPERAND (*expr_p, 0);
+      return;
+    }
+}
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.153.2.16
diff -u -p -r1.153.2.16 java-tree.h
--- java-tree.h	3 Jun 2003 16:52:07 -0000	1.153.2.16
+++ java-tree.h	11 Jun 2003 22:57:45 -0000
@@ -1772,4 +1772,6 @@ enum

 extern tree build_expr_wfl              PARAMS ((tree, const char *, int, int));

+extern int java_simplify_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.13
diff -u -p -r1.103.2.13 lang.c
--- lang.c	9 Apr 2003 19:28:43 -0000	1.103.2.13
+++ lang.c	11 Jun 2003 22:57:45 -0000
@@ -63,8 +63,6 @@ static void put_decl_string (const char
 static void put_decl_node (tree);
 static void java_print_error_function (diagnostic_context *, const char *);
 static int process_option_with_no (const char *, const struct string_option *, int);
-static tree java_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
-					      void *, void *);
 static int java_unsafe_for_reeval (tree);
 static int merge_init_test_initialization (void * *, void *);
 static int inline_init_test_initialization (void * *, void *);
@@ -176,7 +174,8 @@ int flag_force_classes_archive_check;

 /* When zero, don't optimize static class initialization. This flag shouldn't
    be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
-int flag_optimize_sci = 1;
+/* FIXME: Make this work with gimplify.  */
+int flag_optimize_sci = 0;

 /* When nonzero, use offset tables for virtual method calls
    in order to improve binary compatibility. */
@@ -284,12 +283,12 @@ struct language_function GTY(())
 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type

-#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
-#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
-
 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree

+#undef LANG_HOOKS_SIMPLIFY_EXPR
+#define LANG_HOOKS_SIMPLIFY_EXPR java_simplify_expr
+
 /* Each front end provides its own.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;

@@ -854,52 +853,6 @@ decl_constant_value (tree decl)
       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
     return DECL_INITIAL (decl);
   return decl;
-}
-
-/* Walk the language specific tree nodes during inlining.  */
-
-static tree
-java_tree_inlining_walk_subtrees (tree *tp ATTRIBUTE_UNUSED,
-				  int *subtrees ATTRIBUTE_UNUSED,
-				  walk_tree_fn func ATTRIBUTE_UNUSED,
-				  void *data ATTRIBUTE_UNUSED,
-				  void *htab ATTRIBUTE_UNUSED)
-{
-  enum tree_code code;
-  tree result;
-
-#define WALK_SUBTREE(NODE)				\
-  do							\
-    {							\
-      result = walk_tree (&(NODE), func, data, htab);	\
-      if (result)					\
-	return result;					\
-    }							\
-  while (0)
-
-  tree t = *tp;
-  if (!t)
-    return NULL_TREE;
-
-  code = TREE_CODE (t);
-  switch (code)
-    {
-    case BLOCK:
-      if (BLOCK_EXPR_BODY (t))
-	{
-	  tree *prev = &BLOCK_EXPR_BODY (*tp);
-	  while (*prev)
-	    {
-	      WALK_SUBTREE (*prev);
-	      prev = &TREE_CHAIN (*prev);
-	    }
-	}
-      return NULL_TREE;
-      break;
-
-    default:
-      return NULL_TREE;
-    }
 }

 /* Called from unsafe_for_reeval.  */
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.387.2.22
diff -u -p -r1.387.2.22 parse.y
--- parse.y	3 Jun 2003 16:52:07 -0000	1.387.2.22
+++ parse.y	11 Jun 2003 22:57:46 -0000
@@ -7376,13 +7376,29 @@ 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);
+  cfun->x_whole_function_mode_p = 1;

-  /* 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)));
+    {
+      /* Simplify and run optimizers.  */
+      simplify_function_tree (fndecl);
+      dump_function (TDI_simple, 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));
+    }

   /* pop out of its parameters */
   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
@@ -7399,7 +7415,6 @@ source_end_java_method (void)
 			       TREE_FILENAME (fndecl),
 			       TREE_SOURCE_LINE_FIRST (fndecl));

-      /* Run the optimizers and output assembler code for this function. */
       rest_of_compilation (fndecl);
     }

@@ -8025,10 +8040,9 @@ java_expand_method_bodies (tree class)

       current_function_decl = decl;

-      /* Save the function for inlining.  */
-      if (flag_inline_trees)
-	DECL_SAVED_TREE (decl) =
-	  BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
+      /* Save the function for gimplify and inlining.  */
+      DECL_SAVED_TREE (decl) =
+	BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));

       /* It's time to assign the variable flagging static class
 	 initialization based on which classes invoked static methods
@@ -10739,7 +10753,7 @@ patch_invoke (tree patch, tree method, t
       /* We have to call force_evaluation_order now because creating a
 	 COMPOUND_EXPR wraps the arg list in a way that makes it
 	 unrecognizable by force_evaluation_order later.  Yuk.  */
-      tree save = save_expr (force_evaluation_order (patch));
+      tree save = force_evaluation_order (patch);
       tree type = TREE_TYPE (patch);

       patch = build (COMPOUND_EXPR, type, save, build_java_empty_stmt ());
@@ -12763,7 +12777,7 @@ patch_assignment (tree node, tree wfl_op
 	case INDIRECT_REF:
 	case COMPONENT_REF:
 	  /* Transform a = foo.bar
-	     into a = { int tmp; tmp = foo.bar; tmp; ).
+	     into a = ({int tmp; tmp = foo.bar;}).
 	     We need to ensure that if a read from memory fails
 	     because of a NullPointerException, a destination variable
 	     will remain unchanged.  An explicit temporary does what
@@ -12780,8 +12794,7 @@ patch_assignment (tree node, tree wfl_op
 	    tree assignment
 	      = build (MODIFY_EXPR, TREE_TYPE (new_rhs), tmp, fold (new_rhs));
 	    BLOCK_VARS (block) = tmp;
-	    BLOCK_EXPR_BODY (block)
-	      = build (COMPOUND_EXPR, TREE_TYPE (new_rhs), assignment, tmp);
+	    BLOCK_EXPR_BODY (block) = assignment;
 	    TREE_SIDE_EFFECTS (block) = 1;
 	    new_rhs = block;
 	  }
@@ -14764,20 +14777,6 @@ patch_if_else_statement (tree node)
       return error_mark_node;
     }

-  if (TREE_CODE (expression) == INTEGER_CST)
-    {
-      if (integer_zerop (expression))
-	node = TREE_OPERAND (node, 2);
-      else
-	node = TREE_OPERAND (node, 1);
-      if (CAN_COMPLETE_NORMALLY (node) != can_complete_normally)
-	{
-	  node = build (COMPOUND_EXPR, void_type_node, node,
-		        build_java_empty_stmt ());
-	  CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
-	}
-      return node;
-    }
   TREE_TYPE (node) = void_type_node;
   TREE_SIDE_EFFECTS (node) = 1;
   CAN_COMPLETE_NORMALLY (node) = can_complete_normally;




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