From: Richard Guenther <rguenther@suse.de>
To: Tristan Gingold <gingold@adacore.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
Eric Botcazou <ebotcazou@adacore.com>, Jan Hubicka <jh@suse.de>
Subject: Re: [Patch/cfgexpand]: also consider assembler_name to call expand_main_function
Date: Tue, 20 Mar 2012 16:02:00 -0000 [thread overview]
Message-ID: <alpine.LNX.2.00.1203201701230.4662@zhemvz.fhfr.qr> (raw)
In-Reply-To: <D999EBA8-A0F5-49E6-9BC3-90A44A8BE9DD@adacore.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 18193 bytes --]
On Tue, 20 Mar 2012, Tristan Gingold wrote:
>
> On Mar 20, 2012, at 3:19 PM, Richard Guenther wrote:
>
> [Â…]
> >
> > I'd rather get away from using a global main_identifier_node, instead
> > make that frontend specific, and introduce targetm.main_assembler_name
> > which the assembler-name creating langhook would make sure to use
> > when mangling what the FE thinks main is. main_identifier_node should
> > not serve any purpose outside of Frontends.
> >
> > But I see both as a possible cleanup opportunity, not a necessary change.
>
> Something along these lines ?
Yes, but I'd simply call the hook at the places you now use
main_assembler_name and not create a global tree node for it.
Richard.
> Tristan.
>
> diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
> index 89f5438..c575e97 100644
> --- a/gcc/ada/gcc-interface/trans.c
> +++ b/gcc/ada/gcc-interface/trans.c
> @@ -622,8 +622,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
> integer_type_node, NULL_TREE, true, false, true, false,
> NULL, Empty);
>
> - main_identifier_node = get_identifier ("main");
> -
> /* Install the builtins we might need, either internally or as
> user available facilities for Intrinsic imports. */
> gnat_install_builtins ();
> diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
> index 7383358..b0fa085d 100644
> --- a/gcc/ada/gcc-interface/utils.c
> +++ b/gcc/ada/gcc-interface/utils.c
> @@ -1902,14 +1902,12 @@ create_subprog_decl (tree subprog_name, tree asm_name, tree subprog_type,
> {
> SET_DECL_ASSEMBLER_NAME (subprog_decl, asm_name);
>
> - /* The expand_main_function circuitry expects "main_identifier_node" to
> - designate the DECL_NAME of the 'main' entry point, in turn expected
> - to be declared as the "main" function literally by default. Ada
> - program entry points are typically declared with a different name
> + /* Ada program entry points are typically declared with a different name
> within the binder generated file, exported as 'main' to satisfy the
> - system expectations. Force main_identifier_node in this case. */
> - if (asm_name == main_identifier_node)
> - DECL_NAME (subprog_decl) = main_identifier_node;
> + system expectations. Force main_assembler_node in this case. */
> + if (IDENTIFIER_LENGTH (asm_name) == 4
> + && memcmp (IDENTIFIER_POINTER (asm_name), "main", 4) == 0)
> + DECL_NAME (subprog_decl) = main_assembler_name;
> }
>
> /* Add this decl to the current binding level. */
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index 835b13b..fea5181 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -291,6 +291,8 @@ enum c_tree_index
>
> CTI_DEFAULT_FUNCTION_TYPE,
>
> + CTI_MAIN_IDENTIFIER,
> +
> /* These are not types, but we have to look them up all the time. */
> CTI_FUNCTION_NAME_DECL,
> CTI_PRETTY_FUNCTION_NAME_DECL,
> @@ -426,6 +428,10 @@ extern const unsigned int num_c_common_reswords;
>
> #define default_function_type c_global_trees[CTI_DEFAULT_FUNCTION_TYPE]
>
> +#define main_identifier_node c_global_trees[CTI_MAIN_IDENTIFIER]
> +#define MAIN_NAME_P(NODE) \
> + (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)
> +
> #define function_name_decl_node c_global_trees[CTI_FUNCTION_NAME_DECL]
> #define pretty_function_name_decl_node c_global_trees[CTI_PRETTY_FUNCTION_NAME_DECL]
> #define c99_function_name_decl_node c_global_trees[CTI_C99_FUNCTION_NAME_DECL]
> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> index bd21169..db53309 100644
> --- a/gcc/cfgexpand.c
> +++ b/gcc/cfgexpand.c
> @@ -4513,9 +4513,7 @@ gimple_expand_cfg (void)
>
> /* If this function is `main', emit a call to `__main'
> to run global initializers, etc. */
> - if (DECL_NAME (current_function_decl)
> - && MAIN_NAME_P (DECL_NAME (current_function_decl))
> - && DECL_FILE_SCOPE_P (current_function_decl))
> + if (cgraph_main_function_p (cgraph_get_node (current_function_decl)))
> expand_main_function ();
>
> /* Initialize the stack_protect_guard field. This must happen after the
> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
> index 9cc3690..528fd19 100644
> --- a/gcc/cgraph.c
> +++ b/gcc/cgraph.c
> @@ -2766,7 +2766,7 @@ cgraph_propagate_frequency_1 (struct cgraph_node *node, void *data)
> /* It makes sense to put main() together with the static constructors.
> It will be executed for sure, but rest of functions called from
> main are definitely not at startup only. */
> - if (MAIN_NAME_P (DECL_NAME (edge->caller->decl)))
> + if (cgraph_main_function_p (edge->caller))
> d->only_called_at_startup = 0;
> d->only_called_at_exit &= edge->caller->only_called_at_exit;
> }
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index 191364c..089d851 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -101,6 +101,9 @@ struct GTY(()) cgraph_local_info {
>
> /* True if the function may enter serial irrevocable mode. */
> unsigned tm_may_enter_irr : 1;
> +
> + /* True if the function is the program entry point (main in C). */
> + unsigned main_function : 1;
> };
>
> /* Information about the function that needs to be computed globally
> @@ -790,6 +793,13 @@ cgraph_next_function_with_gimple_body (struct cgraph_node *node)
> return NULL;
> }
>
> +/* Return true iff NODE is the main function (main in C). */
> +static inline bool
> +cgraph_main_function_p (struct cgraph_node *node)
> +{
> + return node && node->local.main_function;
> +}
> +
> /* Walk all functions with body defined. */
> #define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
> for ((node) = cgraph_first_function_with_gimple_body (); (node); \
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 516f187..556f21c 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -346,6 +346,9 @@ cgraph_finalize_function (tree decl, bool nested)
> notice_global_symbol (decl);
> node->local.finalized = true;
> node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
> + node->local.main_function =
> + DECL_FILE_SCOPE_P (decl)
> + && decl_assembler_name_equal (decl, main_assembler_name);
>
> if (cgraph_decide_is_function_needed (node, decl))
> cgraph_mark_needed_node (node);
> diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
> index 2eccda9..e0f6234 100644
> --- a/gcc/config/i386/cygming.h
> +++ b/gcc/config/i386/cygming.h
> @@ -360,7 +360,7 @@ do { \
>
> #undef PROFILE_HOOK
> #define PROFILE_HOOK(LABEL) \
> - if (MAIN_NAME_P (DECL_NAME (current_function_decl))) \
> + if (cgraph_main_function_p (cgraph_get_node (current_function_decl))) \
> { \
> emit_call_insn (gen_rtx_CALL (VOIDmode, \
> gen_rtx_MEM (FUNCTION_MODE, \
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 78a366e..c4a78b1 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -9509,9 +9509,7 @@ ix86_minimum_incoming_stack_boundary (bool sibcall)
> /* Stack at entrance of main is aligned by runtime. We use the
> smallest incoming stack boundary. */
> if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
> - && DECL_NAME (current_function_decl)
> - && MAIN_NAME_P (DECL_NAME (current_function_decl))
> - && DECL_FILE_SCOPE_P (current_function_decl))
> + && cgraph_main_function_p (cgraph_get_node (current_function_decl)))
> incoming_stack_boundary = MAIN_STACK_BOUNDARY;
>
> return incoming_stack_boundary;
> diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
> index 42e3af0..d1df127 100644
> --- a/gcc/config/pdp11/pdp11.c
> +++ b/gcc/config/pdp11/pdp11.c
> @@ -240,7 +240,8 @@ pdp11_expand_prologue (void)
>
> /* If we are outputting code for main, the switch FPU to the
> right mode if TARGET_FPU. */
> - if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
> + if (TARGET_FPU
> + && cgraph_main_function_p (cgraph_get_node (current_function_decl)))
> {
> emit_insn (gen_setd ());
> emit_insn (gen_seti ());
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index 2891bb6..654f8ec 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -8102,6 +8102,11 @@ systems. This macro is used in @code{assemble_name}.
> Given a symbol @var{name}, perform same mangling as @code{varasm.c}'s @code{assemble_name}, but in memory rather than to a file stream, returning result as an @code{IDENTIFIER_NODE}. Required for correct LTO symtabs. The default implementation calls the @code{TARGET_STRIP_NAME_ENCODING} hook and then prepends the @code{USER_LABEL_PREFIX}, if any.
> @end deftypefn
>
> +@deftypefn {Target Hook} tree TARGET_MAIN_ASSEMBLER_NAME (void)
> +It returns the assembler name for the 'main' function.
> +The default is to return 'main', which will be prefixed by USER_LABEL_PREFIX.
> +@end deftypefn
> +
> @defmac ASM_OUTPUT_SYMBOL_REF (@var{stream}, @var{sym})
> A C statement (sans semicolon) to output a reference to
> @code{SYMBOL_REF} @var{sym}. If not defined, @code{assemble_name}
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index a222654..6765344 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -8007,6 +8007,8 @@ systems. This macro is used in @code{assemble_name}.
>
> @hook TARGET_MANGLE_ASSEMBLER_NAME
>
> +@hook TARGET_MAIN_ASSEMBLER_NAME
> +
> @defmac ASM_OUTPUT_SYMBOL_REF (@var{stream}, @var{sym})
> A C statement (sans semicolon) to output a reference to
> @code{SYMBOL_REF} @var{sym}. If not defined, @code{assemble_name}
> diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
> index 8a1dd2e..a51b0ac 100644
> --- a/gcc/fortran/trans-decl.c
> +++ b/gcc/fortran/trans-decl.c
> @@ -4922,9 +4922,8 @@ create_main_function (tree fndecl)
> tmp = build_function_type_list (integer_type_node, integer_type_node,
> build_pointer_type (pchar_type_node),
> NULL_TREE);
> - main_identifier_node = get_identifier ("main");
> ftn_main = build_decl (input_location, FUNCTION_DECL,
> - main_identifier_node, tmp);
> + get_identifier ("main"), tmp);
> DECL_EXTERNAL (ftn_main) = 0;
> TREE_PUBLIC (ftn_main) = 1;
> TREE_STATIC (ftn_main) = 1;
> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
> index 9dddf39..595330e 100644
> --- a/gcc/ipa-split.c
> +++ b/gcc/ipa-split.c
> @@ -1409,7 +1409,7 @@ execute_split_functions (void)
> fprintf (dump_file, "Not splitting: noreturn/malloc function.\n");
> return 0;
> }
> - if (MAIN_NAME_P (DECL_NAME (current_function_decl)))
> + if (cgraph_main_function_p (node))
> {
> if (dump_file)
> fprintf (dump_file, "Not splitting: main function.\n");
> diff --git a/gcc/ipa.c b/gcc/ipa.c
> index 388291a..f9dc42d 100644
> --- a/gcc/ipa.c
> +++ b/gcc/ipa.c
> @@ -639,7 +639,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
> else if (!whole_program)
> return true;
>
> - if (MAIN_NAME_P (DECL_NAME (node->decl)))
> + if (cgraph_main_function_p (node))
> return true;
>
> return false;
> diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
> index 5e899bc..34bcc55 100644
> --- a/gcc/lto-cgraph.c
> +++ b/gcc/lto-cgraph.c
> @@ -502,6 +502,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
> bp_pack_value (&bp, node->local.versionable, 1);
> bp_pack_value (&bp, node->local.can_change_signature, 1);
> bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
> + bp_pack_value (&bp, node->local.main_function, 1);
> bp_pack_value (&bp, node->needed, 1);
> bp_pack_value (&bp, node->address_taken, 1);
> bp_pack_value (&bp, node->abstract_and_needed, 1);
> @@ -904,6 +905,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
> node->local.versionable = bp_unpack_value (bp, 1);
> node->local.can_change_signature = bp_unpack_value (bp, 1);
> node->local.redefined_extern_inline = bp_unpack_value (bp, 1);
> + node->local.main_function = bp_unpack_value (bp, 1);
> node->needed = bp_unpack_value (bp, 1);
> node->address_taken = bp_unpack_value (bp, 1);
> node->abstract_and_needed = bp_unpack_value (bp, 1);
> diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
> index 999db8b..a44a35f 100644
> --- a/gcc/lto/lto-lang.c
> +++ b/gcc/lto/lto-lang.c
> @@ -1137,13 +1137,6 @@ lto_init (void)
> /* Create the basic integer types. */
> build_common_tree_nodes (flag_signed_char, /*short_double=*/false);
>
> - /* The global tree for the main identifier is filled in by
> - language-specific front-end initialization that is not run in the
> - LTO back-end. It appears that all languages that perform such
> - initialization currently do so in the same way, so we do it here. */
> - if (main_identifier_node == NULL_TREE)
> - main_identifier_node = get_identifier ("main");
> -
> /* In the C++ front-end, fileptr_type_node is defined as a variant
> copy of of ptr_type_node, rather than ptr_node itself. The
> distinction should only be relevant to the front-end, so we
> diff --git a/gcc/predict.c b/gcc/predict.c
> index c12b45f..819e64c 100644
> --- a/gcc/predict.c
> +++ b/gcc/predict.c
> @@ -2275,7 +2275,7 @@ compute_function_frequency (void)
> basic_block bb;
> struct cgraph_node *node = cgraph_get_node (current_function_decl);
> if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
> - || MAIN_NAME_P (DECL_NAME (current_function_decl)))
> + || cgraph_main_function_p (node))
> node->only_called_at_startup = true;
> if (DECL_STATIC_DESTRUCTOR (current_function_decl))
> node->only_called_at_exit = true;
> @@ -2291,7 +2291,7 @@ compute_function_frequency (void)
> node->frequency = NODE_FREQUENCY_HOT;
> else if (flags & ECF_NORETURN)
> node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
> - else if (MAIN_NAME_P (DECL_NAME (current_function_decl)))
> + else if (cgraph_main_function_p (node))
> node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
> else if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
> || DECL_STATIC_DESTRUCTOR (current_function_decl))
> diff --git a/gcc/target.def b/gcc/target.def
> index d658b11..2c91620 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -1473,6 +1473,17 @@ DEFHOOK
> tree, (tree decl, tree id),
> default_mangle_decl_assembler_name)
>
> +/* Return the assembler name for the 'main' function. It should return the
> + same identifier as mandle_decl_assembler_name will for the C 'main'
> + function.
> + The default is to return 'main'. */
> +DEFHOOK
> +(main_assembler_name,
> + "It returns the assembler name for the 'main' function.\n\
> +The default is to return 'main', which will be prefixed by USER_LABEL_PREFIX.",
> + tree, (void),
> + default_main_assembler_name)
> +
> /* Do something target-specific to record properties of the DECL into
> the associated SYMBOL_REF. */
> DEFHOOK
> diff --git a/gcc/targhooks.c b/gcc/targhooks.c
> index 8e3d74e..08535b4 100644
> --- a/gcc/targhooks.c
> +++ b/gcc/targhooks.c
> @@ -371,6 +371,13 @@ default_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED)
> return get_identifier (stripped);
> }
>
> +/* The default implementation of TARGET_MAIN_ASSEMBLER_NAME. */
> +tree
> +default_main_assembler_name (void)
> +{
> + return get_identifier ("main");
> +}
> +
> /* True if MODE is valid for the target. By "valid", we mean able to
> be manipulated in non-trivial ways. In particular, this means all
> the arithmetic is supported.
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index 8618115..3016f04 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -66,6 +66,7 @@ extern void default_print_operand (FILE *, rtx, int);
> extern void default_print_operand_address (FILE *, rtx);
> extern bool default_print_operand_punct_valid_p (unsigned char);
> extern tree default_mangle_assembler_name (const char *);
> +extern tree default_main_assembler_name (void);
>
> extern bool default_scalar_mode_supported_p (enum machine_mode);
> extern bool targhook_words_big_endian (void);
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index b65f5aa..9cb7a16 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -6933,7 +6933,7 @@ ipa_pta_execute (void)
>
> /* We also need to make function return values escape. Nothing
> escapes by returning from main though. */
> - if (!MAIN_NAME_P (DECL_NAME (node->decl)))
> + if (!cgraph_main_function_p (node->decl))
> {
> varinfo_t fi, rvi;
> fi = lookup_vi_for_tree (node->decl);
> diff --git a/gcc/tree.c b/gcc/tree.c
> index cfea9f7..6a0d380 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -9477,6 +9477,8 @@ build_common_tree_nodes (bool signed_char, bool short_double)
>
> va_list_type_node = t;
> }
> +
> + main_assembler_name = targetm.main_assembler_name ();
> }
>
> /* A subroutine of build_common_builtin_nodes. Define a builtin function. */
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 62ee454..45c750f 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -3805,7 +3805,7 @@ enum tree_index
>
> TI_VOID_LIST_NODE,
>
> - TI_MAIN_IDENTIFIER,
> + TI_MAIN_ASSEMBLER_NAME,
>
> TI_SAT_SFRACT_TYPE,
> TI_SAT_FRACT_TYPE,
> @@ -4048,9 +4048,7 @@ extern GTY(()) tree global_trees[TI_MAX];
> anything else about this node. */
> #define void_list_node global_trees[TI_VOID_LIST_NODE]
>
> -#define main_identifier_node global_trees[TI_MAIN_IDENTIFIER]
> -#define MAIN_NAME_P(NODE) \
> - (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)
> +#define main_assembler_name global_trees[TI_MAIN_ASSEMBLER_NAME]
>
> /* Optimization options (OPTIMIZATION_NODE) to use for default and current
> functions. */
>
>
--
Richard Guenther <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer
next prev parent reply other threads:[~2012-03-20 16:02 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-14 16:04 Tristan Gingold
2012-03-14 16:09 ` Richard Guenther
2012-03-14 16:25 ` Tristan Gingold
2012-03-15 9:38 ` Richard Guenther
2012-03-15 12:51 ` Tristan Gingold
2012-03-20 12:07 ` Tristan Gingold
2012-03-20 12:22 ` Richard Guenther
2012-03-20 14:12 ` Tristan Gingold
2012-03-20 14:20 ` Richard Guenther
2012-03-20 16:00 ` Tristan Gingold
2012-03-20 16:02 ` Richard Guenther [this message]
2012-03-20 16:06 ` Tristan Gingold
2012-03-21 7:44 ` Richard Guenther
2012-03-20 17:18 ` Jan Hubicka
2012-03-21 8:40 ` Tristan Gingold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LNX.2.00.1203201701230.4662@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=ebotcazou@adacore.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=gingold@adacore.com \
--cc=jh@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).