OSDN Git Service

* calls.c (expand_call): Convert structure_value_addr to Pmode if
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index 8345613..79ce9a1 100644 (file)
@@ -369,9 +369,7 @@ static int (*offsets_at)[NUM_ELIMINABLE_REGS];
 
 static int num_labels;
 \f
-static void replace_pseudos_in_call_usage      PARAMS ((rtx *,
-                                                        enum machine_mode,
-                                                        rtx));
+static void replace_pseudos_in PARAMS ((rtx *, enum machine_mode, rtx));
 static void maybe_fix_stack_asms       PARAMS ((void));
 static void copy_reloads               PARAMS ((struct insn_chain *));
 static void calculate_needs_all_insns  PARAMS ((int));
@@ -583,7 +581,7 @@ compute_use_by_pseudos (to, from)
    equivalences.  */
 
 static void
-replace_pseudos_in_call_usage (loc, mem_mode, usage)
+replace_pseudos_in (loc, mem_mode, usage)
      rtx *loc;
      enum machine_mode mem_mode;
      rtx usage;
@@ -608,7 +606,7 @@ replace_pseudos_in_call_usage (loc, mem_mode, usage)
       if (x != *loc)
        {
          *loc = x;
-         replace_pseudos_in_call_usage (loc, mem_mode, usage);
+         replace_pseudos_in (loc, mem_mode, usage);
          return;
        }
 
@@ -628,7 +626,7 @@ replace_pseudos_in_call_usage (loc, mem_mode, usage)
     }
   else if (code == MEM)
     {
-      replace_pseudos_in_call_usage (& XEXP (x, 0), GET_MODE (x), usage);
+      replace_pseudos_in (& XEXP (x, 0), GET_MODE (x), usage);
       return;
     }
 
@@ -636,10 +634,10 @@ replace_pseudos_in_call_usage (loc, mem_mode, usage)
   fmt = GET_RTX_FORMAT (code);
   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
     if (*fmt == 'e')
-      replace_pseudos_in_call_usage (&XEXP (x, i), mem_mode, usage);
+      replace_pseudos_in (&XEXP (x, i), mem_mode, usage);
     else if (*fmt == 'E')
       for (j = 0; j < XVECLEN (x, i); j++)
-       replace_pseudos_in_call_usage (& XVECEXP (x, i, j), mem_mode, usage);
+       replace_pseudos_in (& XVECEXP (x, i, j), mem_mode, usage);
 }
 
 \f
@@ -1192,9 +1190,8 @@ reload (first, global)
        rtx *pnote;
 
        if (GET_CODE (insn) == CALL_INSN)
-         replace_pseudos_in_call_usage (& CALL_INSN_FUNCTION_USAGE (insn),
-                                        VOIDmode,
-                                        CALL_INSN_FUNCTION_USAGE (insn));
+         replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
+                             VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));
 
        if ((GET_CODE (PATTERN (insn)) == USE
             /* We mark with QImode USEs introduced by reload itself.  */
@@ -1213,6 +1210,13 @@ reload (first, global)
            continue;
          }
 
+       /* Some CLOBBERs may survive until here and still reference unassigned
+          pseudos with const equivalent, which may in turn cause ICE in later
+          passes if the reference remains in place.  */
+       if (GET_CODE (PATTERN (insn)) == CLOBBER)
+         replace_pseudos_in (& XEXP (PATTERN (insn), 0),
+                             VOIDmode, PATTERN (insn));
+
        pnote = &REG_NOTES (insn);
        while (*pnote != 0)
          {
@@ -6134,13 +6138,15 @@ merge_assigned_reloads (insn)
                       ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
 
                  /* Check to see if we accidentally converted two reloads
-                    that use the same reload register to the same type.
-                    If so, the resulting code won't work, so abort.  */
+                    that use the same reload register with different inputs
+                    to the same type.  If so, the resulting code won't work,
+                    so abort.  */
                  if (rld[j].reg_rtx)
                    for (k = 0; k < j; k++)
                      if (rld[k].in != 0 && rld[k].reg_rtx != 0
                          && rld[k].when_needed == rld[j].when_needed
-                         && rtx_equal_p (rld[k].reg_rtx, rld[j].reg_rtx))
+                         && rtx_equal_p (rld[k].reg_rtx, rld[j].reg_rtx)
+                         && ! rtx_equal_p (rld[k].in, rld[j].in))
                        abort ();
                }
        }
@@ -9065,7 +9071,7 @@ reload_combine_note_use (xp, insn)
    use move2add_last_label_luid to note where the label is and then
    later disable any optimization that would cross it.
    reg_offset[n] / reg_base_reg[n] / reg_mode[n] are only valid if
-   reg_set_luid[n] is greater than last_label_luid[n] .  */
+   reg_set_luid[n] is greater than move2add_last_label_luid.  */
 static int reg_set_luid[FIRST_PSEUDO_REGISTER];
 
 /* If reg_base_reg[n] is negative, register n has been set to
@@ -9094,9 +9100,6 @@ static int move2add_last_label_luid;
        && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \
                                 GET_MODE_BITSIZE (INMODE))))
 
-/* The source of the last set to cc0 we've seen.  */
-static rtx move2add_last_cc0;
-
 static void
 reload_cse_move2add (first)
      rtx first;
@@ -9109,7 +9112,6 @@ reload_cse_move2add (first)
 
   move2add_last_label_luid = 0;
   move2add_luid = 2;
-  move2add_last_cc0 = NULL_RTX;
   for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
     {
       rtx pat, note;
@@ -9166,7 +9168,14 @@ reload_cse_move2add (first)
                     value flag.  jump2 already knows how to get rid of
                     no-op moves.  */
                  if (new_src == const0_rtx)
-                   validate_change (insn, &SET_SRC (pat), reg, 0);
+                   {
+                     /* If the constants are different, this is a
+                        truncation, that, if turned into (set (reg)
+                        (reg)), would be discarded.  Maybe we should
+                        try a truncMN pattern?  */
+                     if (INTVAL (src) == reg_offset [regno])
+                       validate_change (insn, &SET_SRC (pat), reg, 0);
+                   }
                  else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
                           && have_add2_insn (reg, new_src))
                    {
@@ -9292,29 +9301,6 @@ reload_cse_move2add (first)
            }
        }
       note_stores (PATTERN (insn), move2add_note_store, NULL);
-
-      /* If INSN is a conditional branch, we try to extract an
-        implicit set out of it.  */
-      if (any_condjump_p (insn) && onlyjump_p (insn))
-       {
-         rtx cnd = get_condition (insn, NULL);
-
-#ifdef HAVE_cc0
-         if (cnd != NULL_RTX && move2add_last_cc0 != NULL_RTX)
-           cnd = simplify_replace_rtx (cnd, cc0_rtx, move2add_last_cc0);
-#endif
-         if (cnd != NULL_RTX
-             && GET_CODE (cnd) == NE
-             && GET_CODE (XEXP (cnd, 0)) == REG
-             && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
-             && GET_CODE (XEXP (cnd, 1)) == CONST_INT)
-           {
-             rtx implicit_set =
-               gen_rtx_SET (VOIDmode, SET_DEST (cnd), SET_SRC (cnd));
-             move2add_note_store (SET_DEST (implicit_set), implicit_set, 0);
-           }
-       }
-
       /* If this is a CALL_INSN, all call used registers are stored with
         unknown values.  */
       if (GET_CODE (insn) == CALL_INSN)
@@ -9361,13 +9347,6 @@ move2add_note_store (dst, set, data)
        reg_set_luid[REGNO (XEXP (dst, 0))] = 0;
       return;
     }
-  /* Note a store into cc0 so that we can later find an implicit
-     set.  */
-  if (CC0_P (dst))
-    {
-      move2add_last_cc0 = SET_SRC (set);
-      return;
-    }
   if (GET_CODE (dst) != REG)
     return;