From 9f2e9ac43b09713711d3f358a2ab4dbb86a925bb Mon Sep 17 00:00:00 2001 From: Zdenek Dvorak Date: Tue, 17 Jul 2007 05:56:40 +0200 Subject: [PATCH] re PR rtl-optimization/32773 (SH: ICE in create_pre_exit, at mode-switching.c:223) PR rtl-optimization/32773 * cfglayout.c (force_one_exit_fallthru): New function. (cfg_layout_finalize): Use it. * gcc.dg/pr32773.c: New test. From-SVN: r126700 --- gcc/ChangeLog | 6 ++++ gcc/cfglayout.c | 51 ++++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/pr32773.c | 11 ++++++++ 4 files changed, 73 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr32773.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab57f35fa51..7b7dee07815 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-07-17 Zdenek Dvorak + + PR rtl-optimization/32773 + * cfglayout.c (force_one_exit_fallthru): New function. + (cfg_layout_finalize): Use it. + 2007-07-16 Richard Guenther Uros Bizjak diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index be4b08767b9..e989344cd80 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -963,6 +963,56 @@ fixup_fallthru_exit_predecessor (void) bb->aux = NULL; } } + +/* In case there are more than one fallthru predecessors of exit, force that + there is only one. */ + +static void +force_one_exit_fallthru (void) +{ + edge e, predecessor = NULL; + bool more = false; + edge_iterator ei; + basic_block forwarder, bb; + + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) + if (e->flags & EDGE_FALLTHRU) + { + if (predecessor == NULL) + predecessor = e; + else + { + more = true; + break; + } + } + + if (!more) + return; + + /* Exit has several fallthru predecessors. Create a forwarder block for + them. */ + forwarder = split_edge (predecessor); + for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); ) + { + if (e->src == forwarder + || !(e->flags & EDGE_FALLTHRU)) + ei_next (&ei); + else + redirect_edge_and_branch_force (e, forwarder); + } + + /* Fix up the chain of blocks -- make FORWARDER immediately preceed the + exit block. */ + FOR_EACH_BB (bb) + { + if (bb->aux == NULL && bb != forwarder) + { + bb->aux = forwarder; + break; + } + } +} /* Return true in case it is possible to duplicate the basic block BB. */ @@ -1178,6 +1228,7 @@ cfg_layout_finalize (void) #ifdef ENABLE_CHECKING verify_flow_info (); #endif + force_one_exit_fallthru (); rtl_register_cfg_hooks (); if (reload_completed #ifdef HAVE_epilogue diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a645d92a0e4..cb178678f89 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-07-17 Zdenek Dvorak + + PR rtl-optimization/32773 + * gcc.dg/pr32773.c: New test. + 2007-07-16 Andrew Pinski * gcc.target/spu/intrinsics-1.c: Use dg-message to diff --git a/gcc/testsuite/gcc.dg/pr32773.c b/gcc/testsuite/gcc.dg/pr32773.c new file mode 100644 index 00000000000..ca5dd53fdf4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr32773.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fprofile-use" } */ +/* { dg-options "-O -m4 -fprofile-use" { target sh-*-* } } */ + +void foo (int *p) +{ + if (p) + *p = 0; +} /* { dg-message "note: \[^\n\]*execution counts estimated" } */ + +/* { dg-final { cleanup-coverage-files } } */