OSDN Git Service

* config/darwin.h (ENABLE_EXECUTE_STACK): New, use getpagesize not
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index a86f6f5..4244b29 100644 (file)
@@ -87,7 +87,7 @@ static rtx *reg_last_reload_reg;
 
 /* Elt N nonzero if reg_last_reload_reg[N] has been set in this insn
    for an output reload that stores into reg N.  */
-static char *reg_has_output_reload;
+static regset_head reg_has_output_reload;
 
 /* Indicates which hard regs are reload-registers for an output reload
    in the current insn.  */
@@ -1167,6 +1167,20 @@ reload (rtx first, int global)
       {
        rtx *pnote;
 
+       /* Clean up invalid ASMs so that they don't confuse later passes.
+          See PR 21299.  */
+       if (asm_noperands (PATTERN (insn)) >= 0)
+         {
+           extract_insn (insn);
+           if (!constrain_operands (1))
+             {
+               error_for_asm (insn,
+                              "%<asm%> operand has impossible constraints");
+               delete_insn (insn);
+               continue;
+             }
+         }
+
        if (CALL_P (insn))
          replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
                              VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));
@@ -1982,8 +1996,11 @@ alter_reg (int i, int from_reg)
       && reg_equiv_memory_loc[i] == 0)
     {
       rtx x;
+      enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
       unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
+      unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
       unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
+      unsigned int min_align = reg_max_ref_width[i] * BITS_PER_UNIT;
       int adjust = 0;
 
       /* Each pseudo reg has an inherent size which comes from its own mode,
@@ -1997,8 +2014,9 @@ alter_reg (int i, int from_reg)
       if (from_reg == -1)
        {
          /* No known place to spill from => no slot to reuse.  */
-         x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size,
-                                 inherent_size == total_size ? 0 : -1);
+         x = assign_stack_local (mode, total_size,
+                                 min_align > inherent_align
+                                 || total_size > inherent_size ? -1 : 0);
          if (BYTES_BIG_ENDIAN)
            /* Cancel the  big-endian correction done in assign_stack_local.
               Get the address of the beginning of the slot.
@@ -2014,7 +2032,8 @@ alter_reg (int i, int from_reg)
       else if (spill_stack_slot[from_reg] != 0
               && spill_stack_slot_width[from_reg] >= total_size
               && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
-                  >= inherent_size))
+                  >= inherent_size)
+              && MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align)
        x = spill_stack_slot[from_reg];
 
       /* Allocate a bigger slot.  */
@@ -2022,7 +2041,6 @@ alter_reg (int i, int from_reg)
        {
          /* Compute maximum size needed, both for inherent size
             and for total size.  */
-         enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
          rtx stack_slot;
 
          if (spill_stack_slot[from_reg])
@@ -2032,11 +2050,14 @@ alter_reg (int i, int from_reg)
                mode = GET_MODE (spill_stack_slot[from_reg]);
              if (spill_stack_slot_width[from_reg] > total_size)
                total_size = spill_stack_slot_width[from_reg];
+             if (MEM_ALIGN (spill_stack_slot[from_reg]) > min_align)
+               min_align = MEM_ALIGN (spill_stack_slot[from_reg]);
            }
 
          /* Make a slot with that size.  */
          x = assign_stack_local (mode, total_size,
-                                 inherent_size == total_size ? 0 : -1);
+                                 min_align > inherent_align
+                                 || total_size > inherent_size ? -1 : 0);
          stack_slot = x;
 
          /* All pseudos mapped to this slot can alias each other.  */
@@ -3814,7 +3835,8 @@ scan_paradoxical_subregs (rtx x)
 
     case SUBREG:
       if (REG_P (SUBREG_REG (x))
-         && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && (GET_MODE_SIZE (GET_MODE (x))
+             > reg_max_ref_width[REGNO (SUBREG_REG (x))]))
        reg_max_ref_width[REGNO (SUBREG_REG (x))]
          = GET_MODE_SIZE (GET_MODE (x));
       return;
@@ -3889,7 +3911,7 @@ reload_as_needed (int live_known)
   memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
   memset (spill_reg_store, 0, sizeof spill_reg_store);
   reg_last_reload_reg = XCNEWVEC (rtx, max_regno);
-  reg_has_output_reload = XNEWVEC (char, max_regno);
+  INIT_REG_SET (&reg_has_output_reload);
   CLEAR_HARD_REG_SET (reg_reloaded_valid);
   CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);
 
@@ -3911,6 +3933,7 @@ reload_as_needed (int live_known)
          regset_head regs_to_forget;
          INIT_REG_SET (&regs_to_forget);
          note_stores (PATTERN (insn), forget_old_reloads_1, &regs_to_forget);
+
          /* If this is a USE and CLOBBER of a MEM, ensure that any
             references to eliminable registers have been removed.  */
 
@@ -3951,7 +3974,7 @@ reload_as_needed (int live_known)
             rtx's for those pseudo regs.  */
          else
            {
-             memset (reg_has_output_reload, 0, max_regno);
+             CLEAR_REG_SET (&reg_has_output_reload);
              CLEAR_HARD_REG_SET (reg_is_output_reload);
 
              find_reloads (insn, 1, spill_indirect_levels, live_known,
@@ -4105,7 +4128,8 @@ reload_as_needed (int live_known)
                             the reload for inheritance.  */
                          SET_HARD_REG_BIT (reg_is_output_reload,
                                            REGNO (reload_reg));
-                         reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1;
+                         SET_REGNO_REG_SET (&reg_has_output_reload,
+                                            REGNO (XEXP (in_reg, 0)));
                        }
                      else
                        forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX,
@@ -4121,7 +4145,8 @@ reload_as_needed (int live_known)
                    {
                      SET_HARD_REG_BIT (reg_is_output_reload,
                                        REGNO (rld[i].reg_rtx));
-                     reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1;
+                     SET_REGNO_REG_SET (&reg_has_output_reload,
+                                        REGNO (XEXP (in_reg, 0)));
                    }
                }
            }
@@ -4159,7 +4184,7 @@ reload_as_needed (int live_known)
 
   /* Clean up.  */
   free (reg_last_reload_reg);
-  free (reg_has_output_reload);
+  CLEAR_REG_SET (&reg_has_output_reload);
 }
 
 /* Discard all record of any value reloaded from X,
@@ -4230,7 +4255,8 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
       while (nr-- > 0)
        /* But don't forget a copy if this is the output reload
           that establishes the copy's validity.  */
-       if (n_reloads == 0 || reg_has_output_reload[regno + nr] == 0)
+       if (n_reloads == 0
+           || !REGNO_REG_SET_P (&reg_has_output_reload, regno + nr))
          reg_last_reload_reg[regno + nr] = 0;
      }
 }
@@ -4253,7 +4279,8 @@ forget_marked_reloads (regset regs)
            CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, reg);
            spill_reg_store[reg] = 0;
          }
-      if (n_reloads == 0 || reg_has_output_reload[reg] == 0)
+      if (n_reloads == 0
+         || !REGNO_REG_SET_P (&reg_has_output_reload, reg))
        reg_last_reload_reg[reg] = 0;
     }
 }
@@ -6083,7 +6110,8 @@ choose_reload_regs (struct insn_chain *chain)
            nr = hard_regno_nregs[nregno][rld[r].mode];
 
          while (--nr >= 0)
-           reg_has_output_reload[nregno + nr] = 1;
+           SET_REGNO_REG_SET (&reg_has_output_reload,
+                              nregno + nr);
 
          if (i >= 0)
            {
@@ -7273,7 +7301,7 @@ emit_reload_insns (struct insn_chain *chain)
 
          if (REG_P (reg)
              && REGNO (reg) >= FIRST_PSEUDO_REGISTER
-             && ! reg_has_output_reload[REGNO (reg)])
+             && !REGNO_REG_SET_P (&reg_has_output_reload, REGNO (reg)))
            {
              int nregno = REGNO (reg);
 
@@ -7384,9 +7412,11 @@ emit_reload_insns (struct insn_chain *chain)
                       && rld[r].in != 0
                       && ((REG_P (rld[r].in)
                            && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER
-                           && ! reg_has_output_reload[REGNO (rld[r].in)])
+                           && !REGNO_REG_SET_P (&reg_has_output_reload,
+                                                REGNO (rld[r].in)))
                           || (REG_P (rld[r].in_reg)
-                              && ! reg_has_output_reload[REGNO (rld[r].in_reg)]))
+                              && !REGNO_REG_SET_P (&reg_has_output_reload,
+                                                   REGNO (rld[r].in_reg))))
                       && ! reg_set_p (rld[r].reg_rtx, PATTERN (insn)))
                {
                  int nregno;
@@ -7544,7 +7574,8 @@ emit_reload_insns (struct insn_chain *chain)
                  /* We have to set reg_has_output_reload here, or else 
                     forget_old_reloads_1 will clear reg_last_reload_reg
                     right away.  */
-                 reg_has_output_reload[nregno] = 1;
+                 SET_REGNO_REG_SET (&reg_has_output_reload,
+                                    nregno);
                }
            }
          else
@@ -8168,7 +8199,7 @@ static rtx
 inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
 {
   /* REG or MEM to be copied and incremented.  */
-  rtx incloc = XEXP (value, 0);
+  rtx incloc = find_replacement (&XEXP (value, 0));
   /* Nonzero if increment after copying.  */
   int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC
              || GET_CODE (value) == POST_MODIFY);
@@ -8177,7 +8208,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
   rtx add_insn;
   int code;
   rtx store;
-  rtx real_in = in == value ? XEXP (in, 0) : in;
+  rtx real_in = in == value ? incloc : in;
 
   /* No hard register is equivalent to this register after
      inc/dec operation.  If REG_LAST_RELOAD_REG were nonzero,
@@ -8189,7 +8220,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
   if (GET_CODE (value) == PRE_MODIFY || GET_CODE (value) == POST_MODIFY)
     {
       gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS);
-      inc = XEXP (XEXP (value, 1), 1);
+      inc = find_replacement (&XEXP (XEXP (value, 1), 1));
     }
   else
     {