Joern Rennecke <[email protected]> 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