rtlanal.c (set_of_1): New static function.
authorJan Hubicka <jh@suse.cz>
Sun, 7 Jan 2001 13:06:43 +0000 (14:06 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 7 Jan 2001 13:06:43 +0000 (13:06 +0000)
* rtlanal.c (set_of_1): New static function.
(reg_set_last_1, reg_set_p_1, reg_set_reg, reg_set_flag,
 reg_set_last_unknown, reg_set_last_value, reg_set_last_first_regno,
 reg_set_last_last_regno): Remove.
(set_of): New global function.
(set_of_data): New structure.
(reg_set_p, reg_set_last): Revamp for set_of.
* rtl.h (set_of): New.

From-SVN: r38772

gcc/ChangeLog
gcc/rtl.h
gcc/rtlanal.c

index 2aa50d0edecb4d1a7a03837328c69034ed2e2633..887605c45c781fa9b092c85675ccab279e36ee05 100644 (file)
@@ -1,3 +1,14 @@
+Sun Jan  7 13:49:19 MET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * rtlanal.c (set_of_1): New static function.
+       (reg_set_last_1, reg_set_p_1, reg_set_reg, reg_set_flag,
+        reg_set_last_unknown, reg_set_last_value, reg_set_last_first_regno,
+        reg_set_last_last_regno): Remove.
+       (set_of): New global function.
+       (set_of_data): New structure.
+       (reg_set_p, reg_set_last): Revamp for set_of.
+       * rtl.h (set_of): New.
+
 2001-01-07  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * c-common.c (c_common_nodes_and_builtins): Add _Exit builtin.
index 972dbd48d7cef8f9d4d72d570c950d5e8cbb4e97..6e2aee68c07b532c43316f46b44825f8f145f03d 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1378,6 +1378,7 @@ extern rtx find_last_value                PARAMS ((rtx, rtx *, rtx, int));
 extern int refers_to_regno_p           PARAMS ((unsigned int, unsigned int,
                                                 rtx, rtx *));
 extern int reg_overlap_mentioned_p     PARAMS ((rtx, rtx));
+extern rtx set_of                      PARAMS ((rtx, rtx));
 extern void note_stores                        PARAMS ((rtx,
                                                 void (*) (rtx, rtx, void *),
                                                 void *));
index b0fbcf31063902c2dcfeaac01cdd67f9db28d153..d58f392cc0cbad209526b56705763b41f960c522 100644 (file)
@@ -25,10 +25,8 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "rtl.h"
 
-static void reg_set_p_1                PARAMS ((rtx, rtx, void *));
+static void set_of_1           PARAMS ((rtx, rtx, void *));
 static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
-static void reg_set_last_1     PARAMS ((rtx, rtx, void *));
-
 
 /* Forward declarations */
 static int jmp_uses_reg_or_mem         PARAMS ((rtx));
@@ -617,24 +615,6 @@ reg_set_between_p (reg, from_insn, to_insn)
 }
 
 /* Internals of reg_set_between_p.  */
-
-static rtx reg_set_reg;
-static int reg_set_flag;
-
-static void
-reg_set_p_1 (x, pat, data)
-     rtx x;
-     rtx pat ATTRIBUTE_UNUSED;
-     void *data ATTRIBUTE_UNUSED;
-{
-  /* We don't want to return 1 if X is a MEM that contains a register
-     within REG_SET_REG.  */
-
-  if ((GET_CODE (x) != MEM)
-      && reg_overlap_mentioned_p (reg_set_reg, x))
-    reg_set_flag = 1;
-}
-
 int
 reg_set_p (reg, insn)
      rtx reg, insn;
@@ -662,10 +642,7 @@ reg_set_p (reg, insn)
       body = PATTERN (insn);
     }
 
-  reg_set_reg = reg;
-  reg_set_flag = 0;
-  note_stores (body, reg_set_p_1, NULL);
-  return reg_set_flag;
+  return set_of (reg, insn) != NULL_RTX;
 }
 
 /* Similar to reg_set_between_p, but check all registers in X.  Return 0
@@ -863,6 +840,38 @@ insn_dependent_p_1 (x, pat, data)
     *pinsn = NULL_RTX;
 }
 \f
+/* Helper function for set_of.  */
+struct set_of_data
+  {
+    rtx found;
+    rtx pat;
+  };
+
+static void
+set_of_1 (x, pat, data1)
+     rtx x;
+     rtx pat;
+     void *data1;
+{
+   struct set_of_data *data = (struct set_of_data *) (data1);
+   if (rtx_equal_p (x, data->pat)
+       || (GET_CODE (x) != MEM && reg_overlap_mentioned_p (data->pat, x)))
+     data->found = pat;
+}
+
+/* Give an INSN, return a SET or CLOBBER expression that does modify PAT
+   (eighter directly or via STRICT_LOW_PART and similar modifiers).  */
+rtx
+set_of (pat, insn)
+     rtx pat, insn;
+{
+  struct set_of_data data;
+  data.found = NULL_RTX;
+  data.pat = pat;
+  note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data);
+  return data.found;
+}
+\f
 /* Given an INSN, return a SET expression if this insn has only a single SET.
    It may also have CLOBBERs, USEs, or SET whose output
    will not be used, which we ignore.  */
@@ -1196,45 +1205,6 @@ reg_overlap_mentioned_p (x, in)
   abort ();
 }
 \f
-/* Used for communications between the next few functions.  */
-
-static int reg_set_last_unknown;
-static rtx reg_set_last_value;
-static unsigned int reg_set_last_first_regno, reg_set_last_last_regno;
-
-/* Called via note_stores from reg_set_last.  */
-
-static void
-reg_set_last_1 (x, pat, data)
-     rtx x;
-     rtx pat;
-     void *data ATTRIBUTE_UNUSED;
-{
-  unsigned int first, last;
-
-  /* If X is not a register, or is not one in the range we care
-     about, ignore.  */
-  if (GET_CODE (x) != REG)
-    return;
-
-  first = REGNO (x);
-  last = first + (first < FIRST_PSEUDO_REGISTER
-                 ? HARD_REGNO_NREGS (first, GET_MODE (x)) : 1);
-
-  if (first >= reg_set_last_last_regno
-      || last <= reg_set_last_first_regno)
-    return;
-
-  /* If this is a CLOBBER or is some complex LHS, or doesn't modify
-     exactly the registers we care about, show we don't know the value.  */
-  if (GET_CODE (pat) == CLOBBER || SET_DEST (pat) != x
-      || first != reg_set_last_first_regno
-      || last != reg_set_last_last_regno)
-    reg_set_last_unknown = 1;
-  else
-    reg_set_last_value = SET_SRC (pat);
-}
-
 /* Return the last value to which REG was set prior to INSN.  If we can't
    find it easily, return 0.
 
@@ -1248,16 +1218,6 @@ reg_set_last (x, insn)
 {
   rtx orig_insn = insn;
 
-  reg_set_last_first_regno = REGNO (x);
-
-  reg_set_last_last_regno
-    = reg_set_last_first_regno
-      + (reg_set_last_first_regno < FIRST_PSEUDO_REGISTER
-        ? HARD_REGNO_NREGS (reg_set_last_first_regno, GET_MODE (x)) : 1);
-
-  reg_set_last_unknown = 0;
-  reg_set_last_value = 0;
-
   /* Scan backwards until reg_set_last_1 changed one of the above flags.
      Stop when we reach a label or X is a hard reg and we reach a
      CALL_INSN (if reg_set_last_last_regno is a hard reg).
@@ -1269,21 +1229,24 @@ reg_set_last (x, insn)
   for (;
        insn && GET_CODE (insn) != CODE_LABEL
        && ! (GET_CODE (insn) == CALL_INSN
-            && reg_set_last_last_regno <= FIRST_PSEUDO_REGISTER);
+            && REGNO (x) <= FIRST_PSEUDO_REGISTER);
        insn = PREV_INSN (insn))
     if (INSN_P (insn))
       {
-       note_stores (PATTERN (insn), reg_set_last_1, NULL);
-       if (reg_set_last_unknown)
-         return 0;
-       else if (reg_set_last_value)
+       rtx set = set_of (x, insn);
+       /* OK, this function modify our register.  See if we understand it.  */
+       if (set)
          {
-           if (CONSTANT_P (reg_set_last_value)
-               || ((GET_CODE (reg_set_last_value) == REG
-                    || GET_CODE (reg_set_last_value) == SUBREG)
-                   && ! reg_set_between_p (reg_set_last_value,
+           rtx last_value;
+           if (GET_CODE (set) != SET || SET_DEST (set) != x)
+             return 0;
+           last_value = SET_SRC (x);
+           if (CONSTANT_P (last_value)
+               || ((GET_CODE (last_value) == REG
+                    || GET_CODE (last_value) == SUBREG)
+                   && ! reg_set_between_p (last_value,
                                            insn, orig_insn)))
-             return reg_set_last_value;
+             return last_value;
            else
              return 0;
          }