]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gcse.c (find_avail_set): Follow chains of register-register copies.
authorBernd Schmidt <bernds@cygnus.co.uk>
Wed, 25 Aug 1999 04:24:36 +0000 (04:24 +0000)
committerJeff Law <law@gcc.gnu.org>
Wed, 25 Aug 1999 04:24:36 +0000 (22:24 -0600)
        * gcse.c (find_avail_set): Follow chains of register-register copies.
        Use oprs_not_set_p to guarantee that the returned value can be
        substituted.
        (cprop_insn): Don't verify the return value of find_avail_set with
        oprs_not_set_p.

From-SVN: r28835

gcc/ChangeLog
gcc/gcse.c

index cb72d95662752823eac4ad71db7198540066c4ec..9df927a19b231603f188fd8a8c0b915abeb1e9c1 100644 (file)
@@ -110,6 +110,12 @@ Tue Aug 24 09:32:07 1999  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
 Tue Aug 24 12:35:20 1999  Bernd Schmidt  <bernds@cygnus.co.uk>
 
+       * gcse.c (find_avail_set): Follow chains of register-register copies.
+       Use oprs_not_set_p to guarantee that the returned value can be
+       substituted.
+       (cprop_insn): Don't verify the return value of find_avail_set with
+       oprs_not_set_p.
+
        * gcse.c (cprop_jump): New function, broken out of cprop_insn.
        (cprop_cc0_jump): New function.
        (cprop_insn): Break out new function cprop_jump and use it.
index 36b376b68670a639ad9764143723c78f055a951e..f5fe9b9cd6f572b05a13b7946bdb4ade71f177c0 100644 (file)
@@ -3656,16 +3656,65 @@ find_avail_set (regno, insn)
      int regno;
      rtx insn;
 {
-  struct expr *set = lookup_set (regno, NULL_RTX);
+  /* SET1 contains the last set found that can be returned to the caller for
+     use in a substitution.  */
+  struct expr *set1 = 0;
+  /* Loops are not possible here.  To get a loop we would need two sets
+     available at the start of the block containing INSN.  ie we would
+     need two sets like this available at the start of the block:
+
+       (set (reg X) (reg Y))
+       (set (reg Y) (reg X))
+
+     This can not happen since the set of (reg Y) would have killed the
+     set of (reg X) making it unavailable at the start of this block.  */
+  while (1)
+     {
+      rtx src;
+      struct expr *set = lookup_set (regno, NULL_RTX);
+
+      /* Find a set that is available at the start of the block
+        which contains INSN.  */
+      while (set)
+       {
+         if (TEST_BIT (cprop_avin[BLOCK_NUM (insn)], set->bitmap_index))
+           break;
+         set = next_set (regno, set);
+       }
 
-  while (set)
-    {
-      if (TEST_BIT (cprop_avin[BLOCK_NUM (insn)], set->bitmap_index))
+      /* If no available set was found we've reached the end of the
+        (possibly empty) copy chain.  */
+      if (set == 0)
+       break;
+
+      if (GET_CODE (set->expr) != SET)
+       abort ();
+
+      src = SET_SRC (set->expr);
+
+      /* We know the set is available.
+        Now check that SRC is ANTLOC (i.e. none of the source operands
+        have changed since the start of the block).  
+
+         If the source operand changed, we may still use it for the next
+         iteration of this loop, but we may not use it for substitutions.  */
+      if (CONSTANT_P (src) || oprs_not_set_p (src, insn))
+       set1 = set;
+
+      /* If the source of the set is anything except a register, then
+        we have reached the end of the copy chain.  */
+      if (GET_CODE (src) != REG)
        break;
-      set = next_set (regno, set);
-    }
 
-  return set;
+      /* Follow the copy chain, ie start another iteration of the loop
+        and see if we have an available copy into SRC.  */
+      regno = REGNO (src);
+     }
+
+  /* SET1 holds the last set that was available and anticipatable at
+     INSN.  */
+  return set1;
 }
 
 /* Subroutine of cprop_insn that tries to propagate constants into
@@ -3875,27 +3924,21 @@ cprop_insn (insn, alter_jumps)
               && REGNO (src) >= FIRST_PSEUDO_REGISTER
               && REGNO (src) != regno)
        {
-         /* We know the set is available.
-            Now check that SET_SRC is ANTLOC (i.e. none of the source operands
-            have changed since the start of the block).  */
-         if (oprs_not_set_p (src, insn))
+         if (try_replace_reg (reg_used->reg_rtx, src, insn))
            {
-             if (try_replace_reg (reg_used->reg_rtx, src, insn))
+             changed = 1;
+             copy_prop_count++;
+             if (gcse_file != NULL)
                {
-                 changed = 1;
-                 copy_prop_count++;
-                 if (gcse_file != NULL)
-                   {
-                     fprintf (gcse_file, "COPY-PROP: Replacing reg %d in insn %d with reg %d\n",
-                              regno, INSN_UID (insn), REGNO (src));
-                   }
-
-                 /* The original insn setting reg_used may or may not now be
-                    deletable.  We leave the deletion to flow.  */
-                 /* FIXME: If it turns out that the insn isn't deletable,
-                    then we may have unnecessarily extended register lifetimes
-                    and made things worse.  */
+                 fprintf (gcse_file, "COPY-PROP: Replacing reg %d in insn %d with reg %d\n",
+                          regno, INSN_UID (insn), REGNO (src));
                }
+
+             /* The original insn setting reg_used may or may not now be
+                deletable.  We leave the deletion to flow.  */
+             /* FIXME: If it turns out that the insn isn't deletable,
+                then we may have unnecessarily extended register lifetimes
+                and made things worse.  */
            }
        }
     }