aboutsummaryrefslogtreecommitdiff
path: root/gcc/fwprop.c
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-04-01 00:49:53 +0200
committerJeff Law <law@gcc.gnu.org>2017-03-31 16:49:53 -0600
commita5a9046deb1a43c09e53b7e406319ac7936c2e07 (patch)
treebf4be001d4d273f6547bada534c9faa1206afa85 /gcc/fwprop.c
parenteee3756de395ab6220f78b471a7cd877301455a2 (diff)
downloadgcc-a5a9046deb1a43c09e53b7e406319ac7936c2e07.zip
gcc-a5a9046deb1a43c09e53b7e406319ac7936c2e07.tar.gz
gcc-a5a9046deb1a43c09e53b7e406319ac7936c2e07.tar.bz2
re PR rtl-optimization/79405 (Infinite loop in fwprop)
PR rtl-optimization/79405 * fwprop.c (propagations_left): New variable. (forward_propagate_into): Decrement it. (fwprop_init): Initialize it. (fw_prop): If the variable has reached zero, stop propagating. (fwprop_addr): Ditto. gcc/testsuite/ PR rtl-optimization/79405 gcc.dg/pr79405.c: New testcase. From-SVN: r246627
Diffstat (limited to 'gcc/fwprop.c')
-rw-r--r--gcc/fwprop.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 285fb1a..0ab25ef 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -120,6 +120,13 @@ static vec<df_ref> use_def_ref;
static vec<df_ref> reg_defs;
static vec<df_ref> reg_defs_stack;
+/* The maximum number of propagations that are still allowed. If we do
+ more propagations than originally we had uses, we must have ended up
+ in a propagation loop, as in PR79405. Until the algorithm fwprop
+ uses can obviously not get into such loops we need a workaround like
+ this. */
+static int propagations_left;
+
/* The MD bitmaps are trimmed to include only live registers to cut
memory usage on testcases like insn-recog.c. Track live registers
in the basic block and do not perform forward propagation if the
@@ -1407,6 +1414,8 @@ forward_propagate_into (df_ref use)
if (forward_propagate_and_simplify (use, def_insn, def_set)
|| forward_propagate_subreg (use, def_insn, def_set))
{
+ propagations_left--;
+
if (cfun->can_throw_non_call_exceptions
&& find_reg_note (use_insn, REG_EH_REGION, NULL_RTX)
&& purge_dead_edges (DF_REF_BB (use)))
@@ -1434,6 +1443,8 @@ fwprop_init (void)
active_defs = XNEWVEC (df_ref, max_reg_num ());
if (flag_checking)
active_defs_check = sparseset_alloc (max_reg_num ());
+
+ propagations_left = DF_USES_TABLE_SIZE ();
}
static void
@@ -1480,6 +1491,9 @@ fwprop (void)
for (i = 0; i < DF_USES_TABLE_SIZE (); i++)
{
+ if (!propagations_left)
+ break;
+
df_ref use = DF_USES_GET (i);
if (use)
if (DF_REF_TYPE (use) == DF_REF_REG_USE
@@ -1540,6 +1554,9 @@ fwprop_addr (void)
end, and we'll go through them as well. */
for (i = 0; i < DF_USES_TABLE_SIZE (); i++)
{
+ if (!propagations_left)
+ break;
+
df_ref use = DF_USES_GET (i);
if (use)
if (DF_REF_TYPE (use) != DF_REF_REG_USE