OSDN Git Service

(fixup_var_refs_1, case ZERO_EXTRACT): Don't call fixup_memory_subreg
[pf3gnuchains/gcc-fork.git] / gcc / global.c
index e9941e6..a4f5ab1 100644 (file)
@@ -1,5 +1,5 @@
 /* Allocate registers for pseudo-registers that span basic blocks.
-   Copyright (C) 1987, 1988, 1991, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1991, 1994, 1996 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -75,7 +75,7 @@ static int max_allocno;
 /* Indexed by (pseudo) reg number, gives the allocno, or -1
    for pseudo registers already allocated by local_allocate.  */
 
-static int *reg_allocno;
+int *reg_allocno;
 
 /* Indexed by allocno, gives the reg number.  */
 
@@ -251,7 +251,7 @@ static int n_regs_set;
 
 static HARD_REG_SET eliminable_regset;
 
-static int allocno_compare     PROTO((int *, int *));
+static int allocno_compare     PROTO((const GENERIC_PTR, const GENERIC_PTR));
 static void global_conflicts   PROTO((void));
 static void expand_preferences PROTO((void));
 static void prune_preferences  PROTO((void));
@@ -584,27 +584,29 @@ global_alloc (file)
    Returns -1 (1) if *v1 should be allocated before (after) *v2.  */
 
 static int
-allocno_compare (v1, v2)
-     int *v1, *v2;
+allocno_compare (v1p, v2p)
+     const GENERIC_PTR v1p;
+     const GENERIC_PTR v2p;
 {
+  int v1 = *(int *)v1p, v2 = *(int *)v2p;
   /* Note that the quotient will never be bigger than
      the value of floor_log2 times the maximum number of
      times a register can occur in one insn (surely less than 100).
      Multiplying this by 10000 can't overflow.  */
   register int pri1
-    = (((double) (floor_log2 (allocno_n_refs[*v1]) * allocno_n_refs[*v1])
-       / allocno_live_length[*v1])
-       * 10000 * allocno_size[*v1]);
+    = (((double) (floor_log2 (allocno_n_refs[v1]) * allocno_n_refs[v1])
+       / allocno_live_length[v1])
+       * 10000 * allocno_size[v1]);
   register int pri2
-    = (((double) (floor_log2 (allocno_n_refs[*v2]) * allocno_n_refs[*v2])
-       / allocno_live_length[*v2])
-       * 10000 * allocno_size[*v2]);
+    = (((double) (floor_log2 (allocno_n_refs[v2]) * allocno_n_refs[v2])
+       / allocno_live_length[v2])
+       * 10000 * allocno_size[v2]);
   if (pri2 - pri1)
     return pri2 - pri1;
 
   /* If regs are equally good, sort by allocno,
      so that the results of qsort leave nothing to chance.  */
-  return *v1 - *v2;
+  return v1 - v2;
 }
 \f
 /* Scan the rtl code and record all conflicts and register preferences in the
@@ -869,7 +871,8 @@ prune_preferences ()
         we want to give the lower-priority allocno the first chance for
         these registers).  */
       for (j = i + 1; j < max_allocno; j++)
-       if (CONFLICTP (allocno, allocno_order[j]))
+       if (CONFLICTP (allocno, allocno_order[j])
+           || CONFLICTP (allocno_order[j], allocno))
          {
            COPY_HARD_REG_SET (temp,
                               hard_reg_full_preferences[allocno_order[j]]);
@@ -1085,7 +1088,14 @@ find_reg (allocno, losers, alt_regs_p, accept_call_clobbered, retrying)
          && CALLER_SAVE_PROFITABLE (allocno_n_refs[allocno],
                                     allocno_calls_crossed[allocno]))
        {
-         find_reg (allocno, losers, alt_regs_p, 1, retrying);
+         HARD_REG_SET new_losers;
+         if (! losers)
+           CLEAR_HARD_REG_SET (new_losers);
+         else
+           COPY_HARD_REG_SET (new_losers, losers);
+           
+         IOR_HARD_REG_SET(new_losers, losing_caller_save_reg_set);
+         find_reg (allocno, new_losers, alt_regs_p, 1, retrying);
          if (reg_renumber[allocno_reg[allocno]] >= 0)
            {
              caller_save_needed = 1;