OSDN Git Service

* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
[pf3gnuchains/gcc-fork.git] / gcc / regclass.c
index e3eca7f..579a1ea 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996
    1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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 version.
+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
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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 GNU CC; 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 COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 
 /* This file contains two passes of the compiler: reg_scan and reg_class.
@@ -94,6 +94,15 @@ HARD_REG_SET losing_caller_save_reg_set;
 /* Data for initializing the above.  */
 
 static char initial_call_used_regs[] = CALL_USED_REGISTERS;
+
+/* This is much like call_used_regs, except it doesn't have to
+   be a superset of FIXED_REGISTERS. This vector indicates
+   what is really call clobbered, and is used when defining 
+   regs_invalidated_by_call.  */
+
+#ifdef CALL_REALLY_USED_REGISTERS
+char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
+#endif
   
 /* Indexed by hard register number, contains 1 for registers that are
    fixed use or call used registers that cannot hold quantities across
@@ -140,10 +149,11 @@ HARD_REG_SET reg_class_contents[N_REG_CLASSES];
 
 /* The same information, but as an array of unsigned ints.  We copy from
    these unsigned ints to the table above.  We do this so the tm.h files
-   do not have to be aware of the wordsize for machines with <= 64 regs.  */
+   do not have to be aware of the wordsize for machines with <= 64 regs.
+   Note that we hard-code 32 here, not HOST_BITS_PER_INT.  */
 
 #define N_REG_INTS  \
-  ((FIRST_PSEUDO_REGISTER + (HOST_BITS_PER_INT - 1)) / HOST_BITS_PER_INT)
+  ((FIRST_PSEUDO_REGISTER + (32 - 1)) / 32)
 
 static unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS] 
   = REG_CLASS_CONTENTS;
@@ -255,7 +265,7 @@ struct reg_info_data {
 static struct reg_info_data *reg_info_head;
 
 /* No more global register variables may be declared; true once
-   regclass has been initialized. */
+   regclass has been initialized.  */
 
 static int no_global_reg_vars = 0;
 
@@ -275,9 +285,10 @@ init_reg_sets ()
     {
       CLEAR_HARD_REG_SET (reg_class_contents[i]);
 
+      /* Note that we hard-code 32 here, not HOST_BITS_PER_INT.  */
       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
-       if (int_reg_class_contents[i][j / HOST_BITS_PER_INT]
-           & ((unsigned) 1 << (j % HOST_BITS_PER_INT)))
+       if (int_reg_class_contents[i][j / 32]
+           & ((unsigned) 1 << (j % 32)))
          SET_HARD_REG_BIT (reg_class_contents[i], j);
     }
 
@@ -462,7 +473,13 @@ init_reg_sets_1 ()
       else if (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
        ;
 #endif
-      else if (call_used_regs[i] || global_regs[i])
+      else if (0
+#ifdef CALL_REALLY_USED_REGISTERS
+              || call_really_used_regs[i]
+#else
+              || call_used_regs[i]
+#endif
+              || global_regs[i])
        SET_HARD_REG_BIT (regs_invalidated_by_call, i);
     }
 
@@ -616,7 +633,7 @@ memory_move_secondary_cost (mode, class, in)
   enum reg_class altclass;
   int partial_cost = 0;
   /* We need a memory reference to feed to SECONDARY... macros.  */
-  /* mem may be unused even if the SECONDARY_ macros are defined. */
+  /* mem may be unused even if the SECONDARY_ macros are defined.  */
   rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
 
 
@@ -745,6 +762,10 @@ fix_register (name, fixed, call_used)
        {
          fixed_regs[i] = fixed;
          call_used_regs[i] = call_used;
+#ifdef CALL_REALLY_USED_REGISTERS
+         if (fixed == 0)
+           call_really_used_regs[i] = call_used;
+#endif
        }
     }
   else
@@ -827,7 +848,7 @@ static struct costs init_cost;
 
 static struct reg_pref *reg_pref;
 
-/* Allocated buffers for reg_pref. */
+/* Allocated buffers for reg_pref.  */
 
 static struct reg_pref *reg_pref_buffer;
 
@@ -887,7 +908,7 @@ regclass_init ()
      before regclass is run.  */
   reg_pref = NULL;
 
-  /* No more global register variables may be declared. */
+  /* No more global register variables may be declared.  */
   no_global_reg_vars = 1;
 }
 \f
@@ -1231,7 +1252,7 @@ regclass (f, nregs, dump)
 
       if (!optimize)
        {
-         frequency = 1;
+         frequency = REG_FREQ_MAX;
          for (insn = f; insn; insn = NEXT_INSN (insn))
            insn = scan_one_insn (insn, pass);
        }
@@ -1244,10 +1265,7 @@ regclass (f, nregs, dump)
               times more than insns outside a loop.  This is much more
               aggressive than the assumptions made elsewhere and is being
               tried as an experiment.  */
-           if (optimize_size)
-             frequency = 1;
-           else
-             frequency = bb->frequency ? bb->frequency : 1;
+           frequency = REG_FREQ_FROM_BB (bb);
            for (insn = bb->head; ; insn = NEXT_INSN (insn))
              {
                insn = scan_one_insn (insn, pass);
@@ -2425,7 +2443,10 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
 
       if (GET_CODE (dest) == REG
          && REGNO (dest) >= min_regno)
-       REG_N_SETS (REGNO (dest))++;
+       {
+         REG_N_SETS (REGNO (dest))++;
+         REG_N_REFS (REGNO (dest))++;
+       }
 
       /* If this is setting a pseudo from another pseudo or the sum of a
         pseudo and a constant integer and the other pseudo is known to be