Commit 916b57ce by Jeff Sturm Committed by Jeff Sturm

decl.c (java_expand_body): New function.

* decl.c (java_expand_body): New function.
* expr.c (build_class_init): Set DECL_IGNORED_P.
* java-tree.h (start_complete_expand_method,
java_expand_body): Declare.
* jcf-parse.c (cgraph.h): Include.
(java_parse_file): Handle flag_unit_at_a_time.
* lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING,
LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Define.
(java_estimate_num_insns): Use walk_tree_without_duplicates.
(java_start_inlining): New function.
* parse.h (java_finish_classes): Declare.
* parse.y: Include cgraph.h.
(block): Don't special-case empty block production.
(craft_constructor): Set DECL_INLINE.
(source_end_java_method): Handle flag_unit_at_a_time.
Replace inline code with call to java_expand_body.
(start_complete_expand_method): Remove static modifier.
(java_expand_method_bodies): Patch function tree for
class initialization and/or synchronization as needed.
Don't begin RTL expansion yet.
(java_expand_classes): Check flag_unit_at_a_time before
calling finish_class.
(java_finish_classes): New function.
(java_complete_lhs): Ensure COMPOUND_EXPR has non-NULL type.
(patch_assignment): Set DECL_CONTEXT on temporary variable.
(emit_test_initialization): Set DECL_IGNORED_P.

From-SVN: r71024
parent e71d3aae
2003-09-03 Jeff Sturm <jsturm@one-point.com>
* decl.c (java_expand_body): New function.
* expr.c (build_class_init): Set DECL_IGNORED_P.
* java-tree.h (start_complete_expand_method,
java_expand_body): Declare.
* jcf-parse.c (cgraph.h): Include.
(java_parse_file): Handle flag_unit_at_a_time.
* lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING,
LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Define.
(java_estimate_num_insns): Use walk_tree_without_duplicates.
(java_start_inlining): New function.
* parse.h (java_finish_classes): Declare.
* parse.y: Include cgraph.h.
(block): Don't special-case empty block production.
(craft_constructor): Set DECL_INLINE.
(source_end_java_method): Handle flag_unit_at_a_time.
Replace inline code with call to java_expand_body.
(start_complete_expand_method): Remove static modifier.
(java_expand_method_bodies): Patch function tree for
class initialization and/or synchronization as needed.
Don't begin RTL expansion yet.
(java_expand_classes): Check flag_unit_at_a_time before
calling finish_class.
(java_finish_classes): New function.
(java_complete_lhs): Ensure COMPOUND_EXPR has non-NULL type.
(patch_assignment): Set DECL_CONTEXT on temporary variable.
(emit_test_initialization): Set DECL_IGNORED_P.
2003-09-03 Roger Sayle <roger@eyesopen.com> 2003-09-03 Roger Sayle <roger@eyesopen.com>
* builtins.c (enum builtin_type): Delete unused enumeration. * builtins.c (enum builtin_type): Delete unused enumeration.
......
...@@ -1811,6 +1811,59 @@ end_java_method (void) ...@@ -1811,6 +1811,59 @@ end_java_method (void)
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
} }
/* Expand a function's body. */
void
java_expand_body (tree fndecl)
{
const char *saved_input_filename = input_filename;
int saved_lineno = input_line;
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);
if (! flag_emit_class_files && ! flag_emit_xref)
{
/* 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);
/* Generate the RTL for this function. */
expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 1);
}
/* Pop out of its parameters. */
pushdecl_force_head (DECL_ARGUMENTS (fndecl));
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
if (! flag_emit_class_files && ! flag_emit_xref)
{
/* Generate RTL for function exit. */
input_line = DECL_FUNCTION_LAST_LINE (fndecl);
expand_function_end ();
/* Run the optimizers and output the assembler code
for this function. */
rest_of_compilation (fndecl);
}
timevar_pop (TV_EXPAND);
input_filename = saved_input_filename;
input_line = saved_lineno;
current_function_decl = NULL_TREE;
}
/* Dump FUNCTION_DECL FN as tree dump PHASE. */ /* Dump FUNCTION_DECL FN as tree dump PHASE. */
static void static void
......
...@@ -1710,6 +1710,8 @@ build_class_init (tree clas, tree expr) ...@@ -1710,6 +1710,8 @@ build_class_init (tree clas, tree expr)
optimizing class initialization. */ optimizing class initialization. */
if (!STATIC_CLASS_INIT_OPT_P ()) if (!STATIC_CLASS_INIT_OPT_P ())
DECL_BIT_INDEX(*init_test_decl) = -1; DECL_BIT_INDEX(*init_test_decl) = -1;
/* Don't emit any symbolic debugging info for this decl. */
DECL_IGNORED_P (*init_test_decl) = 1;
} }
init = build (CALL_EXPR, void_type_node, init = build (CALL_EXPR, void_type_node,
......
...@@ -1297,6 +1297,9 @@ extern void compile_resource_file (const char *, const char *); ...@@ -1297,6 +1297,9 @@ extern void compile_resource_file (const char *, const char *);
extern void write_resource_constructor (void); extern void write_resource_constructor (void);
extern void init_resource_processing (void); extern void init_resource_processing (void);
extern void start_complete_expand_method (tree);
extern void java_expand_body (tree);
#define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL) #define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL)
......
...@@ -42,6 +42,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -42,6 +42,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "debug.h" #include "debug.h"
#include "assert.h" #include "assert.h"
#include "tm_p.h" #include "tm_p.h"
#include "cgraph.h"
#ifdef HAVE_LOCALE_H #ifdef HAVE_LOCALE_H
#include <locale.h> #include <locale.h>
...@@ -1119,6 +1120,13 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) ...@@ -1119,6 +1120,13 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
java_expand_classes (); java_expand_classes ();
if (!java_report_errors () && !flag_syntax_only) if (!java_report_errors () && !flag_syntax_only)
{ {
if (flag_unit_at_a_time)
{
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
java_finish_classes ();
}
emit_register_classes (); emit_register_classes ();
if (flag_indirect_dispatch) if (flag_indirect_dispatch)
emit_offset_symbol_table (); emit_offset_symbol_table ();
......
...@@ -67,6 +67,7 @@ static bool java_dump_tree (void *, tree); ...@@ -67,6 +67,7 @@ static bool java_dump_tree (void *, tree);
static void dump_compound_expr (dump_info_p, tree); static void dump_compound_expr (dump_info_p, tree);
static bool java_decl_ok_for_sibcall (tree); static bool java_decl_ok_for_sibcall (tree);
static int java_estimate_num_insns (tree); static int java_estimate_num_insns (tree);
static int java_start_inlining (tree);
#ifndef TARGET_OBJECT_SUFFIX #ifndef TARGET_OBJECT_SUFFIX
# define TARGET_OBJECT_SUFFIX ".o" # define TARGET_OBJECT_SUFFIX ".o"
...@@ -253,12 +254,18 @@ struct language_function GTY(()) ...@@ -253,12 +254,18 @@ struct language_function GTY(())
#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS #undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS java_estimate_num_insns #define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS java_estimate_num_insns
#undef LANG_HOOKS_TREE_INLINING_START_INLINING
#define LANG_HOOKS_TREE_INLINING_START_INLINING java_start_inlining
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
#undef LANG_HOOKS_DECL_OK_FOR_SIBCALL #undef LANG_HOOKS_DECL_OK_FOR_SIBCALL
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall #define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION java_expand_body
/* Each front end provides its own. */ /* Each front end provides its own. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
...@@ -1178,8 +1185,21 @@ static int ...@@ -1178,8 +1185,21 @@ static int
java_estimate_num_insns (tree decl) java_estimate_num_insns (tree decl)
{ {
int num = 0; int num = 0;
walk_tree (&DECL_SAVED_TREE (decl), java_estimate_num_insns_1, &num, NULL); walk_tree_without_duplicates (&DECL_SAVED_TREE (decl),
java_estimate_num_insns_1, &num);
return num; return num;
} }
/* Start inlining fn. Called by the tree inliner via
lang_hooks.tree_inlining.cannot_inline_tree_fn. */
static int
java_start_inlining (tree fn)
{
/* A java function's body doesn't have a BLOCK structure suitable
for debug output until it is expanded. Prevent inlining functions
that are not yet expanded. */
return TREE_ASM_WRITTEN (fn) ? 1 : 0;
}
#include "gt-java-lang.h" #include "gt-java-lang.h"
...@@ -941,6 +941,7 @@ ATTRIBUTE_NORETURN ...@@ -941,6 +941,7 @@ ATTRIBUTE_NORETURN
#endif #endif
; ;
extern void java_expand_classes (void); extern void java_expand_classes (void);
extern void java_finish_classes (void);
extern GTY(()) struct parser_ctxt *ctxp; extern GTY(()) struct parser_ctxt *ctxp;
extern GTY(()) struct parser_ctxt *ctxp_for_generation; extern GTY(()) struct parser_ctxt *ctxp_for_generation;
......
...@@ -71,6 +71,7 @@ definitions and other extensions. */ ...@@ -71,6 +71,7 @@ definitions and other extensions. */
#include "ggc.h" #include "ggc.h"
#include "debug.h" #include "debug.h"
#include "tree-inline.h" #include "tree-inline.h"
#include "cgraph.h"
/* Local function prototypes */ /* Local function prototypes */
static char *java_accstring_lookup (int); static char *java_accstring_lookup (int);
...@@ -141,7 +142,6 @@ static tree java_complete_tree (tree); ...@@ -141,7 +142,6 @@ static tree java_complete_tree (tree);
static tree maybe_generate_pre_expand_clinit (tree); static tree maybe_generate_pre_expand_clinit (tree);
static int analyze_clinit_body (tree, tree); static int analyze_clinit_body (tree, tree);
static int maybe_yank_clinit (tree); static int maybe_yank_clinit (tree);
static void start_complete_expand_method (tree);
static void java_complete_expand_method (tree); static void java_complete_expand_method (tree);
static void java_expand_method_bodies (tree); static void java_expand_method_bodies (tree);
static int unresolved_type_p (tree, tree *); static int unresolved_type_p (tree, tree *);
...@@ -1352,14 +1352,8 @@ variable_initializers: ...@@ -1352,14 +1352,8 @@ variable_initializers:
/* 19.11 Production from 14: Blocks and Statements */ /* 19.11 Production from 14: Blocks and Statements */
block: block:
OCB_TK CCB_TK block_begin block_end
{ { $$ = $2; }
/* Store the location of the `}' when doing xrefs */
if (current_function_decl && flag_emit_xref)
DECL_END_SOURCE_LINE (current_function_decl) =
EXPR_WFL_ADD_COL ($2.location, 1);
$$ = empty_stmt_node;
}
| block_begin block_statements block_end | block_begin block_statements block_end
{ $$ = $3; } { $$ = $3; }
; ;
...@@ -5405,6 +5399,7 @@ craft_constructor (tree class_decl, tree args) ...@@ -5405,6 +5399,7 @@ craft_constructor (tree class_decl, tree args)
/* Now, mark the artificial parameters. */ /* Now, mark the artificial parameters. */
DECL_FUNCTION_NAP (decl) = artificial; DECL_FUNCTION_NAP (decl) = artificial;
DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1; DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
DECL_INLINE (decl) = 1;
return decl; return decl;
} }
...@@ -7476,30 +7471,20 @@ source_end_java_method (void) ...@@ -7476,30 +7471,20 @@ source_end_java_method (void)
patched. Dump it to a file if the user requested it. */ patched. Dump it to a file if the user requested it. */
dump_java_tree (TDI_original, fndecl); dump_java_tree (TDI_original, fndecl);
java_optimize_inline (fndecl); /* In unit-at-a-time mode, don't expand the method yet. */
if (DECL_SAVED_TREE (fndecl) && flag_unit_at_a_time)
/* 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));
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
/* Generate rtl for function exit. */
if (! flag_emit_class_files && ! flag_emit_xref)
{ {
input_line = DECL_FUNCTION_LAST_LINE (fndecl); cgraph_finalize_function (fndecl, DECL_SAVED_TREE (fndecl));
expand_function_end (); current_function_decl = NULL_TREE;
java_parser_context_restore_global ();
/* Run the optimizers and output assembler code for this function. */ return;
rest_of_compilation (fndecl);
} }
current_function_decl = NULL_TREE; java_optimize_inline (fndecl);
/* Expand the function's body. */
java_expand_body (fndecl);
java_parser_context_restore_global (); java_parser_context_restore_global ();
} }
...@@ -7969,7 +7954,7 @@ maybe_yank_clinit (tree mdecl) ...@@ -7969,7 +7954,7 @@ maybe_yank_clinit (tree mdecl)
/* Install the argument from MDECL. Suitable to completion and /* Install the argument from MDECL. Suitable to completion and
expansion of mdecl's body. */ expansion of mdecl's body. */
static void void
start_complete_expand_method (tree mdecl) start_complete_expand_method (tree mdecl)
{ {
tree tem; tree tem;
...@@ -8112,15 +8097,26 @@ java_expand_method_bodies (tree class) ...@@ -8112,15 +8097,26 @@ java_expand_method_bodies (tree class)
tree decl; tree decl;
for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl)) for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
{ {
if (!DECL_FUNCTION_BODY (decl)) tree block;
tree body;
if (! DECL_FUNCTION_BODY (decl))
continue; continue;
current_function_decl = decl; current_function_decl = decl;
/* Save the function for inlining. */ block = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
if (flag_inline_trees)
DECL_SAVED_TREE (decl) = if (TREE_CODE (block) != BLOCK)
BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)); abort ();
/* Save the function body for 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 /* It's time to assign the variable flagging static class
initialization based on which classes invoked static methods initialization based on which classes invoked static methods
...@@ -8153,15 +8149,41 @@ java_expand_method_bodies (tree class) ...@@ -8153,15 +8149,41 @@ java_expand_method_bodies (tree class)
} }
} }
/* Prepare the function for RTL expansion */ /* Prepend class initialization to static methods. */
start_complete_expand_method (decl); 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);
/* Expand function start, generate initialization flag body = build (COMPOUND_EXPR, void_type_node,
assignment, and handle synchronized methods. */ enter,
complete_start_java_method (decl); build (TRY_FINALLY_EXPR, void_type_node, body, exit));
BLOCK_EXPR_BODY (block) = body;
}
/* Expand the rest of the function body and terminate /* Expand the the function body. */
expansion. */
source_end_java_method (); source_end_java_method ();
} }
} }
...@@ -9124,12 +9146,30 @@ java_expand_classes (void) ...@@ -9124,12 +9146,30 @@ java_expand_classes (void)
else if (! flag_syntax_only) else if (! flag_syntax_only)
{ {
java_expand_method_bodies (current_class); java_expand_method_bodies (current_class);
finish_class (); if (!flag_unit_at_a_time)
finish_class ();
} }
} }
} }
} }
void
java_finish_classes (void)
{
static struct parser_ctxt *cur_ctxp = NULL;
for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
{
tree current;
ctxp = cur_ctxp;
for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
{
current_class = TREE_TYPE (current);
outgoing_cpool = TYPE_CPOOL (current_class);
finish_class ();
}
}
}
/* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
a tree list node containing RIGHT. Fore coming RIGHTs will be a tree list node containing RIGHT. Fore coming RIGHTs will be
chained to this hook. LOCATION contains the location of the chained to this hook. LOCATION contains the location of the
...@@ -11659,6 +11699,8 @@ java_complete_lhs (tree node) ...@@ -11659,6 +11699,8 @@ java_complete_lhs (tree node)
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR) && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
unreachable_stmt_error (*ptr); unreachable_stmt_error (*ptr);
} }
if (TREE_TYPE (*ptr) == NULL_TREE)
TREE_TYPE (*ptr) = void_type_node;
ptr = next; ptr = next;
} }
*ptr = java_complete_tree (*ptr); *ptr = java_complete_tree (*ptr);
...@@ -12889,6 +12931,7 @@ patch_assignment (tree node, tree wfl_op1) ...@@ -12889,6 +12931,7 @@ patch_assignment (tree node, tree wfl_op1)
tree block = build (BLOCK, TREE_TYPE (new_rhs), NULL); tree block = build (BLOCK, TREE_TYPE (new_rhs), NULL);
tree assignment tree assignment
= build (MODIFY_EXPR, TREE_TYPE (new_rhs), tmp, fold (new_rhs)); = build (MODIFY_EXPR, TREE_TYPE (new_rhs), tmp, fold (new_rhs));
DECL_CONTEXT (tmp) = current_function_decl;
BLOCK_VARS (block) = tmp; BLOCK_VARS (block) = tmp;
BLOCK_EXPR_BODY (block) BLOCK_EXPR_BODY (block)
= build (COMPOUND_EXPR, TREE_TYPE (new_rhs), assignment, tmp); = build (COMPOUND_EXPR, TREE_TYPE (new_rhs), assignment, tmp);
...@@ -16221,6 +16264,8 @@ emit_test_initialization (void **entry_p, void *info) ...@@ -16221,6 +16264,8 @@ emit_test_initialization (void **entry_p, void *info)
LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1; LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
DECL_CONTEXT (decl) = current_function_decl; DECL_CONTEXT (decl) = current_function_decl;
DECL_INITIAL (decl) = boolean_true_node; DECL_INITIAL (decl) = boolean_true_node;
/* Don't emit any symbolic debugging info for this decl. */
DECL_IGNORED_P (decl) = 1;
/* The trick is to find the right context for it. */ /* The trick is to find the right context for it. */
block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl)); block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment