OSDN Git Service

* flags.h (g_switch_value): Change to an unsigned
[pf3gnuchains/gcc-fork.git] / gcc / resource.c
index 5b19fe4..f542460 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for computing resource usage of specific insns.
-   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "toplev.h"
 #include "rtl.h"
 #include "tm_p.h"
@@ -133,7 +135,7 @@ find_basic_block (insn, search_limit)
      rtx insn;
      int search_limit;
 {
-  int i;
+  basic_block bb;
 
   /* Scan backwards to the previous BARRIER.  Then see if we can find a
      label that starts a basic block.  Return the basic block number.  */
@@ -146,9 +148,9 @@ find_basic_block (insn, search_limit)
   if (search_limit == 0)
     return -1;
 
-  /* The start of the function is basic block zero.  */
+  /* The start of the function.  */
   else if (insn == 0)
-    return 0;
+    return ENTRY_BLOCK_PTR->next_bb->index;
 
   /* See if any of the upcoming CODE_LABELs start a basic block.  If we reach
      anything other than a CODE_LABEL or note, we can't find this code.  */
@@ -156,9 +158,9 @@ find_basic_block (insn, search_limit)
        insn && GET_CODE (insn) == CODE_LABEL;
        insn = next_nonnote_insn (insn))
     {
-      for (i = 0; i < n_basic_blocks; i++)
-       if (insn == BLOCK_HEAD (i))
-         return i;
+      FOR_EACH_BB (bb)
+       if (insn == bb->head)
+         return bb->index;
     }
 
   return -1;
@@ -175,10 +177,23 @@ next_insn_no_annul (insn)
     {
       /* If INSN is an annulled branch, skip any insns from the target
         of the branch.  */
-      if (INSN_ANNULLED_BRANCH_P (insn)
+      if ((GET_CODE (insn) == JUMP_INSN
+          || GET_CODE (insn) == CALL_INSN
+          || GET_CODE (insn) == INSN)
+         && INSN_ANNULLED_BRANCH_P (insn)
          && NEXT_INSN (PREV_INSN (insn)) != insn)
-       while (INSN_FROM_TARGET_P (NEXT_INSN (insn)))
-         insn = NEXT_INSN (insn);
+       {
+         rtx next = NEXT_INSN (insn);
+         enum rtx_code code = GET_CODE (next);
+
+         while ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
+                && INSN_FROM_TARGET_P (next))
+           {
+             insn = next;
+             next = NEXT_INSN (insn);
+             code = GET_CODE (next);
+           }
+       }
 
       insn = NEXT_INSN (insn);
       if (insn && GET_CODE (insn) == INSN
@@ -212,6 +227,7 @@ mark_referenced_resources (x, res, include_delayed_effects)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -280,7 +296,7 @@ mark_referenced_resources (x, res, include_delayed_effects)
         We can not just fall through here since then we would be confused
         by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
         traditional asms unlike their normal usage.  */
-      
+
       for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
        mark_referenced_resources (ASM_OPERANDS_INPUT (x, i), res, 0);
       return;
@@ -358,7 +374,7 @@ mark_referenced_resources (x, res, include_delayed_effects)
             We assume that they both use and set all registers.  Using all
             registers ensures that a register will not be considered dead
             just because it crosses a setjmp call.  A register should be
-            considered dead only if the setjmp call returns non-zero.  */
+            considered dead only if the setjmp call returns nonzero.  */
          if (find_reg_note (x, REG_SETJMP, NULL))
            SET_HARD_REG_SET (res->regs);
 
@@ -422,7 +438,7 @@ mark_referenced_resources (x, res, include_delayed_effects)
 }
 \f
 /* A subroutine of mark_target_live_regs.  Search forward from TARGET
-   looking for registers that are set before they are used.  These are dead. 
+   looking for registers that are set before they are used.  These are dead.
    Stop after passing a few conditional jumps, and/or a small
    number of unconditional branches.  */
 
@@ -645,6 +661,7 @@ mark_set_resources (x, res, in_dest, mark_type)
     case USE:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case LABEL_REF:
     case SYMBOL_REF:
     case CONST:
@@ -719,7 +736,7 @@ mark_set_resources (x, res, in_dest, mark_type)
     case CLOBBER:
       mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST);
       return;
-      
+
     case SEQUENCE:
       for (i = 0; i < XVECLEN (x, 0); i++)
        if (! (INSN_ANNULLED_BRANCH_P (XVECEXP (x, 0, 0))
@@ -819,7 +836,7 @@ mark_set_resources (x, res, in_dest, mark_type)
         We can not just fall through here since then we would be confused
         by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
         traditional asms unlike their normal usage.  */
-      
+
       for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
        mark_set_resources (ASM_OPERANDS_INPUT (x, i), res, in_dest,
                            MARK_SRC_DEST);
@@ -944,7 +961,7 @@ mark_target_live_regs (insns, target, res)
        }
       else
        {
-         /* Allocate a place to put our results and chain it into the 
+         /* Allocate a place to put our results and chain it into the
             hash table.  */
          tinfo = (struct target_info *) xmalloc (sizeof (struct target_info));
          tinfo->uid = INSN_UID (target);
@@ -1005,16 +1022,18 @@ mark_target_live_regs (insns, target, res)
        {
          rtx link;
          rtx real_insn = insn;
+         enum rtx_code code = GET_CODE (insn);
 
          /* If this insn is from the target of a branch, it isn't going to
             be used in the sequel.  If it is used in both cases, this
             test will not be true.  */
-         if (INSN_FROM_TARGET_P (insn))
+         if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
+             && INSN_FROM_TARGET_P (insn))
            continue;
 
          /* 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
+         if (code == INSN && GET_CODE (PATTERN (insn)) == USE
              && INSN_P (XEXP (PATTERN (insn), 0)))
              real_insn = XEXP (PATTERN (insn), 0);
 
@@ -1054,7 +1073,7 @@ mark_target_live_regs (insns, target, res)
                      = (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);
                  }
@@ -1073,7 +1092,7 @@ mark_target_live_regs (insns, target, res)
                      = (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);
                  }
@@ -1091,7 +1110,7 @@ mark_target_live_regs (insns, target, res)
             RTL chain when there are no epilogue insns.  Certain resources
             are implicitly required at that point.  */
          else if (GET_CODE (real_insn) == NOTE
-                  && NOTE_LINE_NUMBER (real_insn) == NOTE_INSN_EPILOGUE_BEG)
+                  && NOTE_LINE_NUMBER (real_insn) == NOTE_INSN_EPILOGUE_BEG)
            IOR_HARD_REG_SET (current_live_regs, start_of_epilogue_needs.regs);
        }
 
@@ -1161,7 +1180,7 @@ init_resource_info (epilogue_insn)
   /* Indicate what resources are required to be valid at the end of the current
      function.  The condition code never is and memory always is.  If the
      frame pointer is needed, it is and so is the stack pointer unless
-     EXIT_IGNORE_STACK is non-zero.  If the frame pointer is not needed, the
+     EXIT_IGNORE_STACK is nonzero.  If the frame pointer is not needed, the
      stack pointer is.  Registers used to return the function value are
      needed.  Registers holding global variables are needed.  */
 
@@ -1223,10 +1242,10 @@ init_resource_info (epilogue_insn)
   /* Allocate and initialize the tables used by mark_target_live_regs.  */
   target_hash_table = (struct target_info **)
     xcalloc (TARGET_HASH_PRIME, sizeof (struct target_info *));
-  bb_ticks = (int *) xcalloc (n_basic_blocks, sizeof (int));
+  bb_ticks = (int *) xcalloc (last_basic_block, sizeof (int));
 }
 \f
-/* Free up the resources allcated to mark_target_live_regs ().  This
+/* Free up the resources allocated to mark_target_live_regs ().  This
    should be invoked after the last call to mark_target_live_regs ().  */
 
 void
@@ -1235,12 +1254,12 @@ free_resource_info ()
   if (target_hash_table != NULL)
     {
       int i;
-      
-      for (i = 0; i < TARGET_HASH_PRIME; ++i) 
+
+      for (i = 0; i < TARGET_HASH_PRIME; ++i)
        {
          struct target_info *ti = target_hash_table[i];
 
-         while (ti) 
+         while (ti)
            {
              struct target_info *next = ti->next;
              free (ti);
@@ -1266,7 +1285,7 @@ clear_hashed_info_for_insn (insn)
      rtx insn;
 {
   struct target_info *tinfo;
-      
+
   if (target_hash_table != NULL)
     {
       for (tinfo = target_hash_table[INSN_UID (insn) % TARGET_HASH_PRIME];