tree-inline.c (remap_block): All local class initialization flags go in the outermost scope.

2002-10-14  Andrew Haley  <aph@redhat.com>

        * tree-inline.c (remap_block): All local class initialization
        flags go in the outermost scope.
        (expand_call_inline): Call java_inlining_map_static_initializers.
        (expand_call_inline): Call java_inlining_merge_static_initializers.
        * java/lang.c (merge_init_test_initialization): New.
        (java_inlining_merge_static_initializers): New.
        (inline_init_test_initialization): New.
        (java_inlining_map_static_initializers): New.

        * tree-inline.c (expand_call_inline): Convert retvar to expected
        type.

From-SVN: r58129
This commit is contained in:
Andrew Haley 2002-10-14 18:12:12 +00:00 committed by Andrew Haley
parent 34146b9406
commit 3eb429b2ce
4 changed files with 175 additions and 10 deletions

View File

@ -1,3 +1,17 @@
2002-10-14 Andrew Haley <aph@redhat.com>
* tree-inline.c (remap_block): All local class initialization
flags go in the outermost scope.
(expand_call_inline): Call java_inlining_map_static_initializers.
(expand_call_inline): Call java_inlining_merge_static_initializers.
* java/lang.c (merge_init_test_initialization): New.
(java_inlining_merge_static_initializers): New.
(inline_init_test_initialization): New.
(java_inlining_map_static_initializers): New.
* tree-inline.c (expand_call_inline): Convert retvar to expected
type.
2002-10-14 Graham Stott <graham.stott@btinternet.com>
* stmt.c (decl_conflicts_with_clobbers_p): Add REG_P check.

View File

@ -1,3 +1,14 @@
2002-10-14 Andrew Haley <aph@redhat.com>
* tree-inline.c (remap_block): All local class initialization
flags go in the outermost scope.
(expand_call_inline): Call java_inlining_map_static_initializers.
(expand_call_inline): Call java_inlining_merge_static_initializers.
* java/lang.c (merge_init_test_initialization): New.
(java_inlining_merge_static_initializers): New.
(inline_init_test_initialization): New.
(java_inlining_map_static_initializers): New.
2002-10-11 Mark Wielaard <mark@klomp.org>
* gcj.texi (Compatibility): Add Limitations and Extensions section.

View File

@ -41,6 +41,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "ggc.h"
#include "diagnostic.h"
#include "tree-inline.h"
#include "splay-tree.h"
struct string_option
{
@ -62,15 +63,18 @@ 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 tree java_tree_inlining_walk_subtrees PARAMS ((tree *,
int *,
walk_tree_fn,
void *,
void *));
static int java_unsafe_for_reeval PARAMS ((tree));
static int merge_init_test_initialization PARAMS ((void * *,
void *));
static int inline_init_test_initialization PARAMS ((void * *,
void *));
static bool java_can_use_bit_fields_p PARAMS ((void));
#ifndef TARGET_OBJECT_SUFFIX
# define TARGET_OBJECT_SUFFIX ".o"
#endif
@ -928,4 +932,113 @@ java_unsafe_for_reeval (t)
return -1;
}
/* Every call to a static constructor has an associated boolean
variable which is in the outermost scope of the calling method.
This variable is used to avoid multiple calls to the static
constructor for each class.
It looks somthing like this:
foo ()
{
boolean dummy = OtherClass.is_initialized;
...
if (! dummy)
OtherClass.initialize();
... use OtherClass.data ...
}
Each of these boolean variables has an entry in the
DECL_FUNCTION_INIT_TEST_TABLE of a method. When inlining a method
we must merge the DECL_FUNCTION_INIT_TEST_TABLE from the function
being linlined and create the boolean variables in the outermost
scope of the method being inlined into. */
/* Create a mapping from a boolean variable in a method being inlined
to one in the scope of the method being inlined into. */
static int
merge_init_test_initialization (entry, x)
void * * entry;
void * x;
{
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
splay_tree decl_map = (splay_tree)x;
splay_tree_node n;
tree *init_test_decl;
/* See if we have remapped this declaration. If we haven't there's
a bug in the inliner. */
n = splay_tree_lookup (decl_map, (splay_tree_key) ite->value);
if (! n)
abort ();
/* Create a new entry for the class and its remapped boolean
variable. If we already have a mapping for this class we've
already initialized it, so don't overwrite the value. */
init_test_decl = java_treetreehash_new
(DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
if (!*init_test_decl)
*init_test_decl = (tree)n->value;
return true;
}
/* Merge the DECL_FUNCTION_INIT_TEST_TABLE from the function we're
inlining. */
void
java_inlining_merge_static_initializers (fn, decl_map)
tree fn;
void *decl_map;
{
htab_traverse
(DECL_FUNCTION_INIT_TEST_TABLE (fn),
merge_init_test_initialization, decl_map);
}
/* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
inlining into. If we already have a corresponding entry in that
class we don't need to create another one, so we create a mapping
from the variable in the inlined class to the corresponding
pre-existing one. */
static int
inline_init_test_initialization (entry, x)
void * * entry;
void * x;
{
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
splay_tree decl_map = (splay_tree)x;
tree h = java_treetreehash_find
(DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
if (! h)
return true;
splay_tree_insert (decl_map,
(splay_tree_key) ite->value,
(splay_tree_value) h);
return true;
}
/* Look up the boolean variables in the DECL_FUNCTION_INIT_TEST_TABLE
of a method being inlined. For each hone, if we already have a
variable associated with the same class in the method being inlined
into, create a new mapping for it. */
void
java_inlining_map_static_initializers (fn, decl_map)
tree fn;
void *decl_map;
{
htab_traverse
(DECL_FUNCTION_INIT_TEST_TABLE (fn),
inline_init_test_initialization, decl_map);
}
#include "gt-java-lang.h"

View File

@ -336,6 +336,23 @@ remap_block (block, decls, id)
{
tree new_var;
/* All local class initialization flags go in the outermost
scope. */
if (LOCAL_CLASS_INITIALIZATION_FLAG_P (old_var))
{
/* We may already have one. */
if (! splay_tree_lookup (id->decl_map, (splay_tree_key) old_var))
{
tree outermost_block;
new_var = remap_decl (old_var, id);
DECL_ABSTRACT_ORIGIN (new_var) = NULL;
outermost_block = DECL_SAVED_TREE (current_function_decl);
TREE_CHAIN (new_var) = BLOCK_VARS (outermost_block);
BLOCK_VARS (outermost_block) = new_var;
}
continue;
}
/* Remap the variable. */
new_var = remap_decl (old_var, id);
/* If we didn't remap this variable, so we can't mess with
@ -1180,7 +1197,9 @@ expand_call_inline (tp, walk_subtrees, data)
*inlined_body = copy_body (id);
#else /* INLINER_FOR_JAVA */
{
tree new_body = copy_body (id);
tree new_body;
java_inlining_map_static_initializers (fn, id->decl_map);
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),
@ -1218,9 +1237,17 @@ expand_call_inline (tp, walk_subtrees, data)
= 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);
{
/* Mention the retvar. If the return type of the function was
promoted, convert it back to the expected type. */
if (TREE_TYPE (TREE_TYPE (fn)) != TREE_TYPE (retvar))
retvar = build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)), retvar);
BLOCK_EXPR_BODY (expr)
= add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
TREE_TYPE (retvar), retvar);
}
java_inlining_merge_static_initializers (fn, id->decl_map);
#endif /* INLINER_FOR_JAVA */
/* Clean up. */