On Wed, Nov 1, 2017 at 7:18 PM, Alexandre Oliva <[email protected]> wrote:
> On Oct 31, 2017, Jeff Law <[email protected]> wrote:
>
>> On 09/30/2017 03:08 AM, Alexandre Oliva wrote:
>>> This API change will enable final_start_function() to "consume"
>>> initial insns, and choose the first insn to be passed to final().
>>>
>>> Many ports call final_start_function() and final() when creating
>>> thunks and whatnot, so they needed adjusting.
>> So I haven't really followed the discussion until now. What's driving
>> the need to have some insns "consumed" and have more control over what
>> tthe first insn passed to final will be?
>
> We want to build debug notes that bind arguments into the initial view
> in a function. That initial view (first .loc note) is emitted in
> final_start_function. So we don't want to process the initial debug
> bind insns in final_start_function, and not process them again in final.
>
> In response to richi's objections, I reverted the API exposed by final.c
> so that we process the loc notes in final_start_function, and just skip
> them in final, so that no changes are required to the various backends,
> at a very slight performance penalty as the leading debug insns will be
> looked at twice instead of just once, when final is so used by the
> backends.
That works for me - we can still improve with some refactoring but didn't
introduce some ugliness in the way.
Richard.
> As for uses within final.c, those benefit from an API change internal to
> that file, that allows the leading debug insns to be processed just
> once. Here are the relevant snippets from the updated patchset (yet to
> be posted):
>
>
> +/* We want to emit param bindings (before the first begin_stmt) in the
> + initial view, if we are emitting views. To that end, we may
> + consume initial notes in the function, processing them in
> + final_start_function, before signaling the beginning of the
> + prologue, rather than in final.
> +
> + We don't test whether the DECLs are PARM_DECLs: the assumption is
> + that there will be a NOTE_INSN_BEGIN_STMT marker before any
> + non-parameter NOTE_INSN_VAR_LOCATION. It's ok if the marker is not
> + there, we'll just have more variable locations bound in the initial
> + view, which is consistent with their being bound without any code
> + that would give them a value. */
> +
> +static inline bool
> +in_initial_view_p (rtx_insn *insn)
> +{
> + return !DECL_IGNORED_P (current_function_decl)
> + && debug_variable_location_views
> + && insn && GET_CODE (insn) == NOTE
> + && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION;
> +}
> +
> /* Output assembler code for the start of a function,
> and initialize some of the variables in this file
> for the new function. The label for the function and associated
> @@ -1757,12 +1819,15 @@ get_some_local_dynamic_name ()
>
> FIRST is the first insn of the rtl for the function being compiled.
> FILE is the file to write assembler code to.
> + SEEN should be initially set to zero, and it may be updated to
> + indicate we have references to the next location view, that would
> + require us to emit it at the current PC.
> OPTIMIZE_P is nonzero if we should eliminate redundant
> test and compare insns. */
>
> -void
> -final_start_function (rtx_insn *first, FILE *file,
> - int optimize_p ATTRIBUTE_UNUSED)
> +static void
> +final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
> + int optimize_p ATTRIBUTE_UNUSED)
> {
> block_depth = 0;
>
> @@ -1780,8 +1845,21 @@ final_start_function (rtx_insn *first, FILE *file,
> if (flag_sanitize & SANITIZE_ADDRESS)
> asan_function_start ();
>
> + rtx_insn *first = *firstp;
> + if (in_initial_view_p (first))
> + {
> + do
> + {
> + final_scan_insn (first, file, 0, 0, seen);
> + first = NEXT_INSN (first);
> + }
> + while (in_initial_view_p (first));
> + *firstp = first;
> + }
> +
> if (!DECL_IGNORED_P (current_function_decl))
> @@ -1856,6 +1934,17 @@ final_start_function (rtx_insn *first, FILE *file,
> profile_after_prologue (file);
> }
>
> +/* This is an exported final_start_function_1, callable without SEEN. */
> +
> +void
> +final_start_function (rtx_insn *first, FILE *file,
> + int optimize_p ATTRIBUTE_UNUSED)
> +{
> + int seen = 0;
> + final_start_function_1 (&first, file, &seen, optimize_p);
> + gcc_assert (seen == 0);
> +}
> +
> static void
> profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
> {
> @@ -1987,11 +2076,10 @@ dump_basic_block_info (FILE *file, rtx_insn *insn,
> basic_block *start_to_bb,
> /* Output assembler code for some insns: all or part of a function.
> For description of args, see `final_start_function', above. */
>
> -void
> -final (rtx_insn *first, FILE *file, int optimize_p)
> +static void
> +final_1 (rtx_insn *first, FILE *file, int seen, int optimize_p)
> {
> rtx_insn *insn, *next;
> - int seen = 0;
>
> /* Used for -dA dump. */
> basic_block *start_to_bb = NULL;
> @@ -2074,6 +2164,23 @@ final (rtx_insn *first, FILE *file, int optimize_p)
> delete_insn (insn);
> }
> }
> +
> +/* This is an exported final_1, callable without SEEN. */
> +
> +void
> +final (rtx_insn *first, FILE *file, int optimize_p)
> +{
> + /* Those that use the internal final_start_function_1/final_1 API
> + skip initial debug bind notes in final_start_function_1, and pass
> + the modified FIRST to final_1. But those that use the public
> + final_start_function/final APIs, final_start_function can't move
> + FIRST because it's not passed by reference, so if they were
> + skipped there, skip them again here. */
> + while (in_initial_view_p (first))
> + first = NEXT_INSN (first);
> +
> + final_1 (first, file, 0, optimize_p);
> +}
>
> const char *
> get_insn_template (int code, rtx insn)
>
>
> @@ -4525,8 +4650,10 @@ rest_of_handle_final (void)
> variable_tracking_main ();
>
> assemble_start_function (current_function_decl, fnname);
> - final_start_function (get_insns (), asm_out_file, optimize);
> - final (get_insns (), asm_out_file, optimize);
> + rtx_insn *first = get_insns ();
> + int seen = 0;
> + final_start_function_1 (&first, asm_out_file, &seen, optimize);
> + final_1 (first, asm_out_file, seen, optimize);
> if (flag_ipa_ra
> && !lookup_attribute ("noipa", DECL_ATTRIBUTES
> (current_function_decl)))
> collect_fn_hard_reg_usage ();
>
> --
> Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
> You must be the change you wish to see in the world. -- Gandhi
> Be Free! -- http://FSFLA.org/ FSF Latin America board member
> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer