OSDN Git Service

gcc/ada/
[pf3gnuchains/gcc-fork.git] / gcc / resource.c
index ce86aaf..7cb4d2a 100644 (file)
@@ -1,12 +1,12 @@
 /* Definitions for computing resource usage of specific insns.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -35,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "except.h"
 #include "insn-attr.h"
 #include "params.h"
+#include "df.h"
 
 /* This structure is used to record liveness information at the targets or
    fallthrough insns of branches.  We will most likely need the information
@@ -78,7 +78,7 @@ static HARD_REG_SET current_live_regs;
 
 static HARD_REG_SET pending_dead_regs;
 \f
-static void update_live_status (rtx, rtx, void *);
+static void update_live_status (rtx, const_rtx, void *);
 static int find_basic_block (rtx, int);
 static rtx next_insn_no_annul (rtx);
 static rtx find_dead_or_set_registers (rtx, struct resources*,
@@ -89,7 +89,7 @@ static rtx find_dead_or_set_registers (rtx, struct resources*,
    It deadens any CLOBBERed registers and livens any SET registers.  */
 
 static void
-update_live_status (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
+update_live_status (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED)
 {
   int first_regno, last_regno;
   int i;
@@ -99,11 +99,16 @@ update_live_status (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
     return;
 
   if (GET_CODE (dest) == SUBREG)
-    first_regno = subreg_regno (dest);
-  else
-    first_regno = REGNO (dest);
+    {
+      first_regno = subreg_regno (dest);
+      last_regno = first_regno + subreg_nregs (dest);
 
-  last_regno = first_regno + hard_regno_nregs[first_regno][GET_MODE (dest)];
+    }
+  else
+    {
+      first_regno = REGNO (dest);
+      last_regno = END_HARD_REGNO (dest);
+    }
 
   if (GET_CODE (x) == CLOBBER)
     for (i = first_regno; i < last_regno; i++)
@@ -217,6 +222,7 @@ mark_referenced_resources (rtx x, struct resources *res,
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_FIXED:
     case CONST_VECTOR:
     case PC:
     case SYMBOL_REF:
@@ -229,8 +235,7 @@ mark_referenced_resources (rtx x, struct resources *res,
       else
        {
          unsigned int regno = subreg_regno (x);
-         unsigned int last_regno
-           = regno + hard_regno_nregs[regno][GET_MODE (x)];
+         unsigned int last_regno = regno + subreg_nregs (x);
 
          gcc_assert (last_regno <= FIRST_PSEUDO_REGISTER);
          for (r = regno; r < last_regno; r++)
@@ -239,15 +244,8 @@ mark_referenced_resources (rtx x, struct resources *res,
       return;
 
     case REG:
-       {
-         unsigned int regno = REGNO (x);
-         unsigned int last_regno
-           = regno + hard_regno_nregs[regno][GET_MODE (x)];
-
-         gcc_assert (last_regno <= FIRST_PSEUDO_REGISTER);
-         for (r = regno; r < last_regno; r++)
-           SET_HARD_REG_BIT (res->regs, r);
-       }
+      gcc_assert (HARD_REGISTER_P (x));
+      add_to_hard_reg_set (&res->regs, GET_MODE (x), REGNO (x));
       return;
 
     case MEM:
@@ -641,6 +639,7 @@ mark_set_resources (rtx x, struct resources *res, int in_dest,
     case USE:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_FIXED:
     case CONST_VECTOR:
     case LABEL_REF:
     case SYMBOL_REF:
@@ -763,8 +762,7 @@ mark_set_resources (rtx x, struct resources *res, int in_dest,
          else
            {
              unsigned int regno = subreg_regno (x);
-             unsigned int last_regno
-               = regno + hard_regno_nregs[regno][GET_MODE (x)];
+             unsigned int last_regno = regno + subreg_nregs (x);
 
              gcc_assert (last_regno <= FIRST_PSEUDO_REGISTER);
              for (r = regno; r < last_regno; r++)
@@ -776,13 +774,8 @@ mark_set_resources (rtx x, struct resources *res, int in_dest,
     case REG:
       if (in_dest)
        {
-         unsigned int regno = REGNO (x);
-         unsigned int last_regno
-           = regno + hard_regno_nregs[regno][GET_MODE (x)];
-
-         gcc_assert (last_regno <= FIRST_PSEUDO_REGISTER);
-         for (r = regno; r < last_regno; r++)
-           SET_HARD_REG_BIT (res->regs, r);
+         gcc_assert (HARD_REGISTER_P (x));
+         add_to_hard_reg_set (&res->regs, GET_MODE (x), REGNO (x));
        }
       return;
 
@@ -832,12 +825,12 @@ mark_set_resources (rtx x, struct resources *res, int in_dest,
 /* Return TRUE if INSN is a return, possibly with a filled delay slot.  */
 
 static bool
-return_insn_p (rtx insn)
+return_insn_p (const_rtx insn)
 {
-  if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == RETURN)
+  if (JUMP_P (insn) && GET_CODE (PATTERN (insn)) == RETURN)
     return true;
 
-  if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
+  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
     return return_insn_p (XVECEXP (PATTERN (insn), 0, 0));
 
   return false;
@@ -949,7 +942,7 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
        {
          /* Allocate a place to put our results and chain it into the
             hash table.  */
-         tinfo = xmalloc (sizeof (struct target_info));
+         tinfo = XNEW (struct target_info);
          tinfo->uid = INSN_UID (target);
          tinfo->block = b;
          tinfo->next
@@ -965,9 +958,7 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
      TARGET.  Otherwise, we must assume everything is live.  */
   if (b != -1)
     {
-      regset regs_live = BASIC_BLOCK (b)->global_live_at_start;
-      unsigned int j;
-      unsigned int regno;
+      regset regs_live = df_get_live_in (BASIC_BLOCK (b));
       rtx start_insn, stop_insn;
       reg_set_iterator rsi;
 
@@ -980,18 +971,14 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
       EXECUTE_IF_SET_IN_REG_SET (regs_live, FIRST_PSEUDO_REGISTER, i, rsi)
        {
          if (reg_renumber[i] >= 0)
-           {
-             regno = reg_renumber[i];
-             for (j = regno;
-                  j < regno + hard_regno_nregs[regno][PSEUDO_REGNO_MODE (i)];
-                  j++)
-               SET_HARD_REG_BIT (current_live_regs, j);
-           }
+           add_to_hard_reg_set (&current_live_regs, PSEUDO_REGNO_MODE (i),
+                               reg_renumber[i]);
        }
 
       /* Get starting and ending insn, handling the case where each might
         be a SEQUENCE.  */
-      start_insn = (b == 0 ? insns : BB_HEAD (BASIC_BLOCK (b)));
+      start_insn = (b == ENTRY_BLOCK_PTR->next_bb->index ? 
+                   insns : BB_HEAD (BASIC_BLOCK (b)));
       stop_insn = target;
 
       if (NONJUMP_INSN_P (start_insn)
@@ -1052,16 +1039,9 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
                if (REG_NOTE_KIND (link) == REG_DEAD
                    && REG_P (XEXP (link, 0))
                    && REGNO (XEXP (link, 0)) < FIRST_PSEUDO_REGISTER)
-                 {
-                   unsigned int first_regno = REGNO (XEXP (link, 0));
-                   unsigned int last_regno
-                     = (first_regno
-                        + hard_regno_nregs[first_regno]
-                                          [GET_MODE (XEXP (link, 0))]);
-
-                   for (i = first_regno; i < last_regno; i++)
-                     SET_HARD_REG_BIT (pending_dead_regs, i);
-                 }
+                 add_to_hard_reg_set (&pending_dead_regs,
+                                     GET_MODE (XEXP (link, 0)),
+                                     REGNO (XEXP (link, 0)));
 
              note_stores (PATTERN (real_insn), update_live_status, NULL);
 
@@ -1071,16 +1051,9 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
                if (REG_NOTE_KIND (link) == REG_UNUSED
                    && REG_P (XEXP (link, 0))
                    && REGNO (XEXP (link, 0)) < FIRST_PSEUDO_REGISTER)
-                 {
-                   unsigned int first_regno = REGNO (XEXP (link, 0));
-                   unsigned int last_regno
-                     = (first_regno
-                        + hard_regno_nregs[first_regno]
-                                          [GET_MODE (XEXP (link, 0))]);
-
-                   for (i = first_regno; i < last_regno; i++)
-                     CLEAR_HARD_REG_BIT (current_live_regs, i);
-                 }
+                 remove_from_hard_reg_set (&current_live_regs,
+                                          GET_MODE (XEXP (link, 0)),
+                                          REGNO (XEXP (link, 0)));
            }
 
          else if (LABEL_P (real_insn))
@@ -1095,7 +1068,7 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
             RTL chain when there are no epilogue insns.  Certain resources
             are implicitly required at that point.  */
          else if (NOTE_P (real_insn)
-                  && NOTE_LINE_NUMBER (real_insn) == NOTE_INSN_EPILOGUE_BEG)
+                  && NOTE_KIND (real_insn) == NOTE_INSN_EPILOGUE_BEG)
            IOR_HARD_REG_SET (current_live_regs, start_of_epilogue_needs.regs);
        }
 
@@ -1226,8 +1199,8 @@ init_resource_info (rtx epilogue_insn)
     }
 
   /* Allocate and initialize the tables used by mark_target_live_regs.  */
-  target_hash_table = xcalloc (TARGET_HASH_PRIME, sizeof (struct target_info *));
-  bb_ticks = xcalloc (last_basic_block, sizeof (int));
+  target_hash_table = XCNEWVEC (struct target_info *, TARGET_HASH_PRIME);
+  bb_ticks = XCNEWVEC (int, last_basic_block);
 }
 \f
 /* Free up the resources allocated to mark_target_live_regs ().  This