This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Do not align labels for jump tables
- From: mitchell at codesourcery dot com (Mark Mitchell)
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 23 May 2009 10:55:15 -0700 (PDT)
- Subject: PATCH: Do not align labels for jump tables
- Reply-to: mark at codesourcery dot com
I've now checked in this patch, previously approved here:
http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00120.html
The only change since that point was to add a condition to the
testcase to make it pass on 68K/fido; those CPUs do not support
-falign-labels=8. If there are other targets with similar
limitations, adding to the target conditional in the test-case is
pre-approved.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2009-05-22 Mark Mitchell <mark@codesourcery.com>
* final.c (shorten_branches): Do not align labels for jump tables.
(final_scan_insn): Use JUMP_TABLE_DATA_P.
2009-05-22 Mark Mitchell <mark@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.dg/falign-labels-1.c: New test.
Index: gcc/final.c
===================================================================
--- gcc/final.c (revision 147813)
+++ gcc/final.c (working copy)
@@ -901,6 +901,7 @@ shorten_branches (rtx first ATTRIBUTE_UN
if (LABEL_P (insn))
{
rtx next;
+ bool next_is_jumptable;
/* Merge in alignments computed by compute_alignments. */
log = LABEL_TO_ALIGNMENT (insn);
@@ -910,31 +911,30 @@ shorten_branches (rtx first ATTRIBUTE_UN
max_skip = LABEL_TO_MAX_SKIP (insn);
}
- log = LABEL_ALIGN (insn);
- if (max_log < log)
+ next = next_nonnote_insn (insn);
+ next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
+ if (!next_is_jumptable)
{
- max_log = log;
- max_skip = LABEL_ALIGN_MAX_SKIP;
+ log = LABEL_ALIGN (insn);
+ if (max_log < log)
+ {
+ max_log = log;
+ max_skip = LABEL_ALIGN_MAX_SKIP;
+ }
}
- next = next_nonnote_insn (insn);
/* 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)
- if (next && JUMP_P (next))
- {
- rtx nextbody = PATTERN (next);
- if (GET_CODE (nextbody) == ADDR_VEC
- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
- {
- log = ADDR_VEC_ALIGN (next);
- if (max_log < log)
- {
- max_log = log;
- max_skip = LABEL_ALIGN_MAX_SKIP;
- }
- }
- }
+ if ((JUMP_TABLES_IN_TEXT_SECTION
+ || readonly_data_section == text_section)
+ && next_is_jumptable)
+ {
+ log = ADDR_VEC_ALIGN (next);
+ if (max_log < log)
+ {
+ max_log = log;
+ max_skip = LABEL_ALIGN_MAX_SKIP;
+ }
+ }
LABEL_TO_ALIGNMENT (insn) = max_log;
LABEL_TO_MAX_SKIP (insn) = max_skip;
max_log = 0;
@@ -2023,48 +2023,41 @@ final_scan_insn (rtx insn, FILE *file, i
app_disable ();
next = next_nonnote_insn (insn);
- if (next != 0 && JUMP_P (next))
+ /* 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))
{
- rtx nextbody = PATTERN (next);
-
- /* 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 (GET_CODE (nextbody) == ADDR_VEC
- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
- {
#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
- /* In this case, the case vector is being moved by the
- target, so don't output the label at all. Leave that
- to the back end macros. */
+ /* In this case, the case vector is being moved by the
+ target, so don't output the label at all. Leave that
+ to the back end macros. */
#else
- if (! JUMP_TABLES_IN_TEXT_SECTION)
- {
- int log_align;
+ if (! JUMP_TABLES_IN_TEXT_SECTION)
+ {
+ int log_align;
- switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ switch_to_section (targetm.asm_out.function_rodata_section
+ (current_function_decl));
#ifdef ADDR_VEC_ALIGN
- log_align = ADDR_VEC_ALIGN (next);
+ log_align = ADDR_VEC_ALIGN (next);
#else
- log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+ log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
#endif
- ASM_OUTPUT_ALIGN (file, log_align);
- }
- else
- switch_to_section (current_function_section ());
+ ASM_OUTPUT_ALIGN (file, log_align);
+ }
+ else
+ 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),
+ next);
#else
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
#endif
#endif
- break;
- }
+ break;
}
if (LABEL_ALT_ENTRY_P (insn))
output_alternate_entry_point (file, insn);
Index: gcc/testsuite/gcc.dg/falign-labels-1.c
===================================================================
--- gcc/testsuite/gcc.dg/falign-labels-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/falign-labels-1.c (revision 0)
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-falign-labels=8" { target { ! { m68k*-*-* || fido*-*-* } } } } */
+
+/* On ARMv7-A CPUs, this test resulted in incorrect code generation.
+ The code generated for the switch statement expected the jump table
+ to immediately follow the jump instruction, but -falign-labels
+ caused the label preceding the table to be aligned. */
+/* M68K and fido only support -falign-labels argument <= 2. */
+
+volatile int x;
+
+int main(void)
+{
+ int y;
+
+ x = 0;
+
+ switch(x)
+ {
+ case 0:
+ y = 2 * x;
+ break;
+ case 1:
+ y = -3 * x;
+ break;
+ case 2:
+ y = x + 5;
+ break;
+ case 3:
+ y = x - 7;
+ break;
+ default:
+ break;
+ }
+
+ x = y;
+
+ return 0;
+}