OSDN Git Service

* init.c (build_new): Allow enumeration types for the array-bounds
[pf3gnuchains/gcc-fork.git] / gcc / resource.c
index d84fabe..8266321 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for computing resource usage of specific insns.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "output.h"
 #include "resource.h"
+#include "except.h"
 #include "insn-attr.h"
 
 /* This structure is used to record liveness information at the targets or
@@ -175,7 +176,7 @@ next_insn_no_annul (insn)
 }
 \f
 /* Given X, some rtl, and RES, a pointer to a `struct resource', mark
-   which resources are references by the insn.  If INCLUDE_DELAYED_EFFECTS
+   which resources are referenced by the insn.  If INCLUDE_DELAYED_EFFECTS
    is TRUE, resources used by the called routine will be included for
    CALL_INSNs.  */
 
@@ -211,14 +212,24 @@ mark_referenced_resources (x, res, include_delayed_effects)
          unsigned int last_regno
            = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
 
+         if (last_regno > FIRST_PSEUDO_REGISTER)
+           abort ();
          for (r = regno; r < last_regno; r++)
            SET_HARD_REG_BIT (res->regs, r);
        }
       return;
 
     case REG:
-      for (r = 0; r < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); r++)
-       SET_HARD_REG_BIT (res->regs, REGNO (x) + r);
+       {
+         unsigned int regno = REGNO (x);
+         unsigned int last_regno
+           = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+
+         if (last_regno > FIRST_PSEUDO_REGISTER)
+           abort ();
+         for (r = regno; r < last_regno; r++)
+           SET_HARD_REG_BIT (res->regs, r);
+       }
       return;
 
     case MEM:
@@ -451,7 +462,7 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
              /* If INSN is a USE made by update_block, we care about the
                 underlying insn.  Any registers set by the underlying insn
                 are live since the insn is being done somewhere else.  */
-             if (GET_RTX_CLASS (GET_CODE (XEXP (PATTERN (insn), 0))) == 'i')
+             if (INSN_P (XEXP (PATTERN (insn), 0)))
                mark_set_resources (XEXP (PATTERN (insn), 0), res, 0,
                                    MARK_SRC_DEST_CALL);
 
@@ -720,6 +731,13 @@ mark_set_resources (x, res, in_dest, mark_type)
       mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST);
       return;
 
+    case PRE_MODIFY:
+    case POST_MODIFY:
+      mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST);
+      mark_set_resources (XEXP (XEXP (x, 1), 0), res, 0, MARK_SRC_DEST);
+      mark_set_resources (XEXP (XEXP (x, 1), 1), res, 0, MARK_SRC_DEST);
+      return;
+
     case SIGN_EXTRACT:
     case ZERO_EXTRACT:
       if (! (mark_type == MARK_DEST && in_dest))
@@ -752,6 +770,8 @@ mark_set_resources (x, res, in_dest, mark_type)
              unsigned int last_regno
                = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
 
+             if (last_regno > FIRST_PSEUDO_REGISTER)
+               abort ();
              for (r = regno; r < last_regno; r++)
                SET_HARD_REG_BIT (res->regs, r);
            }
@@ -760,8 +780,16 @@ mark_set_resources (x, res, in_dest, mark_type)
 
     case REG:
       if (in_dest)
-        for (r = 0; r < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); r++)
-         SET_HARD_REG_BIT (res->regs, REGNO (x) + r);
+       {
+         unsigned int regno = REGNO (x);
+         unsigned int last_regno
+           = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+
+         if (last_regno > FIRST_PSEUDO_REGISTER)
+           abort ();
+         for (r = regno; r < last_regno; r++)
+           SET_HARD_REG_BIT (res->regs, r);
+       }
       return;
 
     case STRICT_LOW_PART:
@@ -915,7 +943,7 @@ mark_target_live_regs (insns, target, res)
        {
          /* Allocate a place to put our results and chain it into the 
             hash table.  */
-         tinfo = (struct target_info *) oballoc (sizeof (struct target_info));
+         tinfo = (struct target_info *) xmalloc (sizeof (struct target_info));
          tinfo->uid = INSN_UID (target);
          tinfo->block = b;
          tinfo->next = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
@@ -983,7 +1011,7 @@ mark_target_live_regs (insns, target, res)
          /* If this insn is a USE made by update_block, we care about the
             underlying insn.  */
          if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE
-             && GET_RTX_CLASS (GET_CODE (XEXP (PATTERN (insn), 0))) == 'i')
+             && INSN_P (XEXP (PATTERN (insn), 0)))
              real_insn = XEXP (PATTERN (insn), 0);
 
          if (GET_CODE (real_insn) == CALL_INSN)
@@ -1001,7 +1029,7 @@ mark_target_live_regs (insns, target, res)
 #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
                    && ! (i == ARG_POINTER_REGNUM && fixed_regs[i])
 #endif
-#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
+#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
                    && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
 #endif
                    )
@@ -1215,6 +1243,20 @@ free_resource_info ()
 {
   if (target_hash_table != NULL)
     {
+      int i;
+      
+      for (i = 0; i < TARGET_HASH_PRIME; ++i) 
+       {
+         struct target_info *ti = target_hash_table[i];
+
+         while (ti) 
+           {
+             struct target_info *next = ti->next;
+             free (ti);
+             ti = next;
+           }
+       }
+
       free (target_hash_table);
       target_hash_table = NULL;
     }
@@ -1268,109 +1310,3 @@ mark_end_of_function_resources (trial, include_delayed_effects)
   mark_referenced_resources (trial, &end_of_function_needs,
                             include_delayed_effects);
 }
-\f
-/* Try to find a hard register of mode MODE, matching the register class in
-   CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
-   remains available until the end of LAST_INSN.  LAST_INSN may be NULL_RTX,
-   in which case the only condition is that the register must be available
-   before CURRENT_INSN.
-   Registers that already have bits set in REG_SET will not be considered.
-
-   If an appropriate register is available, it will be returned and the
-   corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
-   returned.  */
-
-rtx
-find_free_register (current_insn, last_insn, class_str, mode, reg_set)
-     rtx current_insn, last_insn;
-     const char *class_str;
-     int mode;
-     HARD_REG_SET *reg_set;
-{
-  int i, j;
-  struct resources used;
-  unsigned char clet = class_str[0];
-  enum reg_class class
-    = (clet == 'r' ? GENERAL_REGS :  REG_CLASS_FROM_LETTER (clet));
-
-  mark_target_live_regs (get_insns (), current_insn, &used);
-  if (last_insn)
-    while (current_insn != last_insn)
-      {
-       /* Exclude anything set in this insn.  */
-       mark_set_resources (PATTERN (current_insn), &used, 0,
-                           MARK_SRC_DEST_CALL);
-       current_insn = next_nonnote_insn (current_insn);
-      }
-
-
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      int regno;
-      int success;
-
-#ifdef REG_ALLOC_ORDER
-      regno = reg_alloc_order [i];
-#else
-      regno = i;
-#endif
-
-      /* Don't allocate fixed registers.  */
-      if (fixed_regs[regno])
-       continue;
-      /* Make sure the register is of the right class.  */
-      if (! TEST_HARD_REG_BIT (reg_class_contents[class], regno))
-       continue;
-      /* And can support the mode we need.  */
-      if (! HARD_REGNO_MODE_OK (regno, mode))
-       continue;
-      /* And that we don't create an extra save/restore.  */
-      if (! call_used_regs[regno] && ! regs_ever_live[regno])
-       continue;
-      /* And we don't clobber traceback for noreturn functions.  */
-      if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM)
-         && (! reload_completed || frame_pointer_needed))
-       continue;
-
-      success = 1;
-      for (j = HARD_REGNO_NREGS (regno, mode) - 1; j >= 0; j--)
-       {
-         if (TEST_HARD_REG_BIT (*reg_set, regno + j)
-             || TEST_HARD_REG_BIT (used.regs, regno + j))
-           {
-             success = 0;
-             break;
-           }
-       }
-      if (success)
-       {
-         for (j = HARD_REGNO_NREGS (regno, mode) - 1; j >= 0; j--)
-           {
-             SET_HARD_REG_BIT (*reg_set, regno + j);
-           }
-         return gen_rtx_REG (mode, regno);
-       }
-    }
-  return NULL_RTX;
-}
-
-/* Return true if REG is dead at CURRENT_INSN.  */
-
-int
-reg_dead_p (current_insn, reg)
-     rtx current_insn, reg;
-{
-  struct resources used;
-  int regno, j;
-
-  mark_target_live_regs (get_insns (), current_insn, &used);
-  
-  regno = REGNO (reg);
-  for (j = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1; j >= 0; j--)
-    {
-      if (TEST_HARD_REG_BIT (used.regs, regno + j))
-       return 0;
-    }
-
-  return 1;
-}