summaryrefslogtreecommitdiff
path: root/gcc/final.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2017-08-30 11:18:37 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2017-08-30 11:18:37 +0000
commiteb894c13ea608c1b934080b0c7394ed65d5e9cfa (patch)
treea2c9e2b70bbf121f659d36303df886bad0895c81 /gcc/final.c
parent5e2799ea8ac58bb39840a49a28b702c23efd2334 (diff)
downloadgcc-eb894c13ea608c1b934080b0c7394ed65d5e9cfa.tar.gz
[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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@251511 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/final.c')
-rw-r--r--gcc/final.c84
1 files changed, 39 insertions, 45 deletions
diff --git a/gcc/final.c b/gcc/final.c
index be41d6e10f0..8af1f17886b 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