Make-lang.in (java-tree-inline.o): New.
authorAndrew Haley <aph@cambridge.redhat.com>
Fri, 16 Aug 2002 10:32:30 +0000 (10:32 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Fri, 16 Aug 2002 10:32:30 +0000 (10:32 +0000)
2002-07-30  Andrew Haley  <aph@cambridge.redhat.com>

        * Make-lang.in (java-tree-inline.o): New.
        (JAVA_OBJS): Add java-tree-inline.o.
        * parse.y (source_end_java_method): Call java_optimize_inline.
        (java_expand_method_bodies): Save method's tree in
        DECL_SAVED_TREE.
        (add_stmt_to_compound): Keep track of the number of statments.
        * lang.c (java_init): Enable flag_inline_trees.
        (java_post_options): If flag_inline_functions is on, enable
        flag_inline_trees instread.
        (decl_constant_value): New.
        (java_tree_inlining_walk_subtrees): New.
        * java-tree.h (DECL_NUM_STMTS): New macro.
        (java_optimize_inline): Declare.
        * expr.c (java_expand_expr): Allow a BLOCK to return a value.
        Handle a LABEL_EXPR.
        * decl.c (build_result_decl): If we already have a DECL_RESULT
        don't make another.
        (dump_function): New.
        (java_optimize_inline): New.
        (dump_function): New.

From-SVN: r56377

gcc/java/ChangeLog
gcc/java/Make-lang.in
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/lang.c
gcc/java/parse.y

index da858f272b9269093ca5335ead14a89511a03b81..9f35084a236d9eca3450809f4576eb0a9c5a7417 100644 (file)
@@ -1,3 +1,26 @@
+2002-07-30  Andrew Haley  <aph@cambridge.redhat.com>
+
+       * Make-lang.in (java-tree-inline.o): New.
+       (JAVA_OBJS): Add java-tree-inline.o.
+       * parse.y (source_end_java_method): Call java_optimize_inline.
+       (java_expand_method_bodies): Save method's tree in
+       DECL_SAVED_TREE.
+       (add_stmt_to_compound): Keep track of the number of statments.
+       * lang.c (java_init): Enable flag_inline_trees.
+       (java_post_options): If flag_inline_functions is on, enable
+       flag_inline_trees instread.
+       (decl_constant_value): New.
+       (java_tree_inlining_walk_subtrees): New.
+       * java-tree.h (DECL_NUM_STMTS): New macro.
+       (java_optimize_inline): Declare.
+       * expr.c (java_expand_expr): Allow a BLOCK to return a value.
+       Handle a LABEL_EXPR.
+       * decl.c (build_result_decl): If we already have a DECL_RESULT
+       don't make another.
+       (dump_function): New.
+       (java_optimize_inline): New.
+       (dump_function): New.
+
 2002-08-13  Jesse Rosenstock  <jmr@fulcrummicro.com>
 
        For PR java/7483:
index 5b5f2a9e0a8df6d8b2ad2aecbd3122896c1ec331..50f811bb470cf0e25825fae148dd968c8aa029b1 100644 (file)
@@ -109,7 +109,7 @@ JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
   java/zextract.o java/jcf-io.o java/jcf-parse.o java/mangle.o \
   java/mangle_name.o java/builtins.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 mkdeps.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
@@ -289,6 +289,13 @@ java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
   $(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \
   java/java-except.h java/java-except.h java/parse.h toplev.h \
   $(SYSTEM_H) $(GGC_H) gt-java-expr.h
+java/java-tree-inline.o: tree-inline.c $(CONFIG_H) $(SYSTEM_H) \
+   $(TREE_H) $(RTL_H) expr.h flags.h params.h input.h insn-config.h \
+   $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
+   langhooks.h $(C_COMMON_H) $(srcdir)/tree-inline.h
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+       -DINLINER_FOR_JAVA=1 \
+       $(srcdir)/tree-inline.c -o $@
 java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
 java/jcf-parse.o: java/jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) flags.h \
   input.h java/java-except.h $(SYSTEM_H) toplev.h java/parse.h $(GGC_H) \
index bf5e5ff5192b51b21ae1696b8250441065827176..9f055d3cf57bfdd3a56657931e36f35aeb814d2b 100644 (file)
@@ -41,9 +41,11 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "except.h"
 #include "java-except.h"
 #include "ggc.h"
+#include "timevar.h"
+#include "tree-inline.h"
 
 #if defined (DEBUG_JAVA_BINDING_LEVELS)
-extern void indent PROTO((void));
+extern void indent PARAMS ((void));
 #endif
 
 static tree push_jvm_slot PARAMS ((int, tree));
@@ -53,6 +55,7 @@ static struct binding_level *make_binding_level PARAMS ((void));
 static tree create_primitive_vtable PARAMS ((const char *));
 static tree check_local_named_variable PARAMS ((tree, tree, int, int *));
 static tree check_local_unnamed_variable PARAMS ((tree, tree, tree));
+static void dump_function PARAMS ((enum tree_dump_index, tree));
 
 /* Set to non-zero value in order to emit class initilization code
    before static field references.  */
@@ -1662,11 +1665,18 @@ build_result_decl (fndecl)
   tree fndecl;
 {
   tree restype = TREE_TYPE (TREE_TYPE (fndecl));
-  /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */
-  if (INTEGRAL_TYPE_P (restype)
-      && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
-    restype = integer_type_node;
-  return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));
+  tree result = DECL_RESULT (fndecl);
+  if (! result)
+    {
+      /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */
+      if (INTEGRAL_TYPE_P (restype)
+         && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
+       restype = integer_type_node;
+      result = build_decl (RESULT_DECL, NULL_TREE, restype);
+      DECL_CONTEXT (result) = fndecl;
+      DECL_RESULT (fndecl) = result;
+    }
+  return result;
 }
 
 void
@@ -1825,4 +1835,34 @@ end_java_method ()
   current_function_decl = NULL_TREE;
 }
 
+/* Dump FUNCTION_DECL FN as tree dump PHASE. */
+
+static void
+dump_function (phase, fn)
+     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 (fndecl)
+     tree fndecl;
+{
+  if (flag_inline_trees)
+    {
+      timevar_push (TV_INTEGRATION);
+      optimize_inline_calls (fndecl);
+      timevar_pop (TV_INTEGRATION);
+      dump_function (TDI_inlined, fndecl);
+    }
+}
+
 #include "gt-java-decl.h"
index 133fa039b45617b2befb9b438d0b7e57b405b8f1..d6a443dca9a82f3f62f33af1208cdc82b1aa99b7 100644 (file)
@@ -2534,6 +2534,7 @@ java_expand_expr (exp, target, tmode, modifier)
       if (BLOCK_EXPR_BODY (exp))
        {
          tree local;
+         rtx last;
          tree body = BLOCK_EXPR_BODY (exp);
          /* Set to 1 or more when we found a static class
              initialization flag. */
@@ -2567,11 +2568,11 @@ java_expand_expr (exp, target, tmode, modifier)
              emit_queue ();
              body = TREE_OPERAND (body, 1);
            }
-         expand_expr (body, const0_rtx, VOIDmode, 0);
+         last = expand_expr (body, NULL_RTX, VOIDmode, 0);
          emit_queue ();
          expand_end_bindings (getdecls (), 1, 0);
          poplevel (1, 1, 0);
-         return const0_rtx;
+         return last;
        }
       return const0_rtx;
 
@@ -2628,6 +2629,11 @@ java_expand_expr (exp, target, tmode, modifier)
       return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
                          target, tmode, modifier);
 
+    case LABEL_EXPR:
+      /* Used only by expanded inline functions.  */
+      expand_label (TREE_OPERAND (exp, 0));
+      return const0_rtx;
+
     default:
       internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
     }
index 8a7fb9e9366438500dd21f59ead26228f77ba278..a08ec5830fca904b2335a11886c4df0fd0960dc0 100644 (file)
@@ -902,6 +902,12 @@ union lang_tree_node
 /* The original WFL of a final variable. */
 #define DECL_FIELD_FINAL_WFL(NODE) \
   (DECL_LANG_SPECIFIC(NODE)->u.v.wfl)
+/* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is
+     the approximate number of statements in this function.  There is
+     no need for this number to be exact; it is only used in various
+     heuristics regarding optimization.  */
+#define DECL_NUM_STMTS(NODE) \
+  (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
 /* True if NODE is a local variable final. */
 #define LOCAL_FINAL_P(NODE) (DECL_LANG_SPECIFIC (NODE) && DECL_FINAL (NODE))
 /* True if NODE is a final field. */
@@ -1274,6 +1280,9 @@ extern void append_gpp_mangled_name PARAMS ((const char *, int));
 extern void add_predefined_file PARAMS ((tree));
 extern int predefined_filename_p PARAMS ((tree));
 
+extern void java_optimize_inline PARAMS ((tree));
+extern tree decl_constant_value PARAMS ((tree));
+
 #if defined(RTX_CODE) && defined (HAVE_MACHINE_MODES)
 struct rtx_def * java_expand_expr PARAMS ((tree, rtx, enum machine_mode,
                                           int)); 
index 6d7affacbc9c57a05ccd7ad79afe0a07a38483e3..0a76402f555a8d7a523c91f62c1a85e10062a5a7 100644 (file)
@@ -40,6 +40,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "xref.h"
 #include "ggc.h"
 #include "diagnostic.h"
+#include "tree-inline.h"
 
 struct string_option
 {
@@ -61,6 +62,11 @@ static void java_print_error_function PARAMS ((diagnostic_context *,
 static int process_option_with_no PARAMS ((const char *,
                                           const struct string_option *,
                                           int));
+static tree java_tree_inlining_walk_subtrees  PARAMS ((tree *,
+                                                      int *,
+                                                      walk_tree_fn,
+                                                      void *,
+                                                      void *));
 static int java_unsafe_for_reeval PARAMS ((tree));
 
 #ifndef TARGET_OBJECT_SUFFIX
@@ -265,6 +271,9 @@ 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
+
 /* Each front end provides its own.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
@@ -496,6 +505,9 @@ java_init (filename)
   flag_minimal_debug = 0;
 #endif
 
+  if (flag_inline_functions)
+    flag_inline_trees = 1;
+
   /* Open input file.  */
 
   if (filename == 0 || !strcmp (filename, "-"))
@@ -786,17 +798,93 @@ java_init_options ()
 static bool
 java_post_options ()
 {
-  /* Turn off RTL inliner unless -finline-functions was really specified.  */
-  if (flag_really_inline == 0)
+ /* Use tree inlining if possible.  Function instrumentation is only
+     done in the RTL level, so we disable tree inlining.  */
+  if (! flag_instrument_function_entry_exit)
     {
-      flag_no_inline = 1;
-      flag_inline_functions = 0;
+      if (!flag_no_inline)
+       flag_no_inline = 1;
+      if (flag_inline_functions)
+       {
+         flag_inline_trees = 2;
+         flag_inline_functions = 0;
+       }
     }
 
   /* Initialize the compiler back end.  */
   return false;
 }
 
+/* Return either DECL or its known constant value (if it has one).  */
+
+tree
+decl_constant_value (decl)
+     tree decl;
+{
+  if (/* Don't change a variable array bound or initial value to a constant
+        in a place where a variable is invalid.  */
+      current_function_decl != 0
+      && ! TREE_THIS_VOLATILE (decl)
+      && TREE_READONLY (decl)
+      && DECL_INITIAL (decl) != 0
+      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
+      /* This is invalid if initial value is not constant.
+        If it has either a function call, a memory reference,
+        or a variable, then re-evaluating it could give different results.  */
+      && TREE_CONSTANT (DECL_INITIAL (decl))
+      /* Check for cases where this is sub-optimal, even though valid.  */
+      && 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 (tp,subtrees,func,data,htab)
+     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.  */
 static int
 java_unsafe_for_reeval (t)
index 2a581a156c7aa473e460b74bfcc157036e5ab089..3dabe3593d0ff0cdf26aab515e0c7c1d62644308 100644 (file)
@@ -67,6 +67,7 @@ definitions and other extensions.  */
 #include "except.h"
 #include "ggc.h"
 #include "debug.h"
+#include "tree-inline.h"
 
 #ifndef DIR_SEPARATOR
 #define DIR_SEPARATOR '/'
@@ -7478,6 +7479,8 @@ source_end_java_method ()
      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
@@ -7539,6 +7542,10 @@ static tree
 add_stmt_to_compound (existing, type, stmt)
      tree existing, type, stmt;
 {
+  /* Keep track of this for inlining.  */
+  if (current_function_decl)
+    ++DECL_NUM_STMTS (current_function_decl);
+
   if (existing)
     return build (COMPOUND_EXPR, type, existing, stmt);
   else
@@ -8128,6 +8135,11 @@ java_expand_method_bodies (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));
+      
       /* 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. */