[tree-ssa] Gimplifying Java (updated)

Jeff Sturm jsturm@one-point.com
Wed Jun 18 23:43:00 GMT 2003


On Tue, 17 Jun 2003, Jason Merrill wrote:
> > Or, if these tree codes are only used by Java, perhaps they should
> > disappear from the backend altogether.
>
> They seem like a useful construct, though the way EXIT_BLOCK_EXPR points to
> the LABELED_BLOCK_EXPR causes circularity issues.

Potentially.  Although the way gcj uses EXIT_BLOCK_EXPR the labeled block
should already have been lowered once we get there, I'm not really
checking for that.  (One of my earlier patches swapped out the
LABELED_BLOCK_EXPR operand for a LABEL_EXPR, so I had a test for that; the
current patch will simply abort.)

New patch follows.  Thanks to all who commented on it.

Tested on x86, still depends on
http://gcc.gnu.org/ml/gcc-patches/2003-06/msg02137.html and
http://gcc.gnu.org/ml/gcc-patches/2003-06/msg01965.html.

Jeff

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

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

	* decl.c (java_init_decl_processing): Initialize size_type_node.
	(complete_start_java_method): Update DECL_SAVED_TREE.
	(dump_function): Remove.
	(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-gimplify.c: New file.

	* java-tree.h (java_gimplify_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 -c -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	18 Jun 2003 23:30:24 -0000
*************** JAVA_OBJS = java/parse.o java/class.o ja
*** 110,116 ****
    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

  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
--- 110,117 ----
    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 \
!   java/java-gimplify.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 -c -p -r1.128.2.15 decl.c
*** decl.c	3 Jun 2003 16:52:07 -0000	1.128.2.15
--- decl.c	18 Jun 2003 23:30:24 -0000
*************** static struct binding_level *make_bindin
*** 57,63 ****
  static tree create_primitive_vtable (const char *);
  static tree check_local_named_variable (tree, tree, int, int *);
  static tree check_local_unnamed_variable (tree, tree, tree);
- static void dump_function (enum tree_dump_index, tree);

  /* Name of the Cloneable class.  */
  tree java_lang_cloneable_identifier_node;
--- 57,62 ----
*************** java_init_decl_processing (void)
*** 435,441 ****
    pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
  			unsigned_long_type_node));

!   set_sizetype (make_unsigned_type (POINTER_SIZE));

    /* Define these next since types below may used them.  */
    integer_type_node = java_type_for_size (INT_TYPE_SIZE, 0);
--- 434,443 ----
    pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
  			unsigned_long_type_node));

!   /* 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);
*************** complete_start_java_method (tree fndecl)
*** 1728,1733 ****
--- 1730,1740 ----
  			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;
  	}
      }
  }
*************** end_java_method (void)
*** 1812,1844 ****
    rest_of_compilation (fndecl);

    current_function_decl = NULL_TREE;
- }
-
- /* Dump FUNCTION_DECL FN as tree dump PHASE. */
-
- static void
- dump_function (enum tree_dump_index phase, tree fn)
- {
-   FILE *stream;
-   int flags;
-
-   stream = dump_begin (phase, &flags);
-   if (stream)
-     {
-       dump_node (fn, TDF_SLIM | flags, stream);
-       dump_end (phase, stream);
-     }
- }
-
- 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
--- 1819,1824 ----
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.147.2.13
diff -c -p -r1.147.2.13 expr.c
*** expr.c	7 May 2003 13:32:57 -0000	1.147.2.13
--- expr.c	18 Jun 2003 23:30:24 -0000
*************** tree dtable_ident = NULL_TREE;
*** 94,100 ****

  /* Set to nonzero value in order to emit class initialization code
     before static field references.  */
! int always_initialize_class_p;

  /* We store the stack state in two places:
     Within a basic block, we use the quick_stack, which is a
--- 94,101 ----

  /* Set to nonzero value in order to emit class initialization code
     before static field references.  */
! /* 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
*************** build_instanceof (tree value, tree type)
*** 1224,1230 ****
      {
        tree save = save_expr (value);
        expr = build (COND_EXPR, itype,
! 		    save,
  		    build (EQ_EXPR, itype,
  			   build_get_class (save),
  			   build_class_ref (type)),
--- 1225,1232 ----
      {
        tree save = save_expr (value);
        expr = build (COND_EXPR, itype,
! 		    build (NE_EXPR, boolean_type_node,
! 			   save, null_pointer_node),
  		    build (EQ_EXPR, itype,
  			   build_get_class (save),
  			   build_class_ref (type)),
*************** build_class_init (tree clas, tree expr)
*** 1710,1715 ****
--- 1712,1718 ----
               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,
*************** force_evaluation_order (tree node)
*** 3370,3376 ****

        if (cmp)
  	{
! 	  cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
  	  CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
  	  TREE_SIDE_EFFECTS (cmp) = 1;
  	  node = cmp;
--- 3373,3381 ----

        if (cmp)
  	{
! 	  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-gimplify.c
===================================================================
RCS file: java-gimplify.c
diff -N java-gimplify.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- java-gimplify.c	18 Jun 2003 23:30:24 -0000
***************
*** 0 ****
--- 1,268 ----
+ /* Java(TM) language-specific gimplification 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_gimplify_case_expr (tree);
+ static tree java_gimplify_default_expr (tree);
+ static tree java_gimplify_block (tree);
+ static tree java_gimplify_new_array_init (tree);
+ static tree java_gimplify_try_expr (tree);
+
+ static void cleanup_compound_expr (tree *);
+ static void cleanup_try_finally_expr (tree *);
+
+ /* Gimplify a Java tree.  */
+
+ int
+ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
+ 		    tree *post_p ATTRIBUTE_UNUSED)
+ {
+   switch (TREE_CODE (*expr_p))
+     {
+     case BLOCK:
+       *expr_p = java_gimplify_block (*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_gimplify_case_expr (*expr_p);
+       return 1;
+
+     case DEFAULT_EXPR:
+       *expr_p = java_gimplify_default_expr (*expr_p);
+       return 1;
+
+     case NEW_ARRAY_INIT:
+       *expr_p = java_gimplify_new_array_init (*expr_p);
+       return 1;
+
+     case TRY_EXPR:
+       *expr_p = java_gimplify_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;
+     }
+ }
+
+ static tree
+ java_gimplify_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_gimplify_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);
+ }
+
+ /* Gimplify BLOCK into a BIND_EXPR.  */
+
+ static tree
+ java_gimplify_block (tree block)
+ {
+   tree decls = BLOCK_VARS (block);
+   tree body = BLOCK_EXPR_BODY (block);
+
+   /* Don't bother with empty blocks.  */
+   if (IS_EMPTY_STMT (body))
+     return body;
+
+   return build (BIND_EXPR, TREE_TYPE (block), decls, body, block);
+ }
+
+ /* Gimplify a NEW_ARRAY_INIT node into array/element assignments.  */
+
+ static tree
+ java_gimplify_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_gimplify_block (block);
+ }
+
+ static tree
+ java_gimplify_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 -c -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	18 Jun 2003 23:30:24 -0000
*************** enum
*** 1772,1775 ****
--- 1772,1777 ----

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

+ 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.13
diff -c -p -r1.103.2.13 lang.c
*** lang.c	9 Apr 2003 19:28:43 -0000	1.103.2.13
--- lang.c	18 Jun 2003 23:30:24 -0000
*************** static void put_decl_string (const char
*** 63,70 ****
  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 *);
--- 63,68 ----
*************** int flag_force_classes_archive_check;
*** 176,182 ****

  /* 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;

  /* When nonzero, use offset tables for virtual method calls
     in order to improve binary compatibility. */
--- 174,181 ----

  /* When zero, don't optimize static class initialization. This flag shouldn't
     be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
! /* 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. */
*************** struct language_function GTY(())
*** 284,295 ****
  #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

  /* Each front end provides its own.  */
  const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;

--- 283,294 ----
  #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
  #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type

  #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
  #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree

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

*************** decl_constant_value (tree decl)
*** 854,905 ****
        && 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.  */
--- 853,858 ----
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.387.2.22
diff -c -p -r1.387.2.22 parse.y
*** parse.y	3 Jun 2003 16:52:07 -0000	1.387.2.22
--- parse.y	18 Jun 2003 23:30:25 -0000
*************** definitions and other extensions.  */
*** 71,76 ****
--- 71,77 ----
  #include "ggc.h"
  #include "debug.h"
  #include "tree-inline.h"
+ #include "tree-dump.h"

  /* Local function prototypes */
  static char *java_accstring_lookup (int);
*************** source_end_java_method (void)
*** 7376,7388 ****
       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));
--- 7377,7411 ----
       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)
!     {
!       /* Convert function tree to GIMPLE.  */
!       if (!flag_disable_gimple)
! 	{
! 	  cfun->x_whole_function_mode_p = 1;
! 	  gimplify_function_tree (fndecl);
! 	  dump_function (TDI_gimple, fndecl);
! 	}
!
!       /* 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);
! 	}
!
!       /* Run SSA optimizers if gimplify was successful.  */
!       if (keep_function_tree_in_gimple_form (fndecl)
! 	  && optimize > 0 && !flag_disable_tree_ssa)
! 	optimize_function_tree (fndecl);
!
!       /* Generate function's code.  */
!       expand_expr_stmt (DECL_SAVED_TREE (fndecl));
!     }

    /* pop out of its parameters */
    pushdecl_force_head (DECL_ARGUMENTS (fndecl));
*************** source_end_java_method (void)
*** 7399,7405 ****
  			       TREE_FILENAME (fndecl),
  			       TREE_SOURCE_LINE_FIRST (fndecl));

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

--- 7422,7427 ----
*************** java_expand_method_bodies (tree class)
*** 8025,8034 ****

        current_function_decl = decl;

!       /* Save the function for inlining.  */
!       if (flag_inline_trees)
! 	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
--- 8047,8055 ----

        current_function_decl = 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
*************** patch_invoke (tree patch, tree method, t
*** 10739,10745 ****
        /* 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 type = TREE_TYPE (patch);

        patch = build (COMPOUND_EXPR, type, save, build_java_empty_stmt ());
--- 10760,10766 ----
        /* 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 = force_evaluation_order (patch);
        tree type = TREE_TYPE (patch);

        patch = build (COMPOUND_EXPR, type, save, build_java_empty_stmt ());
*************** patch_assignment (tree node, tree wfl_op
*** 12763,12769 ****
  	case INDIRECT_REF:
  	case COMPONENT_REF:
  	  /* Transform a = foo.bar
! 	     into a = { int tmp; tmp = foo.bar; tmp; ).
  	     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
--- 12784,12790 ----
  	case INDIRECT_REF:
  	case COMPONENT_REF:
  	  /* Transform a = foo.bar
! 	     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
*************** patch_assignment (tree node, tree wfl_op
*** 12780,12787 ****
  	    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);
  	    TREE_SIDE_EFFECTS (block) = 1;
  	    new_rhs = block;
  	  }
--- 12801,12807 ----
  	    tree assignment
  	      = build (MODIFY_EXPR, TREE_TYPE (new_rhs), tmp, fold (new_rhs));
  	    BLOCK_VARS (block) = tmp;
! 	    BLOCK_EXPR_BODY (block) = assignment;
  	    TREE_SIDE_EFFECTS (block) = 1;
  	    new_rhs = block;
  	  }
*************** patch_if_else_statement (tree node)
*** 14764,14783 ****
        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;
--- 14784,14789 ----



More information about the Java-patches mailing list