diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-05-11 18:17:43 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-05-11 18:17:43 +0000 |
commit | dcb172b4aee2541920b5793aa338e40824f521b4 (patch) | |
tree | 1cb4796f120b34f94f9e016946901fdcba7136f8 /gcc | |
parent | 6834c43a3100068ce10f4b1b60c5bbb486e2a353 (diff) | |
download | gcc-dcb172b4aee2541920b5793aa338e40824f521b4.tar.gz |
PR middle-end/44071
* cfglayout.c (fixup_reorder_chain): Allow asm goto to have
no fallthru edge.
* cfgcleanup.c (try_optimize_cfg): When in cfglayout mode
optimizing away empty bb with no successors, move over its
footer chain to fallthru predecessor.
* cfgrtl.c (patch_jump_insn): Update also REG_LABEL_OPERAND.
(rtl_split_edge): For asm goto call patch_jump_insn even if
splitting fallthru edge.
* c-c++-common/asmgoto-4.c: New test.
* gcc.target/i386/pr44071.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159288 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 19 | ||||
-rw-r--r-- | gcc/cfglayout.c | 9 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asmgoto-4.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr44071.c | 103 |
7 files changed, 205 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 16f56b89d03..24f210b3cc6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2010-05-11 Jakub Jelinek <jakub@redhat.com> + PR middle-end/44071 + * cfglayout.c (fixup_reorder_chain): Allow asm goto to have + no fallthru edge. + * cfgcleanup.c (try_optimize_cfg): When in cfglayout mode + optimizing away empty bb with no successors, move over its + footer chain to fallthru predecessor. + * cfgrtl.c (patch_jump_insn): Update also REG_LABEL_OPERAND. + (rtl_split_edge): For asm goto call patch_jump_insn even if + splitting fallthru edge. + PR c++/44059 * config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use qnu_unique_object even for DECL_ONE_ONLY DECL_ARTIFICIAL !TREE_READONLY decls. diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index dc6c245b950..75f56519a26 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1999,6 +1999,25 @@ try_optimize_cfg (int mode) && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b)) { c = b->prev_bb; + if ((mode & CLEANUP_CFGLAYOUT) + && EDGE_COUNT (b->preds) > 0 + && b->il.rtl->footer + && BARRIER_P (b->il.rtl->footer)) + { + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, b->preds) + if (e->flags & EDGE_FALLTHRU) + { + if (e->src->il.rtl->footer == NULL) + { + e->src->il.rtl->footer = b->il.rtl->footer; + b->il.rtl->footer = NULL; + } + break; + } + } delete_basic_block (b); if (!(mode & CLEANUP_CFGLAYOUT)) changed = true; diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index 9d23b16c116..7ba289f1a58 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -1,5 +1,5 @@ /* Basic block reordering routines for the GNU compiler. - Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -861,8 +861,11 @@ fixup_reorder_chain (void) } else if (extract_asm_operands (PATTERN (bb_end_insn)) != NULL) { - /* If the old fallthru is still next, nothing to do. */ - if (bb->aux == e_fall->dest + /* If the old fallthru is still next or if + asm goto doesn't have a fallthru (e.g. when followed by + __builtin_unreachable ()), nothing to do. */ + if (! e_fall + || bb->aux == e_fall->dest || e_fall->dest == EXIT_BLOCK_PTR) continue; diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 7fb1873f53b..abdbf9d8598 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -994,6 +994,9 @@ patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb) && !find_reg_note (insn, REG_LABEL_TARGET, new_label)) add_reg_note (insn, REG_LABEL_TARGET, new_label); } + while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label)) + != NULL_RTX) + XEXP (note, 0) = new_label; } else { @@ -1407,7 +1410,22 @@ rtl_split_edge (edge edge_in) gcc_assert (redirected); } else - redirect_edge_succ (edge_in, bb); + { + if (edge_in->src != ENTRY_BLOCK_PTR) + { + /* For asm goto even splitting of fallthru edge might + need insn patching, as other labels might point to the + old label. */ + rtx last = BB_END (edge_in->src); + if (last + && JUMP_P (last) + && edge_in->dest != EXIT_BLOCK_PTR + && extract_asm_operands (PATTERN (last)) != NULL_RTX + && patch_jump_insn (last, before, bb)) + df_set_bb_dirty (edge_in->src); + } + redirect_edge_succ (edge_in, bb); + } return bb; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8a74fd13476..ee0fab84ca2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2010-05-11 Jakub Jelinek <jakub@redhat.com> + PR middle-end/44071 + * c-c++-common/asmgoto-4.c: New test. + * gcc.target/i386/pr44071.c: New test. + PR c++/44062 * c-c++-common/Wunused-var-7.c: New test. * g++.dg/warn/Wunused-var-9.C: New test. diff --git a/gcc/testsuite/c-c++-common/asmgoto-4.c b/gcc/testsuite/c-c++-common/asmgoto-4.c new file mode 100644 index 00000000000..4532bf196ee --- /dev/null +++ b/gcc/testsuite/c-c++-common/asmgoto-4.c @@ -0,0 +1,44 @@ +/* PR middle-end/44071 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +static inline int +f1 (void) +{ + asm goto ("" : : : : l1, l2); + __builtin_unreachable (); + l1: + return 1; + l2: + return 0; +} + +int +b1 (int x) +{ + if (f1 () || x == 6) + x = 1; + else + x = 2; + return x; +} + +static inline int +f2 (void) +{ + asm goto ("" : : : : l1, l2); + l1: + return 1; + l2: + return 0; +} + +int +b2 (int x) +{ + if (f2 () || x == 6) + x = 1; + else + x = 2; + return x; +} diff --git a/gcc/testsuite/gcc.target/i386/pr44071.c b/gcc/testsuite/gcc.target/i386/pr44071.c new file mode 100644 index 00000000000..514c5e2fd2c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr44071.c @@ -0,0 +1,103 @@ +/* PR middle-end/44071 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +static inline int +f1 (void) +{ + asm goto ("jmp %l[l1]" : : : : l1, l2); + __builtin_unreachable (); + l1: + return 1; + l2: + return 0; +} + +__attribute__((noinline)) int +b1 (int x) +{ + if (f1 () || x == 6) + x = 1; + else + x = 2; + return x; +} + +static inline int +f2 (void) +{ + asm goto ("jmp %l[l2]" : : : : l1, l2); + __builtin_unreachable (); + l1: + return 1; + l2: + return 0; +} + +__attribute__((noinline)) int +b2 (int x) +{ + if (f2 () || x == 6) + x = 1; + else + x = 2; + return x; +} + +static inline int +f3 (void) +{ + asm goto ("jmp %l[l1]" : : : : l1, l2); + l1: + return 1; + l2: + return 0; +} + +__attribute__((noinline)) int +b3 (int x) +{ + if (f3 () || x == 6) + x = 1; + else + x = 2; + return x; +} + +static inline int +f4 (void) +{ + asm goto ("jmp %l[l2]" : : : : l1, l2); + l1: + return 1; + l2: + return 0; +} + +__attribute__((noinline)) int +b4 (int x) +{ + if (f4 () || x == 6) + x = 1; + else + x = 2; + return x; +} + +extern void abort (void); + +int +main (void) +{ + int x; + asm ("" : "=r" (x) : "0" (0)); + if (b1 (x) != 1 || b1 (x + 6) != 1) + abort (); + if (b2 (x) != 2 || b2 (x + 6) != 1) + abort (); + if (b3 (x) != 1 || b3 (x + 6) != 1) + abort (); + if (b4 (x) != 2 || b4 (x + 6) != 1) + abort (); + return 0; +} |