OSDN Git Service

Wed May 5 16:26:13 1999 Vladimir Makarov <vmakarov@tofu.to.cygnus.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 1999 13:30:51 +0000 (13:30 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 1999 13:30:51 +0000 (13:30 +0000)
* function.c (purge_addressof_replacements): Rename into
  purge_bitfield_addressof_replacements.
(purge_addressof_replacements): New variable.
(purge_addressof_1): Add code for changing addressof in notes for
  field values which are extracted by usage MEM with narrower mode.
(purge_addressof): Initialize purge_bitfield_addressof_replacements.

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

gcc/ChangeLog
gcc/function.c

index fb98a33..a56814c 100644 (file)
@@ -1,3 +1,12 @@
+Wed May  5 16:26:13 1999  Vladimir Makarov  <vmakarov@tofu.to.cygnus.com>
+
+       * function.c (purge_addressof_replacements): Rename into
+       purge_bitfield_addressof_replacements.
+       (purge_addressof_replacements): New variable.
+       (purge_addressof_1): Add code for changing addressof in notes for
+       field values which are extracted by usage MEM with narrower mode.
+       (purge_addressof): Initialize purge_bitfield_addressof_replacements.
+
 Wed May  5 07:40:02 1999  Nick Clifton  <nickc@cygnus.com>
 
        Patch from: Nick Burrett  <nick.burrett@btinternet.com>
index e6fb786..0937844 100644 (file)
@@ -3031,6 +3031,14 @@ put_addressof_into_stack (r, ht)
 
 /* List of replacements made below in purge_addressof_1 when creating
    bitfield insertions.  */
+static rtx purge_bitfield_addressof_replacements;
+
+/* List of replacements made below in purge_addressof_1 for patterns
+   (MEM (ADDRESSOF (REG ...))).  The key of the list entry is the
+   corresponding (ADDRESSOF (REG ...)) and value is a substitution for
+   the all pattern.  List PURGE_BITFIELD_ADDRESSOF_REPLACEMENTS is not
+   enough in complex cases, e.g. when some field values can be
+   extracted by usage MEM with narrower mode. */
 static rtx purge_addressof_replacements;
 
 /* Helper function for purge_addressof.  See if the rtx expression at *LOC
@@ -3110,51 +3118,54 @@ purge_addressof_1 (loc, insn, force, store, ht)
                 was replaced by.  */
              rtx tem;
 
-             for (tem = purge_addressof_replacements; tem != NULL_RTX;
+             for (tem = purge_bitfield_addressof_replacements;
+                  tem != NULL_RTX;
                   tem = XEXP (XEXP (tem, 1), 1))
-               {
-                 rtx y = XEXP (tem, 0);
-                 if (GET_CODE (y) == MEM
-                     && rtx_equal_p (XEXP (x, 0), XEXP (y, 0)))
-                   {
-                     /* It can happen that the note may speak of things in
-                        a wider (or just different) mode than the code did. 
-                        This is especially true of REG_RETVAL.  */
+               if (rtx_equal_p (x, XEXP (tem, 0)))
+                 {
+                   *loc = XEXP (XEXP (tem, 1), 0);
+                   return;
+                 }
 
-                     rtx z = XEXP (XEXP (tem, 1), 0);
-                     if (GET_MODE (x) != GET_MODE (y))
-                       {
-                         if (GET_CODE (z) == SUBREG && SUBREG_WORD (z) == 0)
-                           z = SUBREG_REG (z);
-
-                         /* ??? If we'd gotten into any of the really complex
-                            cases below, I'm not sure we can do a proper
-                            replacement.  Might we be able to delete the
-                            note in some cases?  */
-                         if (GET_MODE_SIZE (GET_MODE (x))
-                             < GET_MODE_SIZE (GET_MODE (y)))
-                           abort ();
-
-                         if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
-                             && (GET_MODE_SIZE (GET_MODE (x))
-                                 > GET_MODE_SIZE (GET_MODE (z))))
-                           {
-                             /* This can occur as a result in invalid
-                                pointer casts, e.g. float f; ... 
-                                *(long long int *)&f.
-                                ??? We could emit a warning here, but
-                                without a line number that wouldn't be
-                                very helpful.  */
-                             z = gen_rtx_SUBREG (GET_MODE (x), z, 0);
-                           }
-                         else
-                           z = gen_lowpart (GET_MODE (x), z);
-                       }
+             /* See comment for purge_addressof_replacements. */
+             for (tem = purge_addressof_replacements;
+                  tem != NULL_RTX;
+                  tem = XEXP (XEXP (tem, 1), 1))
+               if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
+                 {
+                   rtx z = XEXP (XEXP (tem, 1), 0);
 
-                     *loc = z;
-                     return;
-                   }
-               }
+                   if (GET_MODE (x) == GET_MODE (z)
+                       || (GET_CODE (XEXP (XEXP (tem, 1), 0)) != REG
+                           && GET_CODE (XEXP (XEXP (tem, 1), 0)) != SUBREG))
+                     abort ();
+
+                   /* It can happen that the note may speak of things
+                      in a wider (or just different) mode than the
+                      code did.  This is especially true of
+                      REG_RETVAL. */
+
+                   if (GET_CODE (z) == SUBREG && SUBREG_WORD (z) == 0)
+                     z = SUBREG_REG (z);
+                   
+                   if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+                       && (GET_MODE_SIZE (GET_MODE (x))
+                           > GET_MODE_SIZE (GET_MODE (z))))
+                     {
+                       /* This can occur as a result in invalid
+                          pointer casts, e.g. float f; ... 
+                          *(long long int *)&f.
+                          ??? We could emit a warning here, but
+                          without a line number that wouldn't be
+                          very helpful.  */
+                       z = gen_rtx_SUBREG (GET_MODE (x), z, 0);
+                     }
+                   else
+                     z = gen_lowpart (GET_MODE (x), z);
+
+                   *loc = z;
+                   return;
+                 }
 
              /* There should always be such a replacement.  */
              abort ();
@@ -3242,10 +3253,11 @@ purge_addressof_1 (loc, insn, force, store, ht)
 
              /* Remember the replacement so that the same one can be done
                 on the REG_NOTES.  */
-             purge_addressof_replacements
+             purge_bitfield_addressof_replacements
                = gen_rtx_EXPR_LIST (VOIDmode, x,
-                                    gen_rtx_EXPR_LIST (VOIDmode, val,
-                                                       purge_addressof_replacements));
+                                    gen_rtx_EXPR_LIST
+                                    (VOIDmode, val,
+                                     purge_bitfield_addressof_replacements));
 
              /* We replaced with a reg -- all done.  */
              return;
@@ -3255,10 +3267,24 @@ purge_addressof_1 (loc, insn, force, store, ht)
        {
          /* Remember the replacement so that the same one can be done
             on the REG_NOTES.  */
-         purge_addressof_replacements
-           = gen_rtx_EXPR_LIST (VOIDmode, x,
-                                gen_rtx_EXPR_LIST (VOIDmode, sub,
-                                                   purge_addressof_replacements));
+         if (GET_CODE (sub) == REG || GET_CODE (sub) == SUBREG)
+           {
+             rtx tem;
+
+             for (tem = purge_addressof_replacements;
+                  tem != NULL_RTX;
+                  tem = XEXP (XEXP (tem, 1), 1))
+               if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
+                 {
+                   XEXP (XEXP (tem, 1), 0) = sub;
+                   return;
+                 }
+             purge_addressof_replacements
+               = gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
+                          gen_rtx_EXPR_LIST (VOIDmode, sub,
+                                             purge_addressof_replacements));
+             return;
+           }
          goto restart;
        }
     give_up:;
@@ -3440,6 +3466,7 @@ purge_addressof (insns)
 
   /* Clean up.  */
   hash_table_free (&ht);
+  purge_bitfield_addressof_replacements = 0;
   purge_addressof_replacements = 0;
 }
 \f