OSDN Git Service

* calls.c (expand_call): Convert structure_value_addr to Pmode if
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index edfd5d5..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 ();
                }
        }
@@ -9162,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))
                    {