OSDN Git Service

* gcse.c (cprop_jump): Make use of REG_EQUAL notes on both
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 May 2003 01:16:33 +0000 (01:16 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 May 2003 01:16:33 +0000 (01:16 +0000)
setcc and jump, if they exist.  If substituted instruction
fails to validate, store current effort in a REG_EQUAL note.
(cprop_insn): Don't attempt further substitutions if the
current instruction has been deleted.
(local_cprop_pass): Likewise.

* jump.c (redirect_jump):  Also update REG_EQUAL note, if
one is attached to the jump instruction.
(invert_jump): Delete REG_EQUAL note on jump, if one exists.

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

gcc/ChangeLog
gcc/gcse.c
gcc/jump.c

index c5c1792..7eaa2e7 100644 (file)
@@ -1,3 +1,18 @@
+2003-05-20  Roger Sayle  <roger@eyesopen.com>
+           Kazu Hirata  <kazu@cs.umass.edu>
+           Joern Rennecke  <joern.rennecke@superh.com>
+
+       * gcse.c (cprop_jump):  Make use of REG_EQUAL notes on both
+       setcc and jump, if they exist.  If substituted instruction
+       fails to validate, store current effort in a REG_EQUAL note.
+       (cprop_insn): Don't attempt further substitutions if the
+       current instruction has been deleted.
+       (local_cprop_pass): Likewise.
+
+       * jump.c (redirect_jump):  Also update REG_EQUAL note, if
+       one is attached to the jump instruction.
+       (invert_jump): Delete REG_EQUAL note on jump, if one exists.
+
 2003-05-21  Danny Smith  <dannysmith@users.sourceforge.net>
 
        PR c++/9738
index db2fb57..8050dd1 100644 (file)
@@ -4089,28 +4089,42 @@ cprop_jump (bb, setcc, jump, from, src)
      rtx from;
      rtx src;
 {
-  rtx new, new_set;
+  rtx new, set_src, note_src;
   rtx set = pc_set (jump);
+  rtx note = find_reg_equal_equiv_note (jump);
 
-  /* First substitute in the INSN condition as the SET_SRC of the JUMP,
-     then substitute that given values in this expanded JUMP.  */
-  if (setcc != NULL
+  if (note)
+    {
+      note_src = XEXP (note, 0);
+      if (GET_CODE (note_src) == EXPR_LIST)
+       note_src = NULL_RTX;
+    }
+  else note_src = NULL_RTX;
+
+  /* Prefer REG_EQUAL notes except those containing EXPR_LISTs.  */
+  set_src = note_src ? note_src : SET_SRC (set);
+
+  /* First substitute the SETCC condition into the JUMP instruction,
+     then substitute that given values into this expanded JUMP.  */
+  if (setcc != NULL_RTX
       && !modified_between_p (from, setcc, jump)
       && !modified_between_p (src, setcc, jump))
     {
+      rtx setcc_src;
       rtx setcc_set = single_set (setcc);
-      new_set = simplify_replace_rtx (SET_SRC (set),
-                                     SET_DEST (setcc_set),
-                                     SET_SRC (setcc_set));
+      rtx setcc_note = find_reg_equal_equiv_note (setcc);
+      setcc_src = (setcc_note && GET_CODE (XEXP (setcc_note, 0)) != EXPR_LIST)
+               ? XEXP (setcc_note, 0) : SET_SRC (setcc_set);
+      set_src = simplify_replace_rtx (set_src, SET_DEST (setcc_set),
+                                     setcc_src);
     }
   else
-    new_set = set;
+    setcc = NULL_RTX;
 
-  new = simplify_replace_rtx (new_set, from, src);
+  new = simplify_replace_rtx (set_src, from, src);
 
-  /* If no simplification can be made, then try the next
-     register.  */
-  if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
+  /* If no simplification can be made, then try the next register.  */
+  if (rtx_equal_p (new, SET_SRC (set)))
     return 0;
 
   /* If this is now a no-op delete it, otherwise this must be a valid insn.  */
@@ -4120,11 +4134,27 @@ cprop_jump (bb, setcc, jump, from, src)
     {
       /* Ensure the value computed inside the jump insn to be equivalent
          to one computed by setcc.  */
-      if (setcc 
-         && modified_in_p (new, setcc))
+      if (setcc && modified_in_p (new, setcc))
        return 0;
       if (! validate_change (jump, &SET_SRC (set), new, 0))
-       return 0;
+       {
+         /* When (some) constants are not valid in a comparison, and there
+            are two registers to be replaced by constants before the entire
+            comparison can be folded into a constant, we need to keep
+            intermediate information in REG_EQUAL notes.  For targets with
+            separate compare insns, such notes are added by try_replace_reg.
+            When we have a combined compare-and-branch instruction, however,
+            we need to attach a note to the branch itself to make this
+            optimization work.  */
+
+         if (!rtx_equal_p (new, note_src))
+           set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new));
+         return 0;
+       }
+
+      /* Remove REG_EQUAL note after simplification.  */
+      if (note_src)
+       remove_note (jump, note);
 
       /* If this has turned into an unconditional jump,
         then put a barrier after it so that the unreachable
@@ -4261,6 +4291,8 @@ cprop_insn (insn, alter_jumps)
                  print_rtl (gcse_file, src);
                  fprintf (gcse_file, "\n");
                }
+             if (INSN_DELETED_P (insn))
+               return 1;
            }
        }
       else if (GET_CODE (src) == REG
@@ -4503,6 +4535,8 @@ local_cprop_pass (alter_jumps)
                    changed = true;
                    break;
                  }
+             if (INSN_DELETED_P (insn))
+               break;
            }
          while (reg_use_count);
        }
index f59fdbc..f15e2ab 100644 (file)
@@ -2074,6 +2074,7 @@ redirect_jump (jump, nlabel, delete_unused)
      int delete_unused;
 {
   rtx olabel = JUMP_LABEL (jump);
+  rtx note;
 
   if (nlabel == olabel)
     return 1;
@@ -2085,6 +2086,29 @@ redirect_jump (jump, nlabel, delete_unused)
   if (nlabel)
     ++LABEL_NUSES (nlabel);
 
+  /* Update labels in any REG_EQUAL note.  */
+  if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
+    {
+      if (nlabel && olabel)
+       {
+         rtx dest = XEXP (note, 0);
+
+         if (GET_CODE (dest) == IF_THEN_ELSE)
+           {
+             if (GET_CODE (XEXP (dest, 1)) == LABEL_REF
+                 && XEXP (XEXP (dest, 1), 0) == olabel)
+               XEXP (XEXP (dest, 1), 0) = nlabel;
+             if (GET_CODE (XEXP (dest, 2)) == LABEL_REF
+                 && XEXP (XEXP (dest, 2), 0) == olabel)
+               XEXP (XEXP (dest, 2), 0) = nlabel;
+           }
+         else
+           remove_note (jump, note);
+       }
+      else
+        remove_note (jump, note);
+    }
+
   /* If we're eliding the jump over exception cleanups at the end of a
      function, move the function end note so that -Wreturn-type works.  */
   if (olabel && nlabel
@@ -2201,6 +2225,11 @@ invert_jump (jump, nlabel, delete_unused)
 
   if (redirect_jump (jump, nlabel, delete_unused))
     {
+      /* Remove REG_EQUAL note if we have one.  */
+      rtx note = find_reg_note (jump, REG_EQUAL, NULL_RTX);
+      if (note)
+       remove_note (jump, note);
+
       invert_br_probabilities (jump);
 
       return 1;