OSDN Git Service

* loop-iv.c (replace_single_def_regs): Look for REG_EQUAL notes;
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 11:01:57 +0000 (11:01 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 11:01:57 +0000 (11:01 +0000)
follow chains of regs with a single definition, and allow expressions
that are function_invariant_p.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146700 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/loop-iv.c

index baa9d2c..2ac0131 100644 (file)
@@ -1,3 +1,9 @@
+2009-04-24  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * loop-iv.c (replace_single_def_regs): Look for REG_EQUAL notes;
+       follow chains of regs with a single definition, and allow expressions
+       that are function_invariant_p.
+
 2009-04-24  Paolo Bonzini  <bonzini@gnu.org>
 
        PR middle-end/39867
index 9403736..23ece7e 100644 (file)
@@ -1376,23 +1376,46 @@ replace_single_def_regs (rtx *reg, void *expr1)
 {
   unsigned regno;
   df_ref adef;
-  rtx set;
+  rtx set, src;
   rtx *expr = (rtx *)expr1;
 
   if (!REG_P (*reg))
     return 0;
 
   regno = REGNO (*reg);
-  adef = DF_REG_DEF_CHAIN (regno);
-  if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
-      || DF_REF_IS_ARTIFICIAL (adef))
-    return -1;
+  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;
+
+      set = single_set (DF_REF_INSN (adef));
+      if (set == NULL || !REG_P (SET_DEST (set))
+         || REGNO (SET_DEST (set)) != regno)
+       return -1;
 
-  set = single_set (DF_REF_INSN (adef));
-  if (set == NULL || SET_DEST (set) != *reg || !CONSTANT_P (SET_SRC (set)))
+      note = find_reg_equal_equiv_note (DF_REF_INSN (adef));
+
+      if (note && function_invariant_p (XEXP (note, 0)))
+       {
+         src = XEXP (note, 0);
+         break;
+       }
+      src = SET_SRC (set);
+
+      if (REG_P (src))
+       {
+         regno = REGNO (src);
+         continue;
+       }
+      break;
+    }
+  if (!function_invariant_p (src))
     return -1;
 
-  *expr = simplify_replace_rtx (*expr, *reg, SET_SRC (set));
+  *expr = simplify_replace_rtx (*expr, *reg, src);
   return 1;
 }