OSDN Git Service

2004-11-16 Eric Christopher <echristo@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / ra.c
index 5884197..0b84dfc 100644 (file)
--- a/gcc/ra.c
+++ b/gcc/ra.c
@@ -1,5 +1,5 @@
 /* Graph coloring register allocator
-   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Michael Matz <matz@suse.de>
    and Daniel Berlin <dan@cgsoftware.com>.
 
@@ -84,6 +84,7 @@
    * use the constraints from asms
   */
 
+static int first_hard_reg (HARD_REG_SET);
 static struct obstack ra_obstack;
 static void create_insn_info (struct df *);
 static void free_insn_info (void);
@@ -147,6 +148,7 @@ int orig_max_uid;
 HARD_REG_SET never_use_colors;
 HARD_REG_SET usable_regs[N_REG_CLASSES];
 unsigned int num_free_regs[N_REG_CLASSES];
+int single_reg_in_regclass[N_REG_CLASSES];
 HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
 HARD_REG_SET invalid_mode_change_regs;
 unsigned char byte2bitcount[256];
@@ -212,6 +214,21 @@ hard_regs_count (HARD_REG_SET rs)
   return count;
 }
 
+/* Returns the first hardreg in HARD_REG_SET RS. Assumes there is at
+   least one reg in the set.  */
+
+static int
+first_hard_reg (HARD_REG_SET rs)
+{
+  int c;
+  
+  for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
+    if (TEST_HARD_REG_BIT (rs, c))
+      break;
+  gcc_assert (c < FIRST_PSEUDO_REGISTER);
+  return c;
+}
+
 /* Basically like emit_move_insn (i.e. validifies constants and such),
    but also handle MODE_CC moves (but then the operands must already
    be basically valid.  */
@@ -276,8 +293,7 @@ create_insn_info (struct df *df)
       act_refs += n;
       insn_df[uid].num_uses = n;
     }
-  if (refs_for_insn_df + (df->def_id + df->use_id) < act_refs)
-    abort ();
+  gcc_assert (refs_for_insn_df + (df->def_id + df->use_id) >= act_refs);
 }
 
 /* Free the insn_df structures.  */
@@ -300,8 +316,7 @@ struct web *
 find_subweb (struct web *web, rtx reg)
 {
   struct web *w;
-  if (GET_CODE (reg) != SUBREG)
-    abort ();
+  gcc_assert (GET_CODE (reg) == SUBREG);
   for (w = web->subreg_next; w; w = w->subreg_next)
     if (GET_MODE (w->orig_x) == GET_MODE (reg)
        && SUBREG_BYTE (w->orig_x) == SUBREG_BYTE (reg))
@@ -472,26 +487,26 @@ init_ra (void)
     {
       if (! CAN_ELIMINATE (eliminables[j].from, eliminables[j].to)
          || (eliminables[j].to == STACK_POINTER_REGNUM && need_fp))
-       for (i = HARD_REGNO_NREGS (eliminables[j].from, Pmode); i--;)
+       for (i = hard_regno_nregs[eliminables[j].from][Pmode]; i--;)
          SET_HARD_REG_BIT (never_use_colors, eliminables[j].from + i);
     }
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
   if (need_fp)
-    for (i = HARD_REGNO_NREGS (HARD_FRAME_POINTER_REGNUM, Pmode); i--;)
+    for (i = hard_regno_nregs[HARD_FRAME_POINTER_REGNUM][Pmode]; i--;)
       SET_HARD_REG_BIT (never_use_colors, HARD_FRAME_POINTER_REGNUM + i);
 #endif
 
 #else
   if (need_fp)
-    for (i = HARD_REGNO_NREGS (FRAME_POINTER_REGNUM, Pmode); i--;)
+    for (i = hard_regno_nregs[FRAME_POINTER_REGNUM][Pmode]; i--;)
       SET_HARD_REG_BIT (never_use_colors, FRAME_POINTER_REGNUM + i);
 #endif
 
   /* Stack and argument pointer are also rather useless to us.  */
-  for (i = HARD_REGNO_NREGS (STACK_POINTER_REGNUM, Pmode); i--;)
+  for (i = hard_regno_nregs[STACK_POINTER_REGNUM][Pmode]; i--;)
     SET_HARD_REG_BIT (never_use_colors, STACK_POINTER_REGNUM + i);
 
-  for (i = HARD_REGNO_NREGS (ARG_POINTER_REGNUM, Pmode); i--;)
+  for (i = hard_regno_nregs[ARG_POINTER_REGNUM][Pmode]; i--;)
     SET_HARD_REG_BIT (never_use_colors, ARG_POINTER_REGNUM + i);
 
   for (i = 0; i < 256; i++)
@@ -515,6 +530,10 @@ init_ra (void)
       size = hard_regs_count (rs);
       num_free_regs[i] = size;
       COPY_HARD_REG_SET (usable_regs[i], rs);
+      if (size == 1)
+       single_reg_in_regclass[i] = first_hard_reg (rs);
+      else
+       single_reg_in_regclass[i] = -1;
     }
 
   /* Setup hardregs_for_mode[].
@@ -528,7 +547,7 @@ init_ra (void)
       for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
        if (HARD_REGNO_MODE_OK (reg, i)
            /* Ignore VOIDmode and similar things.  */
-           && (size = HARD_REGNO_NREGS (reg, i)) != 0
+           && (size = hard_regno_nregs[reg][i]) != 0
            && (reg + size) <= FIRST_PSEUDO_REGISTER)
          {
            while (size--)
@@ -558,8 +577,7 @@ init_ra (void)
        an_unusable_color++)
     if (TEST_HARD_REG_BIT (never_use_colors, an_unusable_color))
       break;
-  if (an_unusable_color == FIRST_PSEUDO_REGISTER)
-    abort ();
+  gcc_assert (an_unusable_color != FIRST_PSEUDO_REGISTER);
 
   orig_max_uid = get_max_uid ();
   compute_bb_for_insn ();
@@ -570,7 +588,7 @@ init_ra (void)
   gcc_obstack_init (&ra_obstack);
 }
 
-/* Check the consistency of DF.  This aborts if it violates some
+/* Check the consistency of DF.  This asserts if it violates some
    invariances we expect.  */
 
 static void
@@ -601,19 +619,21 @@ check_df (struct df *df)
       {
        bitmap_clear (b);
        for (link = DF_INSN_DEFS (df, insn); link; link = link->next)
-         if (!link->ref || bitmap_bit_p (empty_defs, DF_REF_ID (link->ref))
-             || bitmap_bit_p (b, DF_REF_ID (link->ref)))
-           abort ();
-         else
+         {
+           gcc_assert (link->ref);
+           gcc_assert (!bitmap_bit_p (empty_defs, DF_REF_ID (link->ref)));
+           gcc_assert (!bitmap_bit_p (b, DF_REF_ID (link->ref)));
            bitmap_set_bit (b, DF_REF_ID (link->ref));
+         }
 
        bitmap_clear (b);
        for (link = DF_INSN_USES (df, insn); link; link = link->next)
-         if (!link->ref || bitmap_bit_p (empty_uses, DF_REF_ID (link->ref))
-             || bitmap_bit_p (b, DF_REF_ID (link->ref)))
-           abort ();
-         else
+         {
+           gcc_assert (link->ref);
+           gcc_assert (!bitmap_bit_p (empty_uses, DF_REF_ID (link->ref)));
+           gcc_assert (!bitmap_bit_p (b, DF_REF_ID (link->ref)));
            bitmap_set_bit (b, DF_REF_ID (link->ref));
+         }
       }
 
   /* Now the same for the chains per register number.  */
@@ -621,19 +641,21 @@ check_df (struct df *df)
     {
       bitmap_clear (b);
       for (link = df->regs[regno].defs; link; link = link->next)
-       if (!link->ref || bitmap_bit_p (empty_defs, DF_REF_ID (link->ref))
-           || bitmap_bit_p (b, DF_REF_ID (link->ref)))
-         abort ();
-       else
+       {
+         gcc_assert (link->ref);
+         gcc_assert (!bitmap_bit_p (empty_defs, DF_REF_ID (link->ref)));
+         gcc_assert (!bitmap_bit_p (b, DF_REF_ID (link->ref)));
          bitmap_set_bit (b, DF_REF_ID (link->ref));
+       }
 
       bitmap_clear (b);
       for (link = df->regs[regno].uses; link; link = link->next)
-       if (!link->ref || bitmap_bit_p (empty_uses, DF_REF_ID (link->ref))
-           || bitmap_bit_p (b, DF_REF_ID (link->ref)))
-         abort ();
-       else
+       {
+         gcc_assert (link->ref);
+         gcc_assert (!bitmap_bit_p (empty_uses, DF_REF_ID (link->ref)));
+         gcc_assert (!bitmap_bit_p (b, DF_REF_ID (link->ref)));
          bitmap_set_bit (b, DF_REF_ID (link->ref));
+       }
     }
 
   BITMAP_XFREE (empty_uses);
@@ -647,7 +669,7 @@ void
 reg_alloc (void)
 {
   int changed;
-  FILE *ra_dump_file = rtl_dump_file;
+  FILE *ra_dump_file = dump_file;
   rtx last = get_last_insn ();
 
   if (! INSN_P (last))
@@ -660,7 +682,9 @@ reg_alloc (void)
   if (last)
     {
       edge e;
-      for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+      edge_iterator ei;
+
+      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
        {
          basic_block bb = e->src;
          last = BB_END (bb);
@@ -691,16 +715,16 @@ reg_alloc (void)
              break;
       case 6: debug_new_regalloc = DUMP_VALIDIFY; break;
     }
-  if (!rtl_dump_file)
+  if (!dump_file)
     debug_new_regalloc = 0;
 
   /* Run regclass first, so we know the preferred and alternate classes
      for each pseudo.  Deactivate emitting of debug info, if it's not
      explicitly requested.  */
   if ((debug_new_regalloc & DUMP_REGCLASS) == 0)
-    rtl_dump_file = NULL;
-  regclass (get_insns (), max_reg_num (), rtl_dump_file);
-  rtl_dump_file = ra_dump_file;
+    dump_file = NULL;
+  regclass (get_insns (), max_reg_num (), dump_file);
+  dump_file = ra_dump_file;
 
   /* We don't use those NOTEs, and as we anyway change all registers,
      they only make problems later.  */
@@ -752,16 +776,16 @@ reg_alloc (void)
       /* First collect all the register refs and put them into
         chains per insn, and per regno.  In later passes only update
          that info from the new and modified insns.  */
-      df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1,
+      df_analyze (df, (ra_pass == 1) ? 0 : (bitmap) -1,
                  DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN | DF_FOR_REGALLOC);
 
       if ((debug_new_regalloc & DUMP_DF) != 0)
        {
          rtx insn;
-         df_dump (df, DF_HARD_REGS, rtl_dump_file);
+         df_dump (df, DF_HARD_REGS, dump_file);
          for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
             if (INSN_P (insn))
-             df_insn_debug_regno (df, insn, rtl_dump_file);
+             df_insn_debug_regno (df, insn, dump_file);
        }
       check_df (df);
 
@@ -795,7 +819,7 @@ reg_alloc (void)
             therefore repeat some things, including some initialization
             of global data structures.  */
          if ((debug_new_regalloc & DUMP_REGCLASS) == 0)
-           rtl_dump_file = NULL;
+           dump_file = NULL;
          /* We have new pseudos (the stackwebs).  */
          allocate_reg_info (max_reg_num (), FALSE, FALSE);
          /* And new insns.  */
@@ -806,8 +830,8 @@ reg_alloc (void)
          reg_scan_update (get_insns (), NULL, max_regno);
          max_regno = max_reg_num ();
          /* And they need useful classes too.  */
-         regclass (get_insns (), max_reg_num (), rtl_dump_file);
-         rtl_dump_file = ra_dump_file;
+         regclass (get_insns (), max_reg_num (), dump_file);
+         dump_file = ra_dump_file;
 
          /* Remember the number of defs and uses, so we can distinguish
             new from old refs in the next pass.  */
@@ -819,8 +843,8 @@ reg_alloc (void)
       dump_ra (df);
       if (changed && (debug_new_regalloc & DUMP_RTL) != 0)
        {
-         ra_print_rtl_with_bb (rtl_dump_file, get_insns ());
-         fflush (rtl_dump_file);
+         ra_print_rtl_with_bb (dump_file, get_insns ());
+         fflush (dump_file);
        }
 
       /* Reset the web lists.  */
@@ -838,15 +862,15 @@ reg_alloc (void)
   ra_debug_msg (DUMP_COSTS, "ticks for build-phase: %ld\n", ticks_build);
   ra_debug_msg (DUMP_COSTS, "ticks for rebuild-phase: %ld\n", ticks_rebuild);
   if ((debug_new_regalloc & (DUMP_FINAL_RTL | DUMP_RTL)) != 0)
-    ra_print_rtl_with_bb (rtl_dump_file, get_insns ());
+    ra_print_rtl_with_bb (dump_file, get_insns ());
 
   /* We might have new pseudos, so allocate the info arrays for them.  */
   if ((debug_new_regalloc & DUMP_SM) == 0)
-    rtl_dump_file = NULL;
+    dump_file = NULL;
   no_new_pseudos = 0;
   allocate_reg_info (max_reg_num (), FALSE, FALSE);
   no_new_pseudos = 1;
-  rtl_dump_file = ra_dump_file;
+  dump_file = ra_dump_file;
 
   /* Some spill insns could've been inserted after trapping calls, i.e.
      at the end of a basic block, which really ends at that call.
@@ -855,14 +879,14 @@ reg_alloc (void)
 
   /* Cleanup the flow graph.  */
   if ((debug_new_regalloc & DUMP_LAST_FLOW) == 0)
-    rtl_dump_file = NULL;
-  life_analysis (get_insns (), rtl_dump_file,
+    dump_file = NULL;
+  life_analysis (dump_file,
                 PROP_DEATH_NOTES | PROP_LOG_LINKS  | PROP_REG_INFO);
   cleanup_cfg (CLEANUP_EXPENSIVE);
   recompute_reg_usage (get_insns (), TRUE);
-  if (rtl_dump_file)
-    dump_flow_info (rtl_dump_file);
-  rtl_dump_file = ra_dump_file;
+  if (dump_file)
+    dump_flow_info (dump_file);
+  dump_file = ra_dump_file;
 
   /* update_equiv_regs() can't be called after register allocation.
      It might delete some pseudos, and insert other insns setting
@@ -882,16 +906,17 @@ reg_alloc (void)
   remove_suspicious_death_notes ();
 
   if ((debug_new_regalloc & DUMP_LAST_RTL) != 0)
-    ra_print_rtl_with_bb (rtl_dump_file, get_insns ());
-  dump_static_insn_cost (rtl_dump_file,
+    ra_print_rtl_with_bb (dump_file, get_insns ());
+  dump_static_insn_cost (dump_file,
                         "after allocation/spilling, before reload", NULL);
 
   /* Allocate the reg_equiv_memory_loc array for reload.  */
-  reg_equiv_memory_loc = xcalloc (max_regno, sizeof (rtx));
+  VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno);
+  reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0);
   /* And possibly initialize it.  */
   allocate_initial_values (reg_equiv_memory_loc);
   /* And one last regclass pass just before reload.  */
-  regclass (get_insns (), max_reg_num (), rtl_dump_file);
+  regclass (get_insns (), max_reg_num (), dump_file);
 }
 
 /*