Commit c9b9aa64 by Richard Henderson Committed by Richard Henderson

cgraph.h (cgraph_build_static_cdtor): Declare.

        * cgraph.h (cgraph_build_static_cdtor): Declare.
        * cgraphunit.c (cgraph_build_static_cdtor): New.
        * c-objc-common.c (build_cdtor): Use it.
        * coverage.c (create_coverage): Likewise.
        * libfuncs.h (LTI_gcov_init, gcov_init_libfunc): Remove.
        * optabs.c (init_optabs): Don't set gcov_init_libfunc.
java/
        * class.c (registerClass_libfunc): Remove.
        (init_class_processing): Don't set it.
        (emit_register_classes): Take list_p parameter.  Fill it in
        with _Jv_RegisterClass calls.
        * decl.c (java_init_decl_processing): Don't call
        init_resource_processing.
        * jcf-parse.c (java_emit_static_constructor): New.
        (java_parse_file): Call it.
        * resource.c (registerResource_libfunc): Remove.
        (init_resource_processing): Remove.
        (write_resource_constructor): Take list_p parameter.  Fill it in
        with _Jv_RegisterResource calls.
        * java-tree.h: Update prototypes.

From-SVN: r83958
parent 276b3fab
2004-07-01 Richard Henderson <rth@redhat.com>
* cgraph.h (cgraph_build_static_cdtor): Declare.
* cgraphunit.c (cgraph_build_static_cdtor): New.
* c-objc-common.c (build_cdtor): Use it.
* coverage.c (create_coverage): Likewise.
* libfuncs.h (LTI_gcov_init, gcov_init_libfunc): Remove.
* optabs.c (init_optabs): Don't set gcov_init_libfunc.
2004-06-30 Roger Sayle <roger@eyesopen.com>
* expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a
......
......@@ -184,27 +184,20 @@ c_objc_common_init (void)
/* Synthesize a function which calls all the global ctors or global dtors
in this file. */
static void
build_cdtor (int method_type, tree cdtors)
{
tree fnname = get_file_function_name (method_type);
tree cs;
start_function (void_list_node,
build_nt (CALL_EXPR, fnname,
tree_cons (NULL_TREE, NULL_TREE, void_list_node),
NULL_TREE),
NULL_TREE);
store_parm_decls ();
tree body;
cs = c_begin_compound_stmt (true);
body = push_stmt_list ();
for (; cdtors; cdtors = TREE_CHAIN (cdtors))
add_stmt (build_function_call (TREE_VALUE (cdtors), 0));
add_stmt (build_function_call (TREE_VALUE (cdtors), NULL_TREE));
add_stmt (c_end_compound_stmt (cs, true));
body = pop_stmt_list (body);
finish_function ();
cgraph_build_static_cdtor (method_type, body);
}
/* Called at end of parsing, but before end-of-file processing. */
......
......@@ -192,5 +192,6 @@ void verify_cgraph (void);
void verify_cgraph_node (struct cgraph_node *);
void cgraph_mark_inline_edge (struct cgraph_edge *e);
void cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate);
void cgraph_build_static_cdtor (char which, tree body);
#endif /* GCC_CGRAPH_H */
......@@ -168,6 +168,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "hashtab.h"
......@@ -1785,3 +1786,66 @@ cgraph_optimize (void)
}
#endif
}
/* Generate and emit a static constructor or destructor. WHICH must be
one of 'I' or 'D'. BODY should be a STATEMENT_LIST containing
GENERIC statements. */
void
cgraph_build_static_cdtor (char which, tree body)
{
static int counter = 0;
char which_buf[16];
tree decl, name;
sprintf (which_buf, "%c_%d", which, counter++);
name = get_file_function_name_long (which_buf);
decl = build_decl (FUNCTION_DECL, name,
build_function_type (void_type_node, void_list_node));
current_function_decl = decl;
DECL_RESULT (decl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
allocate_struct_function (decl);
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
DECL_SAVED_TREE (decl) = body;
TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
DECL_UNINLINABLE (decl) = 1;
DECL_INITIAL (decl) = make_node (BLOCK);
TREE_USED (DECL_INITIAL (decl)) = 1;
DECL_SOURCE_LOCATION (decl) = input_location;
cfun->function_end_locus = input_location;
if (which == 'I')
DECL_STATIC_CONSTRUCTOR (decl) = 1;
else if (which == 'D')
DECL_STATIC_DESTRUCTOR (decl) = 1;
else
abort ();
gimplify_function_tree (decl);
/* ??? We will get called LATE in the compilation process. */
if (cgraph_global_info_ready)
tree_rest_of_compilation (decl, false);
else
cgraph_finalize_function (decl, 0);
if (targetm.have_ctors_dtors)
{
void (*fn) (rtx, int);
if (which == 'I')
fn = targetm.asm_out.constructor;
else
fn = targetm.asm_out.destructor;
fn (XEXP (DECL_RTL (decl), 0), DEFAULT_INIT_PRIORITY);
}
}
......@@ -39,11 +39,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "function.h"
#include "toplev.h"
#include "ggc.h"
#include "target.h"
#include "coverage.h"
#include "libfuncs.h"
#include "langhooks.h"
#include "hashtab.h"
#include "tree-iterator.h"
#include "cgraph.h"
#include "gcov-io.c"
......@@ -904,69 +904,42 @@ build_gcov_info (void)
static void
create_coverage (void)
{
tree gcov_info, gcov_info_value;
char name[20];
char *ctor_name;
tree ctor;
rtx gcov_info_address;
tree gcov_info, gcov_init, body, t;
char name_buf[32];
no_coverage = 1; /* Disable any further coverage. */
if (!prg_ctr_mask)
return;
gcov_info_value = build_gcov_info ();
gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (gcov_info_value));
DECL_INITIAL (gcov_info) = gcov_info_value;
t = build_gcov_info ();
gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (t));
TREE_STATIC (gcov_info) = 1;
ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
DECL_NAME (gcov_info) = get_identifier (name);
ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
DECL_NAME (gcov_info) = get_identifier (name_buf);
DECL_INITIAL (gcov_info) = t;
/* Build structure. */
assemble_variable (gcov_info, 0, 0, 0);
/* Build the constructor function to invoke __gcov_init. */
ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
"_GCOV", NULL);
ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
build_function_type (void_type_node, NULL_TREE));
free (ctor_name);
DECL_EXTERNAL (ctor) = 0;
/* It can be a static function as long as collect2 does not have
to scan the object file to find its ctor/dtor routine. */
TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
TREE_USED (ctor) = 1;
DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
DECL_UNINLINABLE (ctor) = 1;
rest_of_decl_compilation (ctor, 0, 1, 0);
announce_function (ctor);
current_function_decl = ctor;
make_decl_rtl (ctor, NULL);
init_function_start (ctor);
expand_function_start (ctor, 0);
/* Actually generate the code to call __gcov_init. */
gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
gcov_info_address, Pmode);
expand_function_end ();
/* Create a dummy BLOCK. */
DECL_INITIAL (ctor) = make_node (BLOCK);
TREE_USED (DECL_INITIAL (ctor)) = 1;
rest_of_compilation ();
if (! quiet_flag)
fflush (asm_out_file);
current_function_decl = NULL_TREE;
if (targetm.have_ctors_dtors)
targetm.asm_out.constructor (XEXP (DECL_RTL (ctor), 0),
DEFAULT_INIT_PRIORITY);
/* Build a decl for __gcov_init. */
t = build_pointer_type (TREE_TYPE (gcov_info));
t = build_function_type_list (void_type_node, t, NULL);
t = build_decl (FUNCTION_DECL, get_identifier ("__gcov_init"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
gcov_init = t;
/* Generate a call to __gcov_init(&gcov_info). */
body = NULL;
t = build_fold_addr_expr (gcov_info);
t = tree_cons (NULL, t, NULL);
t = build_function_call_expr (gcov_init, t);
append_to_statement_list (t, &body);
/* Generate a constructor to run it. */
cgraph_build_static_cdtor ('I', body);
}
/* Perform file-level initialization. Read in data file, generate name
......
2004-07-01 Richard Henderson <rth@redhat.com>
* class.c (registerClass_libfunc): Remove.
(init_class_processing): Don't set it.
(emit_register_classes): Take list_p parameter. Fill it in
with _Jv_RegisterClass calls.
* decl.c (java_init_decl_processing): Don't call
init_resource_processing.
* jcf-parse.c (java_emit_static_constructor): New.
(java_parse_file): Call it.
* resource.c (registerResource_libfunc): Remove.
(init_resource_processing): Remove.
(write_resource_constructor): Take list_p parameter. Fill it in
with _Jv_RegisterResource calls.
* java-tree.h: Update prototypes.
2004-06-29 Bryce McKinlay <mckinlay@redhat.com>
PR java/1262
......
......@@ -43,6 +43,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "stdio.h"
#include "target.h"
#include "except.h"
#include "tree-iterator.h"
/* DOS brain-damage */
#ifndef O_BINARY
......@@ -62,8 +63,6 @@ static void add_miranda_methods (tree, tree);
static int assume_compiled (const char *);
static tree build_symbol_entry (tree);
static GTY(()) rtx registerClass_libfunc;
struct obstack temporary_obstack;
/* The compiler generates different code depending on whether or not
......@@ -2276,14 +2275,19 @@ register_class (void)
/* Emit something to register classes at start-up time.
The preferred mechanism is through the .jcr section, which contain
a list of pointers to classes which get registered during
constructor invocation time. The fallback mechanism is to generate
a `constructor' function which calls _Jv_RegisterClass for each
class in this file. */
a list of pointers to classes which get registered during constructor
invocation time.
The fallback mechanism is to add statements to *LIST_P to call
_Jv_RegisterClass for each class in this file. These statements will
be added to a static constructor function for this translation unit. */
void
emit_register_classes (void)
emit_register_classes (tree *list_p)
{
if (registered_class == NULL)
return;
/* ??? This isn't quite the correct test. We also have to know
that the target is using gcc's crtbegin/crtend objects rather
than the ones that come with the operating system. */
......@@ -2302,48 +2306,21 @@ emit_register_classes (void)
}
else
{
extern tree get_file_function_name (int);
tree init_name = get_file_function_name ('I');
tree init_type = build_function_type (void_type_node, end_params_node);
tree init_decl;
tree t;
location_t saved_loc = input_location;
init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
DECL_SOURCE_LINE (init_decl) = 0;
TREE_STATIC (init_decl) = 1;
current_function_decl = init_decl;
DECL_INLINE (init_decl) = 0;
DECL_UNINLINABLE (init_decl) = 1;
DECL_RESULT (init_decl) = build_decl (RESULT_DECL, NULL_TREE,
void_type_node);
/* It can be a static function as long as collect2 does not have
to scan the object file to find its ctor/dtor routine. */
TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
/* Suppress spurious warnings. */
TREE_USED (init_decl) = 1;
pushlevel (0);
make_decl_rtl (init_decl, NULL);
init_function_start (init_decl);
expand_function_start (init_decl, 0);
for ( t = registered_class; t; t = TREE_CHAIN (t))
emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
XEXP (DECL_RTL (t), 0), Pmode);
input_location = DECL_SOURCE_LOCATION (init_decl);
expand_function_end ();
poplevel (1, 0, 1);
rest_of_compilation ();
current_function_decl = NULL_TREE;
if (targetm.have_ctors_dtors)
(* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
DEFAULT_INIT_PRIORITY);
input_location = saved_loc;
tree klass, t, register_class_fn;
t = build_function_type_list (void_type_node, class_ptr_type, NULL);
t = build_decl (FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
register_class_fn = t;
for (klass = registered_class; klass; klass = TREE_CHAIN (klass))
{
t = build_fold_addr_expr (klass);
t = tree_cons (NULL, t, NULL);
t = build_function_call_expr (register_class_fn, t);
append_to_statement_list (t, list_p);
}
}
}
......@@ -2483,9 +2460,9 @@ emit_catch_table (tree this_class)
void
init_class_processing (void)
{
registerClass_libfunc = gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterClass");
fields_ident = get_identifier ("fields");
info_ident = get_identifier ("info");
gcc_obstack_init (&temporary_obstack);
}
......
......@@ -452,7 +452,6 @@ java_init_decl_processing (void)
tree t;
init_class_processing ();
init_resource_processing ();
current_function_decl = NULL;
current_binding_level = NULL_BINDING_LEVEL;
......
......@@ -1245,7 +1245,7 @@ extern tree get_method_index (tree decl);
extern void make_class_data (tree);
extern void register_class (void);
extern int alloc_name_constant (int, tree);
extern void emit_register_classes (void);
extern void emit_register_classes (tree *);
extern tree emit_symbol_table (tree, tree, tree, tree, tree);
extern void lang_init_source (int);
extern void write_classfile (tree);
......@@ -1341,8 +1341,7 @@ extern void java_inlining_map_static_initializers (tree, void *);
extern void compile_resource_data (const char *name, const char *buffer, int);
extern void compile_resource_file (const char *, const char *);
extern void write_resource_constructor (void);
extern void init_resource_processing (void);
extern void write_resource_constructor (tree *);
extern tree build_java_empty_stmt (void);
extern tree add_stmt_to_compound (tree, tree, tree);
extern tree java_add_stmt (tree);
......
......@@ -875,6 +875,21 @@ predefined_filename_p (tree node)
return 0;
}
/* Generate a function that does all static initialization for this
translation unit. */
static void
java_emit_static_constructor (void)
{
tree body = NULL;
emit_register_classes (&body);
write_resource_constructor (&body);
if (body)
cgraph_build_static_cdtor ('I', body);
}
void
java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
{
......@@ -1013,7 +1028,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list));
compile_resource_file (resource_name, resource_filename);
return;
goto finish;
}
current_jcf = main_jcf;
......@@ -1120,23 +1135,23 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
input_filename = main_input_filename;
java_expand_classes ();
if (!java_report_errors () && !flag_syntax_only)
{
/* Expand all classes compiled from source. */
java_finish_classes ();
/* Emit the .jcf section. */
emit_register_classes ();
/* Only finalize the compilation unit after we've told cgraph which
functions have their addresses stored. */
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
}
write_resource_constructor ();
if (java_report_errors () || flag_syntax_only)
return;
/* Expand all classes compiled from source. */
java_finish_classes ();
finish:
/* Arrange for any necessary initialization to happen. */
java_emit_static_constructor ();
/* Only finalize the compilation unit after we've told cgraph which
functions have their addresses stored. */
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
}
/* Return the name of the class corresponding to the name of the file
in this zip entry. The result is newly allocated using ALLOC. */
static char *
......
......@@ -41,6 +41,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "stdio.h"
#include "target.h"
#include "expr.h"
#include "tree-iterator.h"
/* DOS brain-damage */
#ifndef O_BINARY
......@@ -50,9 +51,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
/* A list of all the resources files. */
static GTY(()) tree resources = NULL;
/* Function used to register resources. */
static GTY(()) rtx registerResource_libfunc;
/* Count of all the resources compiled in this invocation. */
static int Jr_count = 0;
......@@ -101,65 +99,27 @@ compile_resource_data (const char *name, const char *buffer, int length)
}
void
write_resource_constructor (void)
write_resource_constructor (tree *list_p)
{
tree init_name, init_type, init_decl;
tree iter;
location_t saved_loc = input_location;
char *resource_ctor_name;
tree iter, t, register_resource_fn;
/* Only do work if required. */
if (resources == NULL_TREE)
if (resources == NULL)
return;
resource_ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
"_resource", NULL);
init_name = get_identifier (resource_ctor_name);
free (resource_ctor_name);
init_type = build_function_type (void_type_node, end_params_node);
init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
DECL_SOURCE_LINE (init_decl) = 0;
SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
TREE_STATIC (init_decl) = 1;
current_function_decl = init_decl;
DECL_RESULT (init_decl) = build_decl (RESULT_DECL,
NULL_TREE, void_type_node);
/* It can be a static function as long as collect2 does not have
to scan the object file to find its ctor/dtor routine. */
TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
/* Suppress spurious warnings. */
TREE_USED (init_decl) = 1;
pushlevel (0);
make_decl_rtl (init_decl, NULL);
init_function_start (init_decl);
expand_function_start (init_decl, 0);
t = build_function_type_list (void_type_node, ptr_type_node, NULL);
t = build_decl (FUNCTION_DECL, get_identifier ("_Jv_RegisterResource"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
register_resource_fn = t;
/* Write out entries in the same order in which they were defined. */
for (iter = nreverse (resources); iter != NULL_TREE;
iter = TREE_CHAIN (iter))
for (iter = nreverse (resources); iter ; iter = TREE_CHAIN (iter))
{
emit_library_call (registerResource_libfunc, 0, VOIDmode, 1,
expand_expr (build_address_of (TREE_VALUE (iter)),
0, Pmode, 0),
Pmode);
t = build_fold_addr_expr (TREE_VALUE (iter));
t = tree_cons (NULL, t, NULL);
t = build_function_call_expr (register_resource_fn, t);
append_to_statement_list (t, list_p);
}
input_location = DECL_SOURCE_LOCATION (init_decl);
expand_function_end ();
poplevel (1, 0, 1);
/* rest_of_compilation forces generation even if -finline-functions. */
rest_of_compilation ();
current_function_decl = NULL_TREE;
if (targetm.have_ctors_dtors)
targetm.asm_out.constructor (XEXP (DECL_RTL (init_decl), 0),
DEFAULT_INIT_PRIORITY);
input_location = saved_loc;
}
/* Generate a byte array representing the contents of FILENAME. The
......@@ -191,14 +151,6 @@ compile_resource_file (const char *name, const char *filename)
close (fd);
compile_resource_data (name, buffer, stat_buf.st_size);
write_resource_constructor ();
}
void
init_resource_processing (void)
{
registerResource_libfunc =
gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterResource");
}
#include "gt-java-resource.h"
......@@ -45,7 +45,6 @@ enum libfunc_index
LTI_profile_function_exit,
LTI_gcov_flush,
LTI_gcov_init,
LTI_MAX
};
......@@ -78,6 +77,5 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
#define profile_function_exit_libfunc (libfunc_table[LTI_profile_function_exit])
#define gcov_flush_libfunc (libfunc_table[LTI_gcov_flush])
#define gcov_init_libfunc (libfunc_table[LTI_gcov_init])
#endif /* GCC_LIBFUNCS_H */
......@@ -5550,7 +5550,6 @@ init_optabs (void)
= init_one_libfunc ("__cyg_profile_func_exit");
gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
gcov_init_libfunc = init_one_libfunc ("__gcov_init");
if (HAVE_conditional_trap)
trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
......
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