diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-08-30 11:18:37 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-08-30 11:18:37 +0000 |
commit | d305ca88fc9b180a1790e02b144e921d17b393f0 (patch) | |
tree | a2c9e2b70bbf121f659d36303df886bad0895c81 /gcc/final.c | |
parent | 2123a9a50fb35109af6c2ba3bcfd71a1d5432954 (diff) | |
download | gcc-d305ca88fc9b180a1790e02b144e921d17b393f0.zip gcc-d305ca88fc9b180a1790e02b144e921d17b393f0.tar.gz gcc-d305ca88fc9b180a1790e02b144e921d17b393f0.tar.bz2 |
[59/77] Add a rtx_jump_table_data::get_data_mode helper
This patch adds a helper function to get the mode of the addresses
or offsets in a jump table. It also changes the final.c code to use
rtx_jump_table_data over rtx or rtx_insn in cases where it needed
to use the new helper. This in turn meant adding a safe_dyn_cast
equivalent of safe_as_a, to cope with null NEXT_INSNs.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* is-a.h (safe_dyn_cast): New function.
* rtl.h (rtx_jump_table_data::get_data_mode): New function.
(jump_table_for_label): Likewise.
* final.c (final_addr_vec_align): Take an rtx_jump_table_data *
instead of an rtx_insn *.
(shorten_branches): Use dyn_cast instead of LABEL_P and
JUMP_TABLE_DATA_P. Use jump_table_for_label and
rtx_jump_table_data::get_data_mode.
(final_scan_insn): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r251511
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 84 |
1 files changed, 39 insertions, 45 deletions
diff --git a/gcc/final.c b/gcc/final.c index be41d6e..8af1f17 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -219,9 +219,6 @@ static void leaf_renumber_regs (rtx_insn *); #if HAVE_cc0 static int alter_cond (rtx); #endif -#ifndef ADDR_VEC_ALIGN -static int final_addr_vec_align (rtx_insn *); -#endif static int align_fuzz (rtx, rtx, int, unsigned); static void collect_fn_hard_reg_usage (void); static tree get_call_fndecl (rtx_insn *); @@ -518,9 +515,9 @@ default_jump_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) #ifndef ADDR_VEC_ALIGN static int -final_addr_vec_align (rtx_insn *addr_vec) +final_addr_vec_align (rtx_jump_table_data *addr_vec) { - int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec))); + int align = GET_MODE_SIZE (addr_vec->get_data_mode ()); if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT) align = BIGGEST_ALIGNMENT / BITS_PER_UNIT; @@ -937,45 +934,41 @@ shorten_branches (rtx_insn *first) if (INSN_P (insn)) continue; - if (LABEL_P (insn)) + if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn)) { - rtx_insn *next; - bool next_is_jumptable; - /* Merge in alignments computed by compute_alignments. */ - log = LABEL_TO_ALIGNMENT (insn); + log = LABEL_TO_ALIGNMENT (label); if (max_log < log) { max_log = log; - max_skip = LABEL_TO_MAX_SKIP (insn); + max_skip = LABEL_TO_MAX_SKIP (label); } - next = next_nonnote_insn (insn); - next_is_jumptable = next && JUMP_TABLE_DATA_P (next); - if (!next_is_jumptable) + rtx_jump_table_data *table = jump_table_for_label (label); + if (!table) { - log = LABEL_ALIGN (insn); + log = LABEL_ALIGN (label); if (max_log < log) { max_log = log; - max_skip = targetm.asm_out.label_align_max_skip (insn); + max_skip = targetm.asm_out.label_align_max_skip (label); } } /* ADDR_VECs only take room if read-only data goes into the text section. */ if ((JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section) - && next_is_jumptable) + && table) { - log = ADDR_VEC_ALIGN (next); + log = ADDR_VEC_ALIGN (table); if (max_log < log) { max_log = log; - max_skip = targetm.asm_out.label_align_max_skip (insn); + max_skip = targetm.asm_out.label_align_max_skip (label); } } - LABEL_TO_ALIGNMENT (insn) = max_log; - LABEL_TO_MAX_SKIP (insn) = max_skip; + LABEL_TO_ALIGNMENT (label) = max_log; + LABEL_TO_MAX_SKIP (label) = max_skip; max_log = 0; max_skip = 0; } @@ -1131,7 +1124,7 @@ shorten_branches (rtx_insn *first) continue; body = PATTERN (insn); - if (JUMP_TABLE_DATA_P (insn)) + if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) { /* This only takes room if read-only data goes into the text section. */ @@ -1139,7 +1132,7 @@ shorten_branches (rtx_insn *first) || readonly_data_section == text_section) insn_lengths[uid] = (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC) - * GET_MODE_SIZE (GET_MODE (body))); + * GET_MODE_SIZE (table->get_data_mode ())); /* Alignment is handled by ADDR_VEC_ALIGN. */ } else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) @@ -1219,28 +1212,27 @@ shorten_branches (rtx_insn *first) uid = INSN_UID (insn); - if (LABEL_P (insn)) + if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn)) { - int log = LABEL_TO_ALIGNMENT (insn); + int log = LABEL_TO_ALIGNMENT (label); #ifdef CASE_VECTOR_SHORTEN_MODE /* If the mode of a following jump table was changed, we may need to update the alignment of this label. */ - rtx_insn *next; - bool next_is_jumptable; - - next = next_nonnote_insn (insn); - next_is_jumptable = next && JUMP_TABLE_DATA_P (next); - if ((JUMP_TABLES_IN_TEXT_SECTION - || readonly_data_section == text_section) - && next_is_jumptable) + + if (JUMP_TABLES_IN_TEXT_SECTION + || readonly_data_section == text_section) { - int newlog = ADDR_VEC_ALIGN (next); - if (newlog != log) + rtx_jump_table_data *table = jump_table_for_label (label); + if (table) { - log = newlog; - LABEL_TO_ALIGNMENT (insn) = log; - something_changed = 1; + int newlog = ADDR_VEC_ALIGN (table); + if (newlog != log) + { + log = newlog; + LABEL_TO_ALIGNMENT (insn) = log; + something_changed = 1; + } } } #endif @@ -1271,6 +1263,7 @@ shorten_branches (rtx_insn *first) && JUMP_TABLE_DATA_P (insn) && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) { + rtx_jump_table_data *table = as_a <rtx_jump_table_data *> (insn); rtx body = PATTERN (insn); int old_length = insn_lengths[uid]; rtx_insn *rel_lab = @@ -1366,13 +1359,14 @@ shorten_branches (rtx_insn *first) max_addr - rel_addr, body); if (!increasing || (GET_MODE_SIZE (vec_mode) - >= GET_MODE_SIZE (GET_MODE (body)))) + >= GET_MODE_SIZE (table->get_data_mode ()))) PUT_MODE (body, vec_mode); if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section) { insn_lengths[uid] - = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body))); + = (XVECLEN (body, 1) + * GET_MODE_SIZE (table->get_data_mode ())); insn_current_address += insn_lengths[uid]; if (insn_lengths[uid] != old_length) something_changed = 1; @@ -2191,6 +2185,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, rtx set; #endif rtx_insn *next; + rtx_jump_table_data *table; insn_counter++; @@ -2448,11 +2443,11 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, app_disable (); - next = next_nonnote_insn (insn); /* If this label is followed by a jump-table, make sure we put the label in the read-only section. Also possibly write the label and jump table together. */ - if (next != 0 && JUMP_TABLE_DATA_P (next)) + table = jump_table_for_label (as_a <rtx_code_label *> (insn)); + if (table) { #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC) /* In this case, the case vector is being moved by the @@ -2467,7 +2462,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, (current_function_decl)); #ifdef ADDR_VEC_ALIGN - log_align = ADDR_VEC_ALIGN (next); + log_align = ADDR_VEC_ALIGN (table); #else log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); #endif @@ -2477,8 +2472,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, switch_to_section (current_function_section ()); #ifdef ASM_OUTPUT_CASE_LABEL - ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), - next); + ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), table); #else targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn)); #endif |