rtlanal.c (operand_preference): Fix preference for objects.
authorJan Hubicka <hubicka@gcc.gnu.org>
Mon, 4 Jun 2001 18:04:36 +0000 (18:04 +0000)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 4 Jun 2001 18:04:36 +0000 (18:04 +0000)
* rtlanal.c (operand_preference): Fix preference for objects.

* gcse.c (handle_avail_expr): Be prepared to handle single_set
parallels.

* combine.c (if_then_else_cond): Use simplify_subreg instead
of operand_subword.
* integreate.c (sub_constants): Likewise.

* emit-rtl.c (constant_subword): Deprecate; remove most of code
and use simplify_gen_subreg.

Mon Jun  4 19:55:23 CEST 2001  Lars Brinkhoff  <lars@nocrew.org>

* sibcall.c (skip_copy_to_return_value): recognize the situation
when the called function's return value is copied into an
intermediate pseudo, and then into the calling functions return
value register.

From-SVN: r42864

gcc/ChangeLog
gcc/combine.c
gcc/config/i386/i386.c
gcc/emit-rtl.c
gcc/gcse.c
gcc/integrate.c
gcc/rtlanal.c
gcc/sibcall.c
gcc/simplify-rtx.c

index 23f4a2c292055aac3ea6afc9cf62728f0e6daca2..7498981726ca1767251bf1c690c3f31b2e0ce67e 100644 (file)
@@ -1,3 +1,30 @@
+Mon Jun  4 20:03:05 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * rtlanal.c (operand_preference): Fix preference for objects.
+
+Mon Jun  4 20:00:40 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * gcse.c (handle_avail_expr): Be prepared to handle single_set
+       parallels.
+
+Mon Jun  4 19:59:46 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * combine.c (if_then_else_cond): Use simplify_subreg instead
+       of operand_subword.
+       * integreate.c (sub_constants): Likewise.
+
+Mon Jun  4 19:59:12 CEST 2001  Jan Hubicka  <jh@suse.cz>
+       
+       * emit-rtl.c (constant_subword): Deprecate; remove most of code
+       and use simplify_gen_subreg.
+
+Mon Jun  4 19:55:23 CEST 2001  Lars Brinkhoff  <lars@nocrew.org>
+
+       * sibcall.c (skip_copy_to_return_value): recognize the situation
+       when the called function's return value is copied into an
+       intermediate pseudo, and then into the calling functions return
+       value register.
+
 Mon Jun  4 16:50:33 CEST 2001  Jan Hubicka  <jh@suse.cz>
 
        * simplify_rtx.c (simplify_subreg): Keep subregs on return values,
index e34ab2f3820b64d9964149ca0776291357e9ee9b..d3c70c31dccc5cb803076cfb18fd7b040f268e45 100644 (file)
@@ -7293,29 +7293,16 @@ if_then_else_cond (x, ptrue, pfalse)
        return cond0;
     }
 
-  /* If X is a normal SUBREG with both inner and outer modes integral,
-     we can narrow both the true and false values of the inner expression,
-     if there is a condition.  */
-  else if (code == SUBREG && GET_MODE_CLASS (mode) == MODE_INT
-          && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
-          && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
+  /* If X is a SUBREG, we can narrow both the true and false values
+     if the inner expression, if there is a condition.  */
+  else if (code == SUBREG
           && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
                                               &true0, &false0)))
     {
-      if ((GET_CODE (SUBREG_REG (x)) == REG
-          || GET_CODE (SUBREG_REG (x)) == MEM
-          || CONSTANT_P (SUBREG_REG (x)))
-         && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) > UNITS_PER_WORD
-         && (WORDS_BIG_ENDIAN || SUBREG_BYTE (x) >= UNITS_PER_WORD))
-       {
-         true0 = operand_subword (true0, SUBREG_BYTE (x) / UNITS_PER_WORD, 0,
-                                  GET_MODE (SUBREG_REG (x)));
-         false0 = operand_subword (false0, SUBREG_BYTE (x) / UNITS_PER_WORD, 0,
-                                   GET_MODE (SUBREG_REG (x)));
-       }
-      *ptrue = force_to_mode (true0, mode, ~(HOST_WIDE_INT) 0, NULL_RTX, 0);
-      *pfalse
-       = force_to_mode (false0, mode, ~(HOST_WIDE_INT) 0, NULL_RTX, 0);
+      *ptrue = simplify_gen_subreg (mode, true0,
+                                   GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
+      *pfalse = simplify_gen_subreg (mode, false0,
+                                    GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
 
       return cond0;
     }
index 4027019220cdd5d86a1063cd064021db12033f31..e352d073efddaf3c2c1615ff474bdf379a4845f1 100644 (file)
@@ -1414,7 +1414,7 @@ const248_operand (op, mode)
 int
 incdec_operand (op, mode)
      register rtx op;
-     enum machine_mode mode;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
 {
   /* On Pentium4, the inc and dec operations causes extra dependancy on flag
      registers, since carry flag is not set.  */
index 6c72a99902b5b63ad2b1d048517324be74de5f36..f7dec2874e23259f6e7a19db2dce64d898354a0c 100644 (file)
@@ -1430,7 +1430,10 @@ constant_subword (op, offset, mode)
    ??? This is still rather broken for some cases.  The problem for the
    moment is that all callers of this thing provide no 'goal mode' to
    tell us to work with.  This exists because all callers were written
-   in a word based SUBREG world.  */
+   in a word based SUBREG world.
+   Now use of this function can be deprecated by simplify_subreg in most
+   cases.
+ */
 
 rtx
 operand_subword (op, offset, validate_address, mode)
@@ -1439,6 +1442,7 @@ operand_subword (op, offset, validate_address, mode)
      int validate_address;
      enum machine_mode mode;
 {
+  rtx new;
   if (mode == VOIDmode)
     mode = GET_MODE (op);
 
@@ -1455,82 +1459,6 @@ operand_subword (op, offset, validate_address, mode)
       && (offset + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
     return const0_rtx;
 
-  switch (GET_CODE (op))
-    {
-    case REG:
-    case SUBREG:
-    case CONCAT:
-    case MEM:
-      break;
-
-    default:
-      /* The only remaining cases are when OP is a constant.  If the host and
-        target floating formats are the same, handling two-word floating
-        constants are easy.  Note that REAL_VALUE_TO_TARGET_{SINGLE,DOUBLE}
-        are defined as returning one or two 32 bit values, respectively,
-        and not values of BITS_PER_WORD bits.  */
-      return constant_subword (op, offset, mode);
-    }
-
-  /* If OP is already an integer word, return it.  */
-  if (GET_MODE_CLASS (mode) == MODE_INT
-      && GET_MODE_SIZE (mode) == UNITS_PER_WORD)
-    return op;
-
-  /* If OP is a REG or SUBREG, we can handle it very simply.  */
-  if (GET_CODE (op) == REG)
-    {
-      if (REGNO (op) < FIRST_PSEUDO_REGISTER)
-       {
-         int final_regno = REGNO (op) +
-           subreg_regno_offset (REGNO (op), GET_MODE (op),
-                               offset * UNITS_PER_WORD,
-                               word_mode);
-
-         /* If the register is not valid for MODE, return 0.  If we don't
-            do this, there is no way to fix up the resulting REG later.  */
-         if (! HARD_REGNO_MODE_OK (final_regno, word_mode))
-           return 0;
-
-         /* integrate.c can't handle parts of a return value register.
-            ??? Then integrate.c should be fixed!
-            ??? What about CLASS_CANNOT_CHANGE_SIZE?  */
-         if ((! REG_FUNCTION_VALUE_P (op)
-              || ! rtx_equal_function_value_matters)
-             /* ??? What about CLASS_CANNOT_CHANGE_SIZE?  */
-             /* We want to keep the stack, frame, and arg pointers
-                special.  */
-             && op != frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-             && op != arg_pointer_rtx
-#endif
-             && op != stack_pointer_rtx)
-           return gen_rtx_REG (word_mode, final_regno);
-       }
-
-      /* Just return a normal SUBREG.  */
-      return gen_rtx_SUBREG (word_mode, op,
-                            (offset * UNITS_PER_WORD));
-    }
-  else if (GET_CODE (op) == SUBREG)
-    {
-      int final_offset = ((offset * UNITS_PER_WORD) + SUBREG_BYTE (op));
-
-      /* When working with SUBREGs the rule is that the byte
-        offset must be a multiple of the SUBREG's mode.  */
-      final_offset = (final_offset / GET_MODE_SIZE (word_mode));
-      final_offset = (final_offset * GET_MODE_SIZE (word_mode));
-      return gen_rtx_SUBREG (word_mode, SUBREG_REG (op), final_offset);
-    }
-  else if (GET_CODE (op) == CONCAT)
-    {
-      unsigned int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
-      if (offset < partwords)
-       return operand_subword (XEXP (op, 0), offset, validate_address, mode);
-      return operand_subword (XEXP (op, 1), offset - partwords,
-                             validate_address, mode);
-    }
-
   /* Form a new MEM at the requested address.  */
   if (GET_CODE (op) == MEM)
     {
@@ -1553,8 +1481,8 @@ operand_subword (op, offset, validate_address, mode)
       return new;
     }
 
-  /* Unreachable... (famous last words) */
-  abort ();
+  /* Rest can be handled by simplify_subreg.  */
+  return simplify_gen_subreg (word_mode, op, mode, (offset * UNITS_PER_WORD));
 }
 
 /* Similar to `operand_subword', but never return 0.  If we can't extract
index 2b1bdee68b3eead9f950619e92c4b4b1d57672d7..82f2787c6a3cdd599ffe33a5ae79b375e6ce3d71 100644 (file)
@@ -3472,7 +3472,7 @@ handle_avail_expr (insn, expr)
      rtx insn;
      struct expr *expr;
 {
-  rtx pat, insn_computes_expr;
+  rtx pat, insn_computes_expr, expr_set;
   rtx to;
   struct reg_set *this_reg;
   int found_setting, use_src;
@@ -3483,6 +3483,9 @@ handle_avail_expr (insn, expr)
   insn_computes_expr = computing_insn (expr, insn);
   if (insn_computes_expr == NULL)
     return 0;
+  expr_set = single_set (insn_computes_expr);
+  if (!expr_set)
+    abort ();
 
   found_setting = 0;
   use_src = 0;
@@ -3490,12 +3493,12 @@ handle_avail_expr (insn, expr)
   /* At this point we know only one computation of EXPR outside of this
      block reaches this insn.  Now try to find a register that the
      expression is computed into.  */
-  if (GET_CODE (SET_SRC (PATTERN (insn_computes_expr))) == REG)
+  if (GET_CODE (SET_SRC (expr_set)) == REG)
     {
       /* This is the case when the available expression that reaches
         here has already been handled as an available expression.  */
       unsigned int regnum_for_replacing
-       = REGNO (SET_SRC (PATTERN (insn_computes_expr)));
+       = REGNO (SET_SRC (expr_set));
 
       /* If the register was created by GCSE we can't use `reg_set_table',
         however we know it's set only once.  */
@@ -3514,7 +3517,7 @@ handle_avail_expr (insn, expr)
   if (!found_setting)
     {
       unsigned int regnum_for_replacing
-       = REGNO (SET_DEST (PATTERN (insn_computes_expr)));
+       = REGNO (SET_DEST (expr_set));
 
       /* This shouldn't happen.  */
       if (regnum_for_replacing >= max_gcse_regno)
@@ -3533,9 +3536,9 @@ handle_avail_expr (insn, expr)
     {
       pat = PATTERN (insn);
       if (use_src)
-       to = SET_SRC (PATTERN (insn_computes_expr));
+       to = SET_SRC (expr_set);
       else
-       to = SET_DEST (PATTERN (insn_computes_expr));
+       to = SET_DEST (expr_set);
       changed = validate_change (insn, &SET_SRC (pat), to, 0);
 
       /* We should be able to ignore the return code from validate_change but
@@ -3563,15 +3566,14 @@ handle_avail_expr (insn, expr)
         replace all uses of REGB with REGN.  */
       rtx new_insn;
 
-      to = gen_reg_rtx (GET_MODE (SET_DEST (PATTERN (insn_computes_expr))));
+      to = gen_reg_rtx (GET_MODE (SET_DEST (expr_set)));
 
       /* Generate the new insn.  */
       /* ??? If the change fails, we return 0, even though we created
         an insn.  I think this is ok.  */
       new_insn
        = emit_insn_after (gen_rtx_SET (VOIDmode, to,
-                                       SET_DEST (PATTERN
-                                                 (insn_computes_expr))),
+                                       SET_DEST (expr_set)),
                           insn_computes_expr);
 
       /* Keep block number table up to date.  */
index 9b7a4e74d5100219910d835ff6b981b10f2336ca..ff9d33f20c41c0ed0e19f71d12020fac0612eb7f 100644 (file)
@@ -2411,19 +2411,14 @@ subst_constants (loc, insn, map, memonly)
             valid.  We handle two cases: extracting a full word in an
             integral mode and extracting the low part.  */
          subst_constants (&inner, NULL_RTX, map, 0);
-
-         if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
-             && GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD
-             && GET_MODE (SUBREG_REG (x)) != VOIDmode)
-           new = operand_subword (inner, SUBREG_BYTE (x) / UNITS_PER_WORD,
-                                  0, GET_MODE (SUBREG_REG (x)));
-
-         cancel_changes (num_changes);
-         if (new == 0 && subreg_lowpart_p (x))
-           new = gen_lowpart_common (GET_MODE (x), inner);
+         new = simplify_gen_subreg (GET_MODE (x), inner,
+                                    GET_MODE (SUBREG_REG (x)),
+                                    SUBREG_BYTE (x));
 
          if (new)
            validate_change (insn, loc, new, 1);
+         else
+           cancel_changes (num_changes);
 
          return;
        }
index 0f0f6cd1fc54643e7f7a27a2f2b3c06d931605c2..ca144159cec511f4b35d010cf904230037e3394d 100644 (file)
@@ -2515,16 +2515,16 @@ operand_preference (op)
 {
   /* Constants always come the second operand.  Prefer "nice" constants.  */
   if (GET_CODE (op) == CONST_INT)
-    return -4;
+    return -5;
   if (GET_CODE (op) == CONST_DOUBLE)
-    return -3;
+    return -4;
   if (CONSTANT_P (op))
-    return -2;
+    return -3;
 
   /* SUBREGs of objects should come second.  */
   if (GET_CODE (op) == SUBREG
       && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o')
-    return -1;
+    return -2;
 
   /* If only one operand is a `neg', `not',
     `mult', `plus', or `minus' expression, it will be the first
@@ -2534,9 +2534,10 @@ operand_preference (op)
       || GET_CODE (op) == MINUS)
     return 2;
 
-  /* Complex expressions should be the first.  */
+  /* Complex expressions should be the first, so decrease priority
+     of objects.  */
   if (GET_RTX_CLASS (GET_CODE (op)) == 'o')
-    return 1;
+    return -1;
   return 0;
 }
 
index 13f9c1f0069a8f512b617f8e6c67bc62362bb8d9..53ce4317c960ed6bf048b15a8793d0a4ed31868a 100644 (file)
@@ -169,6 +169,30 @@ skip_copy_to_return_value (orig_insn)
       && SET_SRC (set) == softret)
     return insn;
 
+  /* Recognize the situation when the called function's return value
+     is copied in two steps: first into an intermediate pseudo, then
+     the into the calling functions return value register.  */
+
+  if (REG_P (SET_DEST (set))
+      && SET_SRC (set) == softret)
+    {
+      rtx x = SET_DEST (set);
+
+      insn = next_nonnote_insn (insn);
+      if (! insn)
+       return orig_insn;
+
+      set = single_set (insn);
+      if (! set)
+       return orig_insn;
+
+      if (SET_DEST (set) == current_function_return_rtx
+         && REG_P (SET_DEST (set))
+         && OUTGOING_REGNO (REGNO (SET_DEST (set))) == REGNO (hardret)
+         && SET_SRC (set) == x)
+       return insn;
+    }
+
   /* It did not look like a copy of the return value, so return the
      same insn we were passed.  */
   return orig_insn;
index aef9b55e20706d81e921daacd376ba1ead85182d..574513f59357da8f5927df15c3af8834d0c00334 100644 (file)
@@ -2227,9 +2227,9 @@ simplify_subreg (outermode, op, innermode, byte)
          && GET_MODE_SIZE (innermode) > UNITS_PER_WORD
          && GET_MODE_CLASS (outermode) == MODE_INT)
        {
-         rtx new = operand_subword (op,
-                                    (byte / UNITS_PER_WORD),
-                                    0, innermode);
+         rtx new = constant_subword (op,
+                                     (byte / UNITS_PER_WORD),
+                                     innermode);
          if (new)
            return new;
        }