This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: [tree-ssa] Gimplifying Java (updated)
- From: Jeff Sturm <jsturm at one-point dot com>
- To: Diego Novillo <dnovillo at redhat dot com>
- Cc: java-patches at gcc dot gnu dot org, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 17 Jun 2003 14:39:08 -0400 (EDT)
- Subject: Re: [tree-ssa] Gimplifying Java (updated)
On 11 Jun 2003, Diego Novillo wrote:
> Could you s/simplify/gimplify/ and s/simple/gimple/?
> Also, can gimplification be disabled with -fdisable-simple?
Done, see updated patch below. Depends on a workaround for EH:
http://gcc.gnu.org/ml/gcc-patches/2003-06/msg01965.html
Tested on i686-pc-linux-gnu. OK for tree-ssa branch?
2003-06-17 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 -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 17 Jun 2003 18:30:28 -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-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 -u -p -r1.128.2.15 decl.c
--- decl.c 3 Jun 2003 16:52:07 -0000 1.128.2.15
+++ decl.c 17 Jun 2003 18:30:28 -0000
@@ -57,7 +57,6 @@ static struct binding_level *make_bindin
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;
@@ -435,7 +434,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 +1730,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;
}
}
}
@@ -1812,33 +1819,6 @@ end_java_method (void)
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
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 17 Jun 2003 18:30:29 -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-gimplify.c
===================================================================
RCS file: java-gimplify.c
diff -N java-gimplify.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java-gimplify.c 17 Jun 2003 18:30:29 -0000
@@ -0,0 +1,313 @@
+/* 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_labeled_block_expr (tree);
+static tree java_gimplify_exit_block_expr (tree);
+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 LABELED_BLOCK_EXPR:
+ *expr_p = java_gimplify_labeled_block_expr (*expr_p);
+ return 1;
+
+ case EXIT_BLOCK_EXPR:
+ *expr_p = java_gimplify_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_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;
+ }
+}
+
+/* Gimplify LABELED_BLOCK_EXPR. */
+
+static tree
+java_gimplify_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_gimplify_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_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);
+ 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);
+ gimplify_stmt (&BIND_EXPR_BODY (bind));
+ gimple_pop_bind_expr ();
+
+ return bind;
+}
+
+/* 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 -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 17 Jun 2003 18:30:29 -0000
@@ -1772,4 +1772,6 @@ enum
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 -u -p -r1.103.2.13 lang.c
--- lang.c 9 Apr 2003 19:28:43 -0000 1.103.2.13
+++ lang.c 17 Jun 2003 18:30:29 -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_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;
@@ -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 17 Jun 2003 18:30:31 -0000
@@ -71,6 +71,7 @@ definitions and other extensions. */
#include "ggc.h"
#include "debug.h"
#include "tree-inline.h"
+#include "tree-dump.h"
/* Local function prototypes */
static char *java_accstring_lookup (int);
@@ -7376,13 +7377,31 @@ 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)));
+ {
+ if (!flag_disable_gimple)
+ {
+ /* Gimplify and run optimizers. */
+ cfun->x_whole_function_mode_p = 1;
+ gimplify_function_tree (fndecl);
+ dump_function (TDI_gimple, 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 +7418,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 +8043,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 +10756,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 +12780,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 +12797,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 +14780,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;