aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-pre.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r--gcc/tree-ssa-pre.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 83b48df..c985e79 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-prop.h"
#include "tree-ssa-propagate.h"
#include "ipa-utils.h"
+#include "tree-cfgcleanup.h"
/* TODO:
@@ -3922,6 +3923,7 @@ compute_avail (void)
/* Local state for the eliminate domwalk. */
static vec<gimple> el_to_remove;
+static vec<gimple> el_to_fixup;
static unsigned int el_todo;
static vec<tree> el_avail;
static vec<tree> el_avail_stack;
@@ -4429,7 +4431,7 @@ eliminate_dom_walker::before_dom_children (basic_block b)
/* When changing a call into a noreturn call, cfg cleanup
is needed to fix up the noreturn call. */
if (!was_noreturn && gimple_call_noreturn_p (stmt))
- el_todo |= TODO_cleanup_cfg;
+ el_to_fixup.safe_push (stmt);
}
else
{
@@ -4529,6 +4531,7 @@ eliminate (bool do_pre)
need_ab_cleanup = BITMAP_ALLOC (NULL);
el_to_remove.create (0);
+ el_to_fixup.create (0);
el_todo = 0;
el_avail.create (num_ssa_names);
el_avail_stack.create (0);
@@ -4580,6 +4583,25 @@ eliminate (bool do_pre)
}
el_to_remove.release ();
+ /* Fixup stmts that became noreturn calls. This may require splitting
+ blocks and thus isn't possible during the dominator walk. Do this
+ in reverse order so we don't inadvertedly remove a stmt we want to
+ fixup by visiting a dominating now noreturn call first. */
+ while (!el_to_fixup.is_empty ())
+ {
+ stmt = el_to_fixup.pop ();
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Fixing up noreturn call ");
+ print_gimple_stmt (dump_file, stmt, 0, 0);
+ }
+
+ if (fixup_noreturn_call (stmt))
+ el_todo |= TODO_cleanup_cfg;
+ }
+ el_to_fixup.release ();
+
return el_todo;
}