Commit d436bff8 by Andrew Haley Committed by Andrew Haley

tree-inline.c: Add includes for Java inliner.

2002-07-30  Andrew Haley  <aph@redhat.com>

        * tree-inline.c: Add includes for Java inliner.
        (remap_decl): Don't handle anonymous types for Java.
        (remap_block): Add handling for Java trees.
        (copy_scope_stmt): Conditionalize for non-Java use only.
        (copy_body_r): Handle Java trees.  Add handling for
        LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR, Java blocks.
        (initialize_inlined_parameters):  Handle Java trees.
        (declare_return_variable): Likewise.
        (expand_call_inline): Handle Java trees.
        (walk_tree): Likewise.
        (copy_tree_r): Don't handle SCOPE_STMTs for Java.
        (add_stmt_to_compound): New function.

From-SVN: r56376
parent 408caa3a
2002-07-30 Andrew Haley <aph@redhat.com>
* tree-inline.c: Add includes for Java inliner.
(remap_decl): Don't handle anonymous types for Java.
(remap_block): Add handling for Java trees.
(copy_scope_stmt): Conditionalize for non-Java use only.
(copy_body_r): Handle Java trees. Add handling for
LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR, Java blocks.
(initialize_inlined_parameters): Handle Java trees.
(declare_return_variable): Likewise.
(expand_call_inline): Handle Java trees.
(walk_tree): Likewise.
(copy_tree_r): Don't handle SCOPE_STMTs for Java.
(add_stmt_to_compound): New function.
2002-08-15 Richard Henderson <rth@redhat.com> 2002-08-15 Richard Henderson <rth@redhat.com>
* Makefile.in (LOOSE_WARN): Remove -fno-common. * Makefile.in (LOOSE_WARN): Remove -fno-common.
......
...@@ -38,7 +38,12 @@ Boston, MA 02111-1307, USA. */ ...@@ -38,7 +38,12 @@ Boston, MA 02111-1307, USA. */
/* This should be eventually be generalized to other languages, but /* This should be eventually be generalized to other languages, but
this would require a shared function-as-trees infrastructure. */ this would require a shared function-as-trees infrastructure. */
#ifndef INLINER_FOR_JAVA
#include "c-common.h" #include "c-common.h"
#else /* INLINER_FOR_JAVA */
#include "parse.h"
#include "java-tree.h"
#endif /* INLINER_FOR_JAVA */
/* 0 if we should not perform inlining. /* 0 if we should not perform inlining.
1 if we should expand functions calls inline at the tree level. 1 if we should expand functions calls inline at the tree level.
...@@ -102,7 +107,6 @@ typedef struct inline_data ...@@ -102,7 +107,6 @@ typedef struct inline_data
/* Prototypes. */ /* Prototypes. */
static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
static tree declare_return_variable PARAMS ((inline_data *, tree *)); static tree declare_return_variable PARAMS ((inline_data *, tree *));
static tree copy_body_r PARAMS ((tree *, int *, void *)); static tree copy_body_r PARAMS ((tree *, int *, void *));
static tree copy_body PARAMS ((inline_data *)); static tree copy_body PARAMS ((inline_data *));
...@@ -110,8 +114,15 @@ static tree expand_call_inline PARAMS ((tree *, int *, void *)); ...@@ -110,8 +114,15 @@ static tree expand_call_inline PARAMS ((tree *, int *, void *));
static void expand_calls_inline PARAMS ((tree *, inline_data *)); static void expand_calls_inline PARAMS ((tree *, inline_data *));
static int inlinable_function_p PARAMS ((tree, inline_data *)); static int inlinable_function_p PARAMS ((tree, inline_data *));
static tree remap_decl PARAMS ((tree, inline_data *)); static tree remap_decl PARAMS ((tree, inline_data *));
#ifndef INLINER_FOR_JAVA
static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
static void remap_block PARAMS ((tree, tree, inline_data *)); static void remap_block PARAMS ((tree, tree, inline_data *));
static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *)); static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *));
#else /* INLINER_FOR_JAVA */
static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree, tree));
static void remap_block PARAMS ((tree *, tree, inline_data *));
static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
#endif /* INLINER_FOR_JAVA */
/* The approximate number of instructions per statement. This number /* The approximate number of instructions per statement. This number
need not be particularly accurate; it is used only to make need not be particularly accurate; it is used only to make
...@@ -158,6 +169,7 @@ remap_decl (decl, id) ...@@ -158,6 +169,7 @@ remap_decl (decl, id)
copy_body_r, id, NULL); copy_body_r, id, NULL);
} }
#ifndef INLINER_FOR_JAVA
if (! DECL_NAME (t) && TREE_TYPE (t) if (! DECL_NAME (t) && TREE_TYPE (t)
&& (*lang_hooks.tree_inlining.anon_aggr_type_p) (TREE_TYPE (t))) && (*lang_hooks.tree_inlining.anon_aggr_type_p) (TREE_TYPE (t)))
{ {
...@@ -178,6 +190,7 @@ remap_decl (decl, id) ...@@ -178,6 +190,7 @@ remap_decl (decl, id)
} }
DECL_ANON_UNION_ELEMS (t) = nreverse (members); DECL_ANON_UNION_ELEMS (t) = nreverse (members);
} }
#endif /* not INLINER_FOR_JAVA */
/* Remember it, so that if we encounter this local entity /* Remember it, so that if we encounter this local entity
again we can reuse this copy. */ again we can reuse this copy. */
...@@ -189,17 +202,28 @@ remap_decl (decl, id) ...@@ -189,17 +202,28 @@ remap_decl (decl, id)
return (tree) n->value; return (tree) n->value;
} }
#ifndef INLINER_FOR_JAVA
/* Copy the SCOPE_STMT_BLOCK associated with SCOPE_STMT to contain /* Copy the SCOPE_STMT_BLOCK associated with SCOPE_STMT to contain
remapped versions of the variables therein. And hook the new block remapped versions of the variables therein. And hook the new block
into the block-tree. If non-NULL, the DECLS are declarations to into the block-tree. If non-NULL, the DECLS are declarations to
add to use instead of the BLOCK_VARS in the old block. */ add to use instead of the BLOCK_VARS in the old block. */
#else /* INLINER_FOR_JAVA */
/* Copy the BLOCK to contain remapped versions of the variables
therein. And hook the new block into the block-tree. */
#endif /* INLINER_FOR_JAVA */
static void static void
#ifndef INLINER_FOR_JAVA
remap_block (scope_stmt, decls, id) remap_block (scope_stmt, decls, id)
tree scope_stmt; tree scope_stmt;
#else /* INLINER_FOR_JAVA */
remap_block (block, decls, id)
tree *block;
#endif /* INLINER_FOR_JAVA */
tree decls; tree decls;
inline_data *id; inline_data *id;
{ {
#ifndef INLINER_FOR_JAVA
/* We cannot do this in the cleanup for a TARGET_EXPR since we do /* We cannot do this in the cleanup for a TARGET_EXPR since we do
not know whether or not expand_expr will actually write out the not know whether or not expand_expr will actually write out the
code we put there. If it does not, then we'll have more BLOCKs code we put there. If it does not, then we'll have more BLOCKs
...@@ -289,8 +313,55 @@ remap_block (scope_stmt, decls, id) ...@@ -289,8 +313,55 @@ remap_block (scope_stmt, decls, id)
abort (); abort ();
SCOPE_STMT_BLOCK (scope_stmt) = (tree) n->value; SCOPE_STMT_BLOCK (scope_stmt) = (tree) n->value;
} }
#else /* INLINER_FOR_JAVA */
tree old_block;
tree new_block;
tree old_var;
tree fn;
/* Make the new block. */
old_block = *block;
new_block = make_node (BLOCK);
TREE_USED (new_block) = TREE_USED (old_block);
BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
BLOCK_SUBBLOCKS (new_block) = BLOCK_SUBBLOCKS (old_block);
TREE_SIDE_EFFECTS (new_block) = TREE_SIDE_EFFECTS (old_block);
TREE_TYPE (new_block) = TREE_TYPE (old_block);
*block = new_block;
/* Remap its variables. */
for (old_var = decls ? decls : BLOCK_VARS (old_block);
old_var;
old_var = TREE_CHAIN (old_var))
{
tree new_var;
/* Remap the variable. */
new_var = remap_decl (old_var, id);
/* If we didn't remap this variable, so we can't mess with
its TREE_CHAIN. If we remapped this variable to
something other than a declaration (say, if we mapped it
to a constant), then we must similarly omit any mention
of it here. */
if (!new_var || !DECL_P (new_var))
;
else
{
TREE_CHAIN (new_var) = BLOCK_VARS (new_block);
BLOCK_VARS (new_block) = new_var;
}
}
/* We put the BLOCK_VARS in reverse order; fix that now. */
BLOCK_VARS (new_block) = nreverse (BLOCK_VARS (new_block));
fn = VARRAY_TREE (id->fns, 0);
/* Remember the remapped block. */
splay_tree_insert (id->decl_map,
(splay_tree_key) old_block,
(splay_tree_value) new_block);
#endif /* INLINER_FOR_JAVA */
} }
#ifndef INLINER_FOR_JAVA
/* Copy the SCOPE_STMT pointed to by TP. */ /* Copy the SCOPE_STMT pointed to by TP. */
static void static void
...@@ -314,10 +385,10 @@ copy_scope_stmt (tp, walk_subtrees, id) ...@@ -314,10 +385,10 @@ copy_scope_stmt (tp, walk_subtrees, id)
/* Remap the associated block. */ /* Remap the associated block. */
remap_block (*tp, NULL_TREE, id); remap_block (*tp, NULL_TREE, id);
} }
#endif /* not INLINER_FOR_JAVA */
/* Called from copy_body via walk_tree. DATA is really an /* Called from copy_body via walk_tree. DATA is really an
`inline_data *'. */ `inline_data *'. */
static tree static tree
copy_body_r (tp, walk_subtrees, data) copy_body_r (tp, walk_subtrees, data)
tree *tp; tree *tp;
...@@ -340,21 +411,37 @@ copy_body_r (tp, walk_subtrees, data) ...@@ -340,21 +411,37 @@ copy_body_r (tp, walk_subtrees, data)
abort (); abort ();
#endif #endif
#ifdef INLINER_FOR_JAVA
if (TREE_CODE (*tp) == BLOCK)
remap_block (tp, NULL_TREE, id);
#endif
/* If this is a RETURN_STMT, change it into an EXPR_STMT and a /* If this is a RETURN_STMT, change it into an EXPR_STMT and a
GOTO_STMT with the RET_LABEL as its target. */ GOTO_STMT with the RET_LABEL as its target. */
#ifndef INLINER_FOR_JAVA
if (TREE_CODE (*tp) == RETURN_STMT && id->ret_label) if (TREE_CODE (*tp) == RETURN_STMT && id->ret_label)
#else /* INLINER_FOR_JAVA */
if (TREE_CODE (*tp) == RETURN_EXPR && id->ret_label)
#endif /* INLINER_FOR_JAVA */
{ {
tree return_stmt = *tp; tree return_stmt = *tp;
tree goto_stmt; tree goto_stmt;
/* Build the GOTO_STMT. */ /* Build the GOTO_STMT. */
#ifndef INLINER_FOR_JAVA
goto_stmt = build_stmt (GOTO_STMT, id->ret_label); goto_stmt = build_stmt (GOTO_STMT, id->ret_label);
TREE_CHAIN (goto_stmt) = TREE_CHAIN (return_stmt); TREE_CHAIN (goto_stmt) = TREE_CHAIN (return_stmt);
GOTO_FAKE_P (goto_stmt) = 1; GOTO_FAKE_P (goto_stmt) = 1;
#else /* INLINER_FOR_JAVA */
tree assignment = TREE_OPERAND (return_stmt, 0);
goto_stmt = build1 (GOTO_EXPR, void_type_node, id->ret_label);
TREE_SIDE_EFFECTS (goto_stmt) = 1;
#endif /* INLINER_FOR_JAVA */
/* If we're returning something, just turn that into an /* If we're returning something, just turn that into an
assignment into the equivalent of the original assignment into the equivalent of the original
RESULT_DECL. */ RESULT_DECL. */
#ifndef INLINER_FOR_JAVA
if (RETURN_EXPR (return_stmt)) if (RETURN_EXPR (return_stmt))
{ {
*tp = build_stmt (EXPR_STMT, *tp = build_stmt (EXPR_STMT,
...@@ -363,6 +450,14 @@ copy_body_r (tp, walk_subtrees, data) ...@@ -363,6 +450,14 @@ copy_body_r (tp, walk_subtrees, data)
/* And then jump to the end of the function. */ /* And then jump to the end of the function. */
TREE_CHAIN (*tp) = goto_stmt; TREE_CHAIN (*tp) = goto_stmt;
} }
#else /* INLINER_FOR_JAVA */
if (assignment)
{
copy_body_r (&assignment, walk_subtrees, data);
*tp = build (COMPOUND_EXPR, void_type_node, assignment, goto_stmt);
TREE_SIDE_EFFECTS (*tp) = 1;
}
#endif /* INLINER_FOR_JAVA */
/* If we're not returning anything just do the jump. */ /* If we're not returning anything just do the jump. */
else else
*tp = goto_stmt; *tp = goto_stmt;
...@@ -394,10 +489,35 @@ copy_body_r (tp, walk_subtrees, data) ...@@ -394,10 +489,35 @@ copy_body_r (tp, walk_subtrees, data)
else if (TREE_CODE (*tp) == UNSAVE_EXPR) else if (TREE_CODE (*tp) == UNSAVE_EXPR)
/* UNSAVE_EXPRs should not be generated until expansion time. */ /* UNSAVE_EXPRs should not be generated until expansion time. */
abort (); abort ();
#ifndef INLINER_FOR_JAVA
/* For a SCOPE_STMT, we must copy the associated block so that we /* For a SCOPE_STMT, we must copy the associated block so that we
can write out debugging information for the inlined variables. */ can write out debugging information for the inlined variables. */
else if (TREE_CODE (*tp) == SCOPE_STMT && !id->in_target_cleanup_p) else if (TREE_CODE (*tp) == SCOPE_STMT && !id->in_target_cleanup_p)
copy_scope_stmt (tp, walk_subtrees, id); copy_scope_stmt (tp, walk_subtrees, id);
#else /* INLINER_FOR_JAVA */
else if (TREE_CODE (*tp) == LABELED_BLOCK_EXPR)
{
/* We need a new copy of this labeled block; the EXIT_BLOCK_EXPR
will refer to it, so save a copy ready for remapping. We
save it in the decl_map, although it isn't a decl. */
tree new_block = copy_node (*tp);
splay_tree_insert (id->decl_map,
(splay_tree_key) *tp,
(splay_tree_value) new_block);
*tp = new_block;
}
else if (TREE_CODE (*tp) == EXIT_BLOCK_EXPR)
{
splay_tree_node n
= splay_tree_lookup (id->decl_map,
(splay_tree_key) TREE_OPERAND (*tp, 0));
/* We _must_ have seen the enclosing LABELED_BLOCK_EXPR. */
if (! n)
abort ();
*tp = copy_node (*tp);
TREE_OPERAND (*tp, 0) = (tree) n->value;
}
#endif /* INLINER_FOR_JAVA */
/* Otherwise, just copy the node. Note that copy_tree_r already /* Otherwise, just copy the node. Note that copy_tree_r already
knows not to copy VAR_DECLs, etc., so this is safe. */ knows not to copy VAR_DECLs, etc., so this is safe. */
else else
...@@ -456,15 +576,25 @@ copy_body (id) ...@@ -456,15 +576,25 @@ copy_body (id)
top of the stack in ID from the ARGS (presented as a TREE_LIST). */ top of the stack in ID from the ARGS (presented as a TREE_LIST). */
static tree static tree
#ifndef INLINER_FOR_JAVA
initialize_inlined_parameters (id, args, fn) initialize_inlined_parameters (id, args, fn)
#else /* INLINER_FOR_JAVA */
initialize_inlined_parameters (id, args, fn, block)
#endif /* INLINER_FOR_JAVA */
inline_data *id; inline_data *id;
tree args; tree args;
tree fn; tree fn;
#ifdef INLINER_FOR_JAVA
tree block;
#endif /* INLINER_FOR_JAVA */
{ {
tree init_stmts; tree init_stmts;
tree parms; tree parms;
tree a; tree a;
tree p; tree p;
#ifdef INLINER_FOR_JAVA
tree vars = NULL_TREE;
#endif /* INLINER_FOR_JAVA */
/* Figure out what the parameters are. */ /* Figure out what the parameters are. */
parms = DECL_ARGUMENTS (fn); parms = DECL_ARGUMENTS (fn);
...@@ -477,7 +607,9 @@ initialize_inlined_parameters (id, args, fn) ...@@ -477,7 +607,9 @@ initialize_inlined_parameters (id, args, fn)
for (p = parms, a = args; p; for (p = parms, a = args; p;
a = a ? TREE_CHAIN (a) : a, p = TREE_CHAIN (p)) a = a ? TREE_CHAIN (a) : a, p = TREE_CHAIN (p))
{ {
#ifndef INLINER_FOR_JAVA
tree init_stmt; tree init_stmt;
#endif /* not INLINER_FOR_JAVA */
tree var; tree var;
tree value; tree value;
tree cleanup; tree cleanup;
...@@ -526,9 +658,14 @@ initialize_inlined_parameters (id, args, fn) ...@@ -526,9 +658,14 @@ initialize_inlined_parameters (id, args, fn)
(splay_tree_value) var); (splay_tree_value) var);
/* Declare this new variable. */ /* Declare this new variable. */
#ifndef INLINER_FOR_JAVA
init_stmt = build_stmt (DECL_STMT, var); init_stmt = build_stmt (DECL_STMT, var);
TREE_CHAIN (init_stmt) = init_stmts; TREE_CHAIN (init_stmt) = init_stmts;
init_stmts = init_stmt; init_stmts = init_stmt;
#else /* INLINER_FOR_JAVA */
TREE_CHAIN (var) = vars;
vars = var;
#endif /* INLINER_FOR_JAVA */
/* Initialize this VAR_DECL from the equivalent argument. If /* Initialize this VAR_DECL from the equivalent argument. If
the argument is an object, created via a constructor or copy, the argument is an object, created via a constructor or copy,
...@@ -536,6 +673,7 @@ initialize_inlined_parameters (id, args, fn) ...@@ -536,6 +673,7 @@ initialize_inlined_parameters (id, args, fn)
representing the argument will be bound to VAR, and the representing the argument will be bound to VAR, and the
object will be constructed in VAR. */ object will be constructed in VAR. */
if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p))) if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
#ifndef INLINER_FOR_JAVA
DECL_INITIAL (var) = value; DECL_INITIAL (var) = value;
else else
{ {
...@@ -573,8 +711,23 @@ initialize_inlined_parameters (id, args, fn) ...@@ -573,8 +711,23 @@ initialize_inlined_parameters (id, args, fn)
TREE_CHAIN (cleanup_stmt) = init_stmts; TREE_CHAIN (cleanup_stmt) = init_stmts;
init_stmts = cleanup_stmt; init_stmts = cleanup_stmt;
} }
#else /* INLINER_FOR_JAVA */
{
tree assignment = build (MODIFY_EXPR, TREE_TYPE (p), var, value);
init_stmts = add_stmt_to_compound (init_stmts, TREE_TYPE (p),
assignment);
}
else
{
/* Java objects don't ever need constructing when being
passed as arguments because only call by reference is
supported. */
abort ();
}
#endif /* INLINER_FOR_JAVA */
} }
#ifndef INLINER_FOR_JAVA
/* Evaluate trailing arguments. */ /* Evaluate trailing arguments. */
for (; a; a = TREE_CHAIN (a)) for (; a; a = TREE_CHAIN (a))
{ {
...@@ -592,6 +745,10 @@ initialize_inlined_parameters (id, args, fn) ...@@ -592,6 +745,10 @@ initialize_inlined_parameters (id, args, fn)
/* The initialization statements have been built up in reverse /* The initialization statements have been built up in reverse
order. Straighten them out now. */ order. Straighten them out now. */
return nreverse (init_stmts); return nreverse (init_stmts);
#else /* INLINER_FOR_JAVA */
BLOCK_VARS (block) = nreverse (vars);
return init_stmts;
#endif /* INLINER_FOR_JAVA */
} }
/* Declare a return variable to replace the RESULT_DECL for the /* Declare a return variable to replace the RESULT_DECL for the
...@@ -599,24 +756,38 @@ initialize_inlined_parameters (id, args, fn) ...@@ -599,24 +756,38 @@ initialize_inlined_parameters (id, args, fn)
The USE_STMT is filled in to contain a use of the declaration to The USE_STMT is filled in to contain a use of the declaration to
indicate the return value of the function. */ indicate the return value of the function. */
#ifndef INLINER_FOR_JAVA
static tree static tree
declare_return_variable (id, use_stmt) declare_return_variable (id, use_stmt)
struct inline_data *id; struct inline_data *id;
tree *use_stmt; tree *use_stmt;
#else /* INLINER_FOR_JAVA */
static tree
declare_return_variable (id, var)
struct inline_data *id;
tree *var;
#endif /* INLINER_FOR_JAVA */
{ {
tree fn = VARRAY_TOP_TREE (id->fns); tree fn = VARRAY_TOP_TREE (id->fns);
tree result = DECL_RESULT (fn); tree result = DECL_RESULT (fn);
#ifndef INLINER_FOR_JAVA
tree var; tree var;
#endif /* not INLINER_FOR_JAVA */
int need_return_decl = 1; int need_return_decl = 1;
/* We don't need to do anything for functions that don't return /* We don't need to do anything for functions that don't return
anything. */ anything. */
if (!result || VOID_TYPE_P (TREE_TYPE (result))) if (!result || VOID_TYPE_P (TREE_TYPE (result)))
{ {
#ifndef INLINER_FOR_JAVA
*use_stmt = NULL_TREE; *use_stmt = NULL_TREE;
#else /* INLINER_FOR_JAVA */
*var = NULL_TREE;
#endif /* INLINER_FOR_JAVA */
return NULL_TREE; return NULL_TREE;
} }
#ifndef INLINER_FOR_JAVA
var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining) var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining)
(result, fn, VARRAY_TREE (id->fns, 0), id->decl_map, (result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
&need_return_decl, &id->target_exprs)); &need_return_decl, &id->target_exprs));
...@@ -636,13 +807,24 @@ declare_return_variable (id, use_stmt) ...@@ -636,13 +807,24 @@ declare_return_variable (id, use_stmt)
*use_stmt = build_stmt (EXPR_STMT, *use_stmt = build_stmt (EXPR_STMT,
build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)), build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)),
var)); var));
TREE_ADDRESSABLE (*use_stmt) = 1; TREE_ADDRESSABLE (*use_stmt) = 1;
/* Build the declaration statement if FN does not return an /* Build the declaration statement if FN does not return an
aggregate. */ aggregate. */
if (need_return_decl) if (need_return_decl)
return build_stmt (DECL_STMT, var); return build_stmt (DECL_STMT, var);
#else /* INLINER_FOR_JAVA */
*var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining)
(result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
&need_return_decl, NULL_TREE));
splay_tree_insert (id->decl_map,
(splay_tree_key) result,
(splay_tree_value) *var);
DECL_IGNORED_P (*var) = 1;
if (need_return_decl)
return *var;
#endif /* INLINER_FOR_JAVA */
/* If FN does return an aggregate, there's no need to declare the /* If FN does return an aggregate, there's no need to declare the
return variable; we're using a variable in our caller's frame. */ return variable; we're using a variable in our caller's frame. */
else else
...@@ -783,10 +965,14 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -783,10 +965,14 @@ expand_call_inline (tp, walk_subtrees, data)
tree t; tree t;
tree expr; tree expr;
tree stmt; tree stmt;
#ifndef INLINER_FOR_JAVA
tree chain; tree chain;
tree fn;
tree scope_stmt; tree scope_stmt;
tree use_stmt; tree use_stmt;
#else /* INLINER_FOR_JAVA */
tree retvar;
#endif /* INLINER_FOR_JAVA */
tree fn;
tree arg_inits; tree arg_inits;
tree *inlined_body; tree *inlined_body;
splay_tree st; splay_tree st;
...@@ -799,6 +985,7 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -799,6 +985,7 @@ expand_call_inline (tp, walk_subtrees, data)
inside the body of a TARGET_EXPR. */ inside the body of a TARGET_EXPR. */
if (TREE_CODE (*tp) == TARGET_EXPR) if (TREE_CODE (*tp) == TARGET_EXPR)
{ {
#ifndef INLINER_FOR_JAVA
int i, len = first_rtl_op (TARGET_EXPR); int i, len = first_rtl_op (TARGET_EXPR);
/* We're walking our own subtrees. */ /* We're walking our own subtrees. */
...@@ -824,6 +1011,9 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -824,6 +1011,9 @@ expand_call_inline (tp, walk_subtrees, data)
VARRAY_POP (id->target_exprs); VARRAY_POP (id->target_exprs);
return NULL_TREE; return NULL_TREE;
#else /* INLINER_FOR_JAVA */
abort ();
#endif /* INLINER_FOR_JAVA */
} }
if (TYPE_P (t)) if (TYPE_P (t))
...@@ -869,6 +1059,7 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -869,6 +1059,7 @@ expand_call_inline (tp, walk_subtrees, data)
because individual statements don't record the filename. */ because individual statements don't record the filename. */
push_srcloc (DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn)); push_srcloc (DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn));
#ifndef INLINER_FOR_JAVA
/* Build a statement-expression containing code to initialize the /* Build a statement-expression containing code to initialize the
arguments, the actual inline expansion of the body, and a label arguments, the actual inline expansion of the body, and a label
for the return statements within the function to jump to. The for the return statements within the function to jump to. The
...@@ -878,6 +1069,15 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -878,6 +1069,15 @@ expand_call_inline (tp, walk_subtrees, data)
/* There is no scope associated with the statement-expression. */ /* There is no scope associated with the statement-expression. */
STMT_EXPR_NO_SCOPE (expr) = 1; STMT_EXPR_NO_SCOPE (expr) = 1;
stmt = STMT_EXPR_STMT (expr); stmt = STMT_EXPR_STMT (expr);
#else /* INLINER_FOR_JAVA */
/* Build a block containing code to initialize the arguments, the
actual inline expansion of the body, and a label for the return
statements within the function to jump to. The type of the
statement expression is the return type of the function call. */
stmt = NULL;
expr = build (BLOCK, TREE_TYPE (TREE_TYPE (fn)), stmt);
#endif /* INLINER_FOR_JAVA */
/* Local declarations will be replaced by their equivalents in this /* Local declarations will be replaced by their equivalents in this
map. */ map. */
st = id->decl_map; st = id->decl_map;
...@@ -885,6 +1085,7 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -885,6 +1085,7 @@ expand_call_inline (tp, walk_subtrees, data)
NULL, NULL); NULL, NULL);
/* Initialize the parameters. */ /* Initialize the parameters. */
#ifndef INLINER_FOR_JAVA
arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn); arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn);
/* Expand any inlined calls in the initializers. Do this before we /* Expand any inlined calls in the initializers. Do this before we
push FN on the stack of functions we are inlining; we want to push FN on the stack of functions we are inlining; we want to
...@@ -893,6 +1094,22 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -893,6 +1094,22 @@ expand_call_inline (tp, walk_subtrees, data)
expand_calls_inline (&arg_inits, id); expand_calls_inline (&arg_inits, id);
/* And add them to the tree. */ /* And add them to the tree. */
COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), arg_inits); COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), arg_inits);
#else /* INLINER_FOR_JAVA */
arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn, expr);
if (arg_inits)
{
/* Expand any inlined calls in the initializers. Do this before we
push FN on the stack of functions we are inlining; we want to
inline calls to FN that appear in the initializers for the
parameters. */
expand_calls_inline (&arg_inits, id);
/* And add them to the tree. */
BLOCK_EXPR_BODY (expr) = add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
TREE_TYPE (arg_inits),
arg_inits);
}
#endif /* INLINER_FOR_JAVA */
/* Record the function we are about to inline so that we can avoid /* Record the function we are about to inline so that we can avoid
recursing into it. */ recursing into it. */
...@@ -920,6 +1137,7 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -920,6 +1137,7 @@ expand_call_inline (tp, walk_subtrees, data)
|| TREE_CODE (DECL_INITIAL (fn)) != BLOCK) || TREE_CODE (DECL_INITIAL (fn)) != BLOCK)
abort (); abort ();
#ifndef INLINER_FOR_JAVA
/* Create a block to put the parameters in. We have to do this /* Create a block to put the parameters in. We have to do this
after the parameters have been remapped because remapping after the parameters have been remapped because remapping
parameters is different from remapping ordinary variables. */ parameters is different from remapping ordinary variables. */
...@@ -939,23 +1157,57 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -939,23 +1157,57 @@ expand_call_inline (tp, walk_subtrees, data)
COMPOUND_BODY (stmt) COMPOUND_BODY (stmt)
= chainon (COMPOUND_BODY (stmt), = chainon (COMPOUND_BODY (stmt),
declare_return_variable (id, &use_stmt)); declare_return_variable (id, &use_stmt));
#else /* INLINER_FOR_JAVA */
{
/* Declare the return variable for the function. */
tree decl = declare_return_variable (id, &retvar);
if (retvar)
{
tree *next = &BLOCK_VARS (expr);
while (*next)
next = &TREE_CHAIN (*next);
*next = decl;
}
}
#endif /* INLINER_FOR_JAVA */
/* After we've initialized the parameters, we insert the body of the /* After we've initialized the parameters, we insert the body of the
function itself. */ function itself. */
#ifndef INLINER_FOR_JAVA
inlined_body = &COMPOUND_BODY (stmt); inlined_body = &COMPOUND_BODY (stmt);
while (*inlined_body) while (*inlined_body)
inlined_body = &TREE_CHAIN (*inlined_body); inlined_body = &TREE_CHAIN (*inlined_body);
*inlined_body = copy_body (id); *inlined_body = copy_body (id);
#else /* INLINER_FOR_JAVA */
{
tree new_body = copy_body (id);
TREE_TYPE (new_body) = TREE_TYPE (TREE_TYPE (fn));
BLOCK_EXPR_BODY (expr)
= add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
TREE_TYPE (new_body), new_body);
inlined_body = &BLOCK_EXPR_BODY (expr);
}
#endif /* INLINER_FOR_JAVA */
/* After the body of the function comes the RET_LABEL. This must come /* After the body of the function comes the RET_LABEL. This must come
before we evaluate the returned value below, because that evalulation before we evaluate the returned value below, because that evalulation
may cause RTL to be generated. */ may cause RTL to be generated. */
#ifndef INLINER_FOR_JAVA
COMPOUND_BODY (stmt) COMPOUND_BODY (stmt)
= chainon (COMPOUND_BODY (stmt), = chainon (COMPOUND_BODY (stmt),
build_stmt (LABEL_STMT, id->ret_label)); build_stmt (LABEL_STMT, id->ret_label));
#else /* INLINER_FOR_JAVA */
{
tree label = build1 (LABEL_EXPR, void_type_node, id->ret_label);
BLOCK_EXPR_BODY (expr)
= add_stmt_to_compound (BLOCK_EXPR_BODY (expr), void_type_node, label);
TREE_SIDE_EFFECTS (label) = TREE_SIDE_EFFECTS (t);
}
#endif /* INLINER_FOR_JAVA */
/* Finally, mention the returned value so that the value of the /* Finally, mention the returned value so that the value of the
statement-expression is the returned value of the function. */ statement-expression is the returned value of the function. */
#ifndef INLINER_FOR_JAVA
COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), use_stmt); COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), use_stmt);
/* Close the block for the parameters. */ /* Close the block for the parameters. */
...@@ -964,6 +1216,12 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -964,6 +1216,12 @@ expand_call_inline (tp, walk_subtrees, data)
remap_block (scope_stmt, NULL_TREE, id); remap_block (scope_stmt, NULL_TREE, id);
COMPOUND_BODY (stmt) COMPOUND_BODY (stmt)
= chainon (COMPOUND_BODY (stmt), scope_stmt); = chainon (COMPOUND_BODY (stmt), scope_stmt);
#else /* INLINER_FOR_JAVA */
if (retvar)
BLOCK_EXPR_BODY (expr)
= add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
TREE_TYPE (retvar), retvar);
#endif /* INLINER_FOR_JAVA */
/* Clean up. */ /* Clean up. */
splay_tree_delete (id->decl_map); splay_tree_delete (id->decl_map);
...@@ -975,11 +1233,19 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -975,11 +1233,19 @@ expand_call_inline (tp, walk_subtrees, data)
/* Replace the call by the inlined body. Wrap it in an /* Replace the call by the inlined body. Wrap it in an
EXPR_WITH_FILE_LOCATION so that we'll get debugging line notes EXPR_WITH_FILE_LOCATION so that we'll get debugging line notes
pointing to the right place. */ pointing to the right place. */
#ifndef INLINER_FOR_JAVA
chain = TREE_CHAIN (*tp); chain = TREE_CHAIN (*tp);
*tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn), *tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn),
/*col=*/0); /*col=*/0);
#else /* INLINER_FOR_JAVA */
*tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn),
DECL_SOURCE_LINE_FIRST(fn),
/*col=*/0);
#endif /* INLINER_FOR_JAVA */
EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1; EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1;
#ifndef INLINER_FOR_JAVA
TREE_CHAIN (*tp) = chain; TREE_CHAIN (*tp) = chain;
#endif /* not INLINER_FOR_JAVA */
pop_srcloc (); pop_srcloc ();
/* If the value of the new expression is ignored, that's OK. We /* If the value of the new expression is ignored, that's OK. We
...@@ -1009,7 +1275,6 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -1009,7 +1275,6 @@ expand_call_inline (tp, walk_subtrees, data)
/* Keep iterating. */ /* Keep iterating. */
return NULL_TREE; return NULL_TREE;
} }
/* Walk over the entire tree *TP, replacing CALL_EXPRs with inline /* Walk over the entire tree *TP, replacing CALL_EXPRs with inline
expansions as appropriate. */ expansions as appropriate. */
...@@ -1174,6 +1439,7 @@ walk_tree (tp, func, data, htab_) ...@@ -1174,6 +1439,7 @@ walk_tree (tp, func, data, htab_)
code = TREE_CODE (*tp); code = TREE_CODE (*tp);
#ifndef INLINER_FOR_JAVA
/* Even if we didn't, FUNC may have decided that there was nothing /* Even if we didn't, FUNC may have decided that there was nothing
interesting below this point in the tree. */ interesting below this point in the tree. */
if (!walk_subtrees) if (!walk_subtrees)
...@@ -1190,13 +1456,22 @@ walk_tree (tp, func, data, htab_) ...@@ -1190,13 +1456,22 @@ walk_tree (tp, func, data, htab_)
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)) if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
|| TREE_CODE_CLASS (code) == 'r' || TREE_CODE_CLASS (code) == 'r'
|| TREE_CODE_CLASS (code) == 's') || TREE_CODE_CLASS (code) == 's')
#else /* INLINER_FOR_JAVA */
if (code != EXIT_BLOCK_EXPR
&& code != SAVE_EXPR
&& (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
|| TREE_CODE_CLASS (code) == 'r'
|| TREE_CODE_CLASS (code) == 's'))
#endif /* INLINER_FOR_JAVA */
{ {
int i, len; int i, len;
#ifndef INLINER_FOR_JAVA
/* Set lineno here so we get the right instantiation context /* Set lineno here so we get the right instantiation context
if we call instantiate_decl from inlinable_function_p. */ if we call instantiate_decl from inlinable_function_p. */
if (statement_code_p (code) && !STMT_LINENO_FOR_FN_P (*tp)) if (statement_code_p (code) && !STMT_LINENO_FOR_FN_P (*tp))
lineno = STMT_LINENO (*tp); lineno = STMT_LINENO (*tp);
#endif /* not INLINER_FOR_JAVA */
/* Walk over all the sub-trees of this operand. */ /* Walk over all the sub-trees of this operand. */
len = first_rtl_op (code); len = first_rtl_op (code);
...@@ -1210,6 +1485,7 @@ walk_tree (tp, func, data, htab_) ...@@ -1210,6 +1485,7 @@ walk_tree (tp, func, data, htab_)
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
WALK_SUBTREE (TREE_OPERAND (*tp, i)); WALK_SUBTREE (TREE_OPERAND (*tp, i));
#ifndef INLINER_FOR_JAVA
/* For statements, we also walk the chain so that we cover the /* For statements, we also walk the chain so that we cover the
entire statement tree. */ entire statement tree. */
if (statement_code_p (code)) if (statement_code_p (code))
...@@ -1232,6 +1508,7 @@ walk_tree (tp, func, data, htab_) ...@@ -1232,6 +1508,7 @@ walk_tree (tp, func, data, htab_)
WALK_SUBTREE_TAIL (TREE_CHAIN (*tp)); WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
} }
#endif /* not INLINER_FOR_JAVA */
/* We didn't find what we were looking for. */ /* We didn't find what we were looking for. */
return NULL_TREE; return NULL_TREE;
} }
...@@ -1327,6 +1604,14 @@ walk_tree (tp, func, data, htab_) ...@@ -1327,6 +1604,14 @@ walk_tree (tp, func, data, htab_)
WALK_SUBTREE (TREE_TYPE (*tp)); WALK_SUBTREE (TREE_TYPE (*tp));
WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp)); WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
#ifdef INLINER_FOR_JAVA
case EXIT_BLOCK_EXPR:
WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
case SAVE_EXPR:
WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
#endif /* INLINER_FOR_JAVA */
default: default:
abort (); abort ();
} }
...@@ -1384,6 +1669,7 @@ copy_tree_r (tp, walk_subtrees, data) ...@@ -1384,6 +1669,7 @@ copy_tree_r (tp, walk_subtrees, data)
/* Now, restore the chain, if appropriate. That will cause /* Now, restore the chain, if appropriate. That will cause
walk_tree to walk into the chain as well. */ walk_tree to walk into the chain as well. */
if (code == PARM_DECL || code == TREE_LIST if (code == PARM_DECL || code == TREE_LIST
#ifndef INLINER_FOR_JAVA
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp) || (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp)
|| statement_code_p (code)) || statement_code_p (code))
TREE_CHAIN (*tp) = chain; TREE_CHAIN (*tp) = chain;
...@@ -1392,6 +1678,10 @@ copy_tree_r (tp, walk_subtrees, data) ...@@ -1392,6 +1678,10 @@ copy_tree_r (tp, walk_subtrees, data)
have to nullify all scope-statements. */ have to nullify all scope-statements. */
if (TREE_CODE (*tp) == SCOPE_STMT) if (TREE_CODE (*tp) == SCOPE_STMT)
SCOPE_STMT_BLOCK (*tp) = NULL_TREE; SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
#else /* INLINER_FOR_JAVA */
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
TREE_CHAIN (*tp) = chain;
#endif /* INLINER_FOR_JAVA */
} }
else if (TREE_CODE_CLASS (code) == 't') else if (TREE_CODE_CLASS (code) == 't')
/* There's no need to copy types, or anything beneath them. */ /* There's no need to copy types, or anything beneath them. */
...@@ -1444,3 +1734,21 @@ remap_save_expr (tp, st_, fn, walk_subtrees) ...@@ -1444,3 +1734,21 @@ remap_save_expr (tp, st_, fn, walk_subtrees)
/* Replace this SAVE_EXPR with the copy. */ /* Replace this SAVE_EXPR with the copy. */
*tp = (tree) n->value; *tp = (tree) n->value;
} }
#ifdef INLINER_FOR_JAVA
/* Add STMT to EXISTING if possible, otherwise create a new
COMPOUND_EXPR and add STMT to it. */
static tree
add_stmt_to_compound (existing, type, stmt)
tree existing, type, stmt;
{
if (!stmt)
return existing;
else if (existing)
return build (COMPOUND_EXPR, type, existing, stmt);
else
return stmt;
}
#endif /* INLINER_FOR_JAVA */
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