diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2007-07-17 05:56:40 +0200 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2007-07-17 03:56:40 +0000 |
commit | 9f2e9ac43b09713711d3f358a2ab4dbb86a925bb (patch) | |
tree | 4a7695fc9b2d11cc77b1801a9f85ca70199d8db4 /gcc/cfglayout.c | |
parent | 02634bb2873d57f5beda6c0f1633b8bfdbc08ffa (diff) | |
download | gcc-9f2e9ac43b09713711d3f358a2ab4dbb86a925bb.zip gcc-9f2e9ac43b09713711d3f358a2ab4dbb86a925bb.tar.gz gcc-9f2e9ac43b09713711d3f358a2ab4dbb86a925bb.tar.bz2 |
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
Diffstat (limited to 'gcc/cfglayout.c')
-rw-r--r-- | gcc/cfglayout.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index be4b087..e989344 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 |