diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cfglayout.c | 6 | ||||
-rw-r--r-- | gcc/final.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20050321-2.c | 54 |
5 files changed, 88 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a308f21..f5e1820 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-03-22 Jakub Jelinek <jakub@redhat.com> + + PR target/20561 + * cfglayout.c (reemit_insn_block_notes): Don't put block notes in + between jump table and its label. + * final.c (shorten_branches): Handle notes in between ADDR_VEC + resp. ADDR_DIFF_VEC and the label preceeding it. + (final_scan_insn): Likewise. Ensure ADDR_VEC resp. ADDR_DIFF_VEC + is emitted in the right section. + 2005-03-22 Kazu Hirata <kazu@cs.umass.edu> * fold-const.c (fold_unary, fold_binary): Update comments diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index 981bcd9..655c9a1 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -523,6 +523,12 @@ reemit_insn_block_notes (void) { tree this_block; + /* Avoid putting scope notes between jump table and its label. */ + if (JUMP_P (insn) + && (GET_CODE (PATTERN (insn)) == ADDR_VEC + || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)) + continue; + this_block = insn_scope (insn); /* For sequences compute scope resulting from merging all scopes of instructions nested inside. */ diff --git a/gcc/final.c b/gcc/final.c index bf5771a..9347efe 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -835,7 +835,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED) max_log = log; max_skip = LABEL_ALIGN_MAX_SKIP; } - next = NEXT_INSN (insn); + 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 || !HAVE_READONLY_DATA_SECTION) @@ -1677,6 +1677,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, #ifdef HAVE_cc0 rtx set; #endif + rtx next; insn_counter++; @@ -1932,10 +1933,11 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, fputs (ASM_APP_OFF, file); app_on = 0; } - if (NEXT_INSN (insn) != 0 - && JUMP_P (NEXT_INSN (insn))) + + next = next_nonnote_insn (insn); + if (next != 0 && JUMP_P (next)) { - rtx nextbody = PATTERN (NEXT_INSN (insn)); + 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 @@ -1956,7 +1958,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, targetm.asm_out.function_rodata_section (current_function_decl); #ifdef ADDR_VEC_ALIGN - log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn)); + log_align = ADDR_VEC_ALIGN (next); #else log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); #endif @@ -1967,7 +1969,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, #ifdef ASM_OUTPUT_CASE_LABEL ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), - NEXT_INSN (insn)); + next); #else targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn)); #endif @@ -2022,6 +2024,11 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, if (prescan > 0) break; + if (! JUMP_TABLES_IN_TEXT_SECTION) + targetm.asm_out.function_rodata_section (current_function_decl); + else + function_section (current_function_decl); + if (app_on) { fputs (ASM_APP_OFF, file); @@ -2157,7 +2164,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, { /* A delayed-branch sequence */ int i; - rtx next; if (prescan > 0) break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7222ef..8960528 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-22 Jakub Jelinek <jakub@redhat.com> + + PR target/20561 + * gcc.dg/20050321-2.c: New test. + 2005-03-22 Nathan Sidwell <nathan@codesourcery.com> PR c++/20465 diff --git a/gcc/testsuite/gcc.dg/20050321-2.c b/gcc/testsuite/gcc.dg/20050321-2.c new file mode 100644 index 0000000..ac31914 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20050321-2.c @@ -0,0 +1,54 @@ +/* This testcase could not assemble on ppc32, because the compiler assumed + the huge ADDR_DIFF_VEC will be emitted into rodata section, yet because + of some notes inserted between jump table's CODE_LABEL and the jump table + it ended up in the .text section and thus shorten_branches couldn't + figure out branch to lab is too far. */ +/* { dg-do link } */ +/* { dg-options "-g1 -fpic" } */ + +#define A(n) \ + case n##1: return n##1 * 131 + 63; \ + case n##3: return n##3 * 1231 + 182; \ + case n##5: return n##5 * 351 + 1; \ + case n##7: return n##7 * 312 + 61; \ + case n##9: return n##9 * 17 - 1; +#define B(n) \ +A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) \ +A(n##5) A(n##6) A(n##7) A(n##8) A(n##9) +#define C(n) \ +B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) \ +B(n##5) B(n##6) B(n##7) B(n##8) B(n##9) +#define D(n) \ +C(n##0) C(n##1) B(n##20) B(n##21) B(n##22) + +int +foo (int x) +{ + { +lab:; + int a = x; + while (a < 60000) + { + int b = a; + { + int c = b; + switch (c) + { + D(1) + default: break; + } + } + a += 10000; + if (a == 4168) + goto lab; + } + } + return x; +} + +int +main (void) +{ + foo (71); + return 0; +} |