[28/50] loop-iv.c:replace_single_def_regs
diff mbox

Message ID 87lhr58xvi.fsf@googlemail.com
State New
Headers show

Commit Message

Richard Sandiford Aug. 3, 2014, 2:13 p.m. UTC
gcc/
	* loop-iv.c: Include rtl-iter.h.
	(find_single_def_src): New function.
	(replace_single_def_regs): Turn from being a for_each_rtx callback
	to being a function that examines each subrtx itself.
	(replace_in_expr, simplify_using_initial_values): Update accordingly.

Comments

Jeff Law Aug. 5, 2014, 10:07 p.m. UTC | #1
On 08/03/14 08:13, Richard Sandiford wrote:
> gcc/
> 	* loop-iv.c: Include rtl-iter.h.
> 	(find_single_def_src): New function.
> 	(replace_single_def_regs): Turn from being a for_each_rtx callback
> 	to being a function that examines each subrtx itself.
> 	(replace_in_expr, simplify_using_initial_values): Update accordingly.
OK.
Jeff

Patch
diff mbox

Index: gcc/loop-iv.c
===================================================================
--- gcc/loop-iv.c	2014-08-03 11:25:09.905954113 +0100
+++ gcc/loop-iv.c	2014-08-03 11:25:27.978132785 +0100
@@ -62,6 +62,7 @@  Free Software Foundation; either version
 #include "df.h"
 #include "hash-table.h"
 #include "dumpfile.h"
+#include "rtl-iter.h"
 
 /* Possible return values of iv_get_reaching_def.  */
 
@@ -1397,33 +1398,27 @@  simple_rhs_p (rtx rhs)
     }
 }
 
-/* If REG has a single definition, replace it with its known value in EXPR.
-   Callback for for_each_rtx.  */
+/* If REGNO has a single definition, return its known value, otherwise return
+   null.  */
 
-static int
-replace_single_def_regs (rtx *reg, void *expr1)
+static rtx
+find_single_def_src (unsigned int regno)
 {
-  unsigned regno;
   df_ref adef;
   rtx set, src;
-  rtx *expr = (rtx *)expr1;
 
-  if (!REG_P (*reg))
-    return 0;
-
-  regno = REGNO (*reg);
   for (;;)
     {
       rtx note;
       adef = DF_REG_DEF_CHAIN (regno);
       if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
-	    || DF_REF_IS_ARTIFICIAL (adef))
-	return -1;
+	  || DF_REF_IS_ARTIFICIAL (adef))
+	return NULL_RTX;
 
       set = single_set (DF_REF_INSN (adef));
       if (set == NULL || !REG_P (SET_DEST (set))
 	  || REGNO (SET_DEST (set)) != regno)
-	return -1;
+	return NULL_RTX;
 
       note = find_reg_equal_equiv_note (DF_REF_INSN (adef));
 
@@ -1442,10 +1437,29 @@  replace_single_def_regs (rtx *reg, void
       break;
     }
   if (!function_invariant_p (src))
-    return -1;
+    return NULL_RTX;
+
+  return src;
+}
+
+/* If any registers in *EXPR that have a single definition, try to replace
+   them with the known-equivalent values.  */
 
-  *expr = simplify_replace_rtx (*expr, *reg, src);
-  return 1;
+static void
+replace_single_def_regs (rtx *expr)
+{
+  subrtx_var_iterator::array_type array;
+ repeat:
+  FOR_EACH_SUBRTX_VAR (iter, array, *expr, NONCONST)
+    {
+      rtx x = *iter;
+      if (REG_P (x))
+	if (rtx new_x = find_single_def_src (REGNO (x)))
+	  {
+	    *expr = simplify_replace_rtx (*expr, x, new_x);
+	    goto repeat;
+	  }
+    }
 }
 
 /* A subroutine of simplify_using_initial_values, this function examines INSN
@@ -1490,8 +1504,7 @@  replace_in_expr (rtx *expr, rtx dest, rt
   *expr = simplify_replace_rtx (*expr, dest, src);
   if (old == *expr)
     return;
-  while (for_each_rtx (expr, replace_single_def_regs, expr) != 0)
-    continue;
+  replace_single_def_regs (expr);
 }
 
 /* Checks whether A implies B.  */
@@ -1934,9 +1947,7 @@  simplify_using_initial_values (struct lo
 
   gcc_assert (op == UNKNOWN);
 
-  for (;;)
-    if (for_each_rtx (expr, replace_single_def_regs, expr) == 0)
-      break;
+  replace_single_def_regs (expr);
   if (CONSTANT_P (*expr))
     return;