Joern Rennecke <joern.renne...@embecosm.com> writes:
> @@ -1165,6 +1175,7 @@ shorten_branches (rtx first ATTRIBUTE_UN
>       get the current insn length.  If it has changed, reflect the change.
>       When nothing changes for a full pass, we are done.  */
>  
> +  bool first_pass ATTRIBUTE_UNUSED = true;
>    while (something_changed)
>      {
>        something_changed = 0;
> @@ -1220,6 +1231,7 @@ shorten_branches (rtx first ATTRIBUTE_UN
>             rtx prev;
>             int rel_align = 0;
>             addr_diff_vec_flags flags;
> +           enum machine_mode vec_mode;
>  
>             /* Avoid automatic aggregate initialization.  */
>             flags = ADDR_DIFF_VEC_FLAGS (body);
> @@ -1298,9 +1310,12 @@ shorten_branches (rtx first ATTRIBUTE_UN
>                 else
>                   max_addr += align_fuzz (max_lab, rel_lab, 0, 0);
>               }
> -           PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
> -                                                     max_addr - rel_addr,
> -                                                     body));
> +           vec_mode = CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
> +                                                max_addr - rel_addr, body);
> +           if (first_pass
> +               || (GET_MODE_SIZE (vec_mode)
> +                   >= GET_MODE_SIZE (GET_MODE (body))))
> +             PUT_MODE (body, vec_mode);
>             if (JUMP_TABLES_IN_TEXT_SECTION
>                 || readonly_data_section == text_section)
>               {

I think instead the set-up loop should have:

      if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
        {
#ifdef CASE_VECTOR_SHORTEN_MODE
          if (increasing && GET_CODE (body) == ADDR_DIFF_VEC)
            PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (0, 0, body));
#endif
          /* This only takes room if read-only data goes into the text
             section.  */
          if (JUMP_TABLES_IN_TEXT_SECTION
              || readonly_data_section == text_section)
            insn_lengths[uid] = (XVECLEN (body,
                                          GET_CODE (body) == ADDR_DIFF_VEC)
                                 * GET_MODE_SIZE (GET_MODE (body)));
          /* Alignment is handled by ADDR_VEC_ALIGN.  */
        }

(with just the CASE_VECTOR_SHORTEN_MODE part being new).
We then start with the most optimistic length possible,
as with everything else.

The main shortening if statement should then be conditional on:

#ifdef CASE_VECTOR_SHORTEN_MODE
          if (increasing
              && JUMP_P (insn)
              && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
...

(testing "increasing" rather than "optimize").  The code for changing
the mode should simply be:

              if (GET_MODE_SIZE (vec_mode)
                  >= GET_MODE_SIZE (GET_MODE (body))))
                PUT_MODE (body, vec_mode);

with first_pass no longer being necessary.

OK with that change, if you agree.

Richard

Reply via email to