* 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
+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
/* 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. */
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 */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "rtl.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "hashtab.h"
}
#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);
+ }
+}
#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"
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);
}
\f
/* 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
#include "stdio.h"
#include "target.h"
#include "except.h"
+#include "tree-iterator.h"
/* DOS brain-damage */
#ifndef O_BINARY
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
/* 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. */
}
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);
+ }
}
}
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);
}
\f
tree t;
init_class_processing ();
- init_resource_processing ();
current_function_decl = NULL;
current_binding_level = NULL_BINDING_LEVEL;
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);
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);
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)
{
resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list));
compile_resource_file (resource_name, resource_filename);
- return;
+ goto finish;
}
current_jcf = main_jcf;
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 *
#include "stdio.h"
#include "target.h"
#include "expr.h"
+#include "tree-iterator.h"
/* DOS brain-damage */
#ifndef O_BINARY
/* 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;
}
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
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"
LTI_profile_function_exit,
LTI_gcov_flush,
- LTI_gcov_init,
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 */
= 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);