On Wed, Nov 1, 2017 at 7:18 PM, Alexandre Oliva <aol...@redhat.com> wrote:
> On Oct 31, 2017, Jeff Law <l...@redhat.com> 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

Reply via email to