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