*** empty log message ***
authorRichard Kenner <kenner@gcc.gnu.org>
Sun, 28 Jun 1992 10:10:54 +0000 (06:10 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Sun, 28 Jun 1992 10:10:54 +0000 (06:10 -0400)
From-SVN: r1318

14 files changed:
gcc/cse.c
gcc/expmed.c
gcc/flow.c
gcc/integrate.c
gcc/loop.c
gcc/reload1.c
gcc/reorg.c
gcc/rtl.c
gcc/rtl.h
gcc/stmt.c
gcc/toplev.c
gcc/tree.c
gcc/tree.h
gcc/varasm.c

index 6476549f1a6d4c04ad39fd572f507e8bb5b5f5ab..334d899ef429b9c0df6667313f46459b47b67599 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4327,10 +4327,32 @@ fold_rtx (x, insn)
          || (new = lookup_as_function (x, CONST_DOUBLE)) != 0)
        return new;
 
-      /* If this is a paradoxical SUBREG, we can't do anything with
-        it because we have no idea what value the extra bits would have.  */
+      /* If this is a paradoxical SUBREG, we have no idea what value the
+        extra bits would have.  However, if the operand is equivalent
+        to a SUBREG whose operand is the same as our mode, and all the
+        modes are within a word, we can just use the inner operand
+        because these SUBREGs just say how to treat the register.  */
+
       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
-       return x;
+       {
+         enum machine_mode imode = GET_MODE (SUBREG_REG (x));
+         struct table_elt *elt;
+
+         if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
+             && GET_MODE_SIZE (imode) <= UNITS_PER_WORD
+             && (elt = lookup (SUBREG_REG (x), HASH (SUBREG_REG (x), imode),
+                               imode)) != 0)
+           {
+             for (elt = elt->first_same_value;
+                  elt; elt = elt->next_same_value)
+               if (GET_CODE (elt->exp) == SUBREG
+                   && GET_MODE (SUBREG_REG (elt->exp)) == mode
+                   && exp_equiv_p (elt->exp, elt->exp, 1))
+                 return copy_rtx (SUBREG_REG (elt->exp));
+           }
+
+         return x;
+       }
 
       /* Fold SUBREG_REG.  If it changed, see if we can simplify the SUBREG.
         We might be able to if the SUBREG is extracting a single word in an
@@ -4364,7 +4386,12 @@ fold_rtx (x, insn)
         extra bits will be.  But we can find an equivalence for this SUBREG
         by folding that operation is the narrow mode.  This allows us to
         fold arithmetic in narrow modes when the machine only supports
-        word-sized arithmetic.  */
+        word-sized arithmetic.  
+
+        Also look for a case where we have a SUBREG whose operand is the
+        same as our result.  If both modes are smaller than a word, we
+        are simply interpreting a register in different modes and we
+        can use the inner value.  */
 
       if (GET_CODE (folded_arg0) == REG
          && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0)))
@@ -4430,6 +4457,13 @@ fold_rtx (x, insn)
                                                     op0, op1);
                }
 
+             else if (GET_CODE (elt->exp) == SUBREG
+                      && GET_MODE (SUBREG_REG (elt->exp)) == mode
+                      && (GET_MODE_SIZE (GET_MODE (folded_arg0))
+                          <= UNITS_PER_WORD)
+                      && exp_equiv_p (elt->exp, elt->exp, 1))
+               new = copy_rtx (SUBREG_REG (elt->exp));
+
              if (new)
                return new;
            }
index 9d0962e6bccd8107285a81df610c3b2ffd65075f..a251644669e3e7083fb175613b7e590fabe61c6e 100644 (file)
@@ -2782,6 +2782,12 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
          else
            op0 = subtarget;
 
+         /* If we want to keep subexpressions around, don't reuse our
+            last target.  */
+
+         if (preserve_subexpressions_p ())
+           subtarget = 0;
+
          /* Now normalize to the proper value in COMPARE_MODE.  Sometimes
             we don't have to do anything.  */
          if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
index bc19c92dfe1ed4491f7d5d1cd423f70a8d2d4848..bc036dd15d8c5a5a8bd85961dd2f3158f1ed5c61 100644 (file)
@@ -121,9 +121,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-extern int xmalloc ();
-extern void free ();
-
 /* List of labels that must never be deleted.  */
 extern rtx forced_labels;
 
index 367d76f631041bff4e657d453fd81a42576eb4a6..31a62bea438b255bea3232757c10db2830398918 100644 (file)
@@ -36,8 +36,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "obstack.h"
 #define        obstack_chunk_alloc     xmalloc
 #define        obstack_chunk_free      free
-extern int xmalloc ();
-extern void free ();
 
 extern struct obstack *function_maybepermanent_obstack;
 
index 237f43ca09f744e1a7d6502b0e769d790614e6b0..13bdcd89609290ca66faee01871bb3c4c03a5f9d 100644 (file)
@@ -193,8 +193,6 @@ extern struct obstack *rtl_obstack;
 #define obstack_chunk_free free
 
 extern char *oballoc ();
-extern int xmalloc ();
-extern void free ();
 \f
 /* During the analysis of a loop, a chain of `struct movable's
    is made to record all the movable insns found.
index c68473dca58fa7f350c1d0053f265c9a1657c4c9..26768dc7e2ded443cc781351a0bca8a180863287 100644 (file)
@@ -246,9 +246,6 @@ char *reload_firstobj;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-extern int xmalloc ();
-extern void free ();
-
 /* List of labels that must never be deleted.  */
 extern rtx forced_labels;
 \f
index 6af7a9132f75e113fa5f8cb60d352a115214078a..afdbb098063f80b6bc5f2b980f9fbe25242741d8 100644 (file)
@@ -129,9 +129,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-extern int xmalloc ();
-extern void free ();
-
 #ifndef ANNUL_IFTRUE_SLOTS
 #define eligible_for_annul_true(INSN, SLOTS, TRIAL) 0
 #endif
index 04bc39c4093ed967cc8832e3aabb277dd770c09a..c3f03575aeed091cae3ef96918f0f10e84a62191 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -26,8 +26,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "obstack.h"
 #define        obstack_chunk_alloc     xmalloc
 #define        obstack_chunk_free      free
-extern int xmalloc ();
-extern void free ();
 
 /* Obstack used for allocating RTL objects.
    Between functions, this is the permanent_obstack.
index a49029ed14a53cd57474adda0562a814bde2f3ad..923786f9942203613ae5335826aa00cc5ea4d915 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -526,6 +526,8 @@ extern char *note_insn_name[];
 \f
 /* Generally useful functions.  */
 
+extern char *xmalloc ();
+extern void free ();
 extern rtx rtx_alloc ();
 extern rtvec rtvec_alloc ();
 extern rtx find_reg_note ();
index 7abf935f407bf2f199c7e3d53c7b11ba4b68c936..a6d98e64f4df6125fb736d46c41304e263793e80 100644 (file)
@@ -54,9 +54,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define obstack_chunk_free free
 struct obstack stmt_obstack;
 
-extern int xmalloc ();
-extern void free ();
-
 /* Filename and line number of last line-number note,
    whether we actually emitted it or not.  */
 char *emit_filename;
index ad6e1e130d2c875539214d8a9fc3361666fa2f02..ab51d2f09c2dbf01e905b911fcf0333757f1b795 100644 (file)
@@ -1161,11 +1161,11 @@ botch (s)
 
 /* Same as `malloc' but report error if no memory available.  */
 
-int
+char *
 xmalloc (size)
      unsigned size;
 {
-  register int value = (int) malloc (size);
+  register char *value = (char *) malloc (size);
   if (value == 0)
     fatal ("virtual memory exhausted");
   return value;
@@ -1173,12 +1173,12 @@ xmalloc (size)
 
 /* Same as `realloc' but report error if no memory available.  */
 
-int
+char *
 xrealloc (ptr, size)
      char *ptr;
      int size;
 {
-  int result = realloc (ptr, size);
+  char *result = (char *) realloc (ptr, size);
   if (!result)
     fatal ("virtual memory exhausted");
   return result;
index a0ff3fefc1bc55cd456954d4b393bf9e418c7d9b..3d3149c0417be4a9bf13b7e8dfec5e1dbe08bcb5 100644 (file)
@@ -43,9 +43,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-extern int xmalloc ();
-extern void free ();
-
 /* Tree nodes of permanent duration are allocated in this obstack.
    They are the identifier nodes, and everything outside of
    the bodies and parameters of function definitions.  */
index 87effce790afe763e1628c28715506c30e73f9a6..a64826c04a2a3e625fee6797204d2e6c764c5f3f 100644 (file)
@@ -855,6 +855,8 @@ union tree_node
 extern char *oballoc ();
 extern char *permalloc ();
 extern char *savealloc ();
+extern char *xmalloc ();
+extern void free ();
 
 /* Lowest level primitive for allocating a node.
    The TREE_CODE is the only argument.  Contents are initialized
index 3e54ce8811de51b354e3362eec80c1f1b7a40ae0..6c25b9282b2c66b3c7335457e32a4015622bf747 100644 (file)
@@ -58,7 +58,6 @@ extern struct obstack *current_obstack;
 extern struct obstack *saveable_obstack;
 extern struct obstack permanent_obstack;
 #define obstack_chunk_alloc xmalloc
-extern int xmalloc ();
 
 /* Number for making the label on the next
    constant that is stored in memory.  */