OSDN Git Service

* struct-equiv.c (rtx_equiv_p): Fix POST_MODIFY case.
[pf3gnuchains/gcc-fork.git] / gcc / global.c
index 2186388..0642a70 100644 (file)
@@ -326,14 +326,12 @@ static void make_accurate_live_analysis (void);
 \f
 
 /* Perform allocation of pseudo-registers not allocated by local_alloc.
-   FILE is a file to output debugging information on,
-   or zero if such output is not desired.
 
    Return value is nonzero if reload failed
    and we must not do any more for this function.  */
 
 static int
-global_alloc (FILE *file)
+global_alloc (void)
 {
   int retval;
 #ifdef ELIMINABLE_REGS
@@ -442,14 +440,14 @@ global_alloc (FILE *file)
   /* Establish mappings from register number to allocation number
      and vice versa.  In the process, count the allocnos.  */
 
-  reg_allocno = xmalloc (max_regno * sizeof (int));
+  reg_allocno = XNEWVEC (int, max_regno);
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     reg_allocno[i] = -1;
 
   /* Initialize the shared-hard-reg mapping
      from the list of pairs that may share.  */
-  reg_may_share = xcalloc (max_regno, sizeof (int));
+  reg_may_share = XCNEWVEC (int, max_regno);
   for (x = regs_may_share; x; x = XEXP (XEXP (x, 1), 1))
     {
       int r1 = REGNO (XEXP (x, 0));
@@ -480,7 +478,7 @@ global_alloc (FILE *file)
     else
       reg_allocno[i] = -1;
 
-  allocno = xcalloc (max_allocno, sizeof (struct allocno));
+  allocno = XCNEWVEC (struct allocno, max_allocno);
 
   for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
     if (reg_allocno[i] >= 0)
@@ -528,9 +526,9 @@ global_alloc (FILE *file)
   /* We used to use alloca here, but the size of what it would try to
      allocate would occasionally cause it to exceed the stack limit and
      cause unpredictable core dumps.  Some examples were > 2Mb in size.  */
-  conflicts = xcalloc (max_allocno * allocno_row_words, sizeof (INT_TYPE));
+  conflicts = XCNEWVEC (INT_TYPE, max_allocno * allocno_row_words);
 
-  allocnos_live = xmalloc (allocno_row_words * sizeof (INT_TYPE));
+  allocnos_live = XNEWVEC (INT_TYPE, allocno_row_words);
 
   /* If there is work to be done (at least one reg to allocate),
      perform global conflict analysis and allocate the regs.  */
@@ -567,7 +565,7 @@ global_alloc (FILE *file)
 
       /* Determine the order to allocate the remaining pseudo registers.  */
 
-      allocno_order = xmalloc (max_allocno * sizeof (int));
+      allocno_order = XNEWVEC (int, max_allocno);
       for (i = 0; i < (size_t) max_allocno; i++)
        allocno_order[i] = i;
 
@@ -590,8 +588,8 @@ global_alloc (FILE *file)
 
       prune_preferences ();
 
-      if (file)
-       dump_conflicts (file);
+      if (dump_file)
+       dump_conflicts (dump_file);
 
       /* Try allocating them, one by one, in that order,
         except for parameters marked with reg_live_length[regno] == -2.  */
@@ -678,9 +676,9 @@ global_conflicts (void)
   int *block_start_allocnos;
 
   /* Make a vector that mark_reg_{store,clobber} will store in.  */
-  regs_set = xmalloc (max_parallel * sizeof (rtx) * 2);
+  regs_set = XNEWVEC (rtx, max_parallel * 2);
 
-  block_start_allocnos = xmalloc (max_allocno * sizeof (int));
+  block_start_allocnos = XNEWVEC (int, max_allocno);
 
   FOR_EACH_BB (b)
     {
@@ -949,7 +947,7 @@ prune_preferences (void)
 {
   int i;
   int num;
-  int *allocno_to_order = xmalloc (max_allocno * sizeof (int));
+  int *allocno_to_order = XNEWVEC (int, max_allocno);
 
   /* Scan least most important to most important.
      For each allocno, remove from preferences registers that cannot be used,
@@ -1241,7 +1239,8 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
      so we can use it instead.  */
   if (best_reg < 0 && !retrying
       /* Let's not bother with multi-reg allocnos.  */
-      && allocno[num].size == 1)
+      && allocno[num].size == 1
+      && REG_BASIC_BLOCK (allocno[num].reg) == REG_BLOCK_GLOBAL)
     {
       /* Count from the end, to find the least-used ones first.  */
       for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
@@ -1278,9 +1277,9 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
                 variables so as to avoid excess precision problems that occur
                 on an i386-unknown-sysv4.2 (unixware) host.  */
 
-             double tmp1 = ((double) local_reg_freq[regno]
+             double tmp1 = ((double) local_reg_freq[regno] * local_reg_n_refs[regno]
                            / local_reg_live_length[regno]);
-             double tmp2 = ((double) allocno[num].freq
+             double tmp2 = ((double) allocno[num].freq * allocno[num].n_refs
                             / allocno[num].live_length);
 
              if (tmp1 < tmp2)
@@ -1288,6 +1287,19 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
                  /* Hard reg REGNO was used less in total by local regs
                     than it would be used by this one allocno!  */
                  int k;
+                 if (dump_file)
+                   {
+                     fprintf (dump_file, "Regno %d better for global %d, ",
+                              regno, allocno[num].reg);
+                     fprintf (dump_file, "fr:%d, ll:%d, nr:%d ",
+                              allocno[num].freq, allocno[num].live_length,
+                              allocno[num].n_refs);
+                     fprintf (dump_file, "(was: fr:%d, ll:%d, nr:%d)\n",
+                              local_reg_freq[regno],
+                              local_reg_live_length[regno],
+                              local_reg_n_refs[regno]);
+                   }
+
                  for (k = 0; k < max_regno; k++)
                    if (reg_renumber[k] >= 0)
                      {
@@ -1296,7 +1308,12 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
                          = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (k)];
 
                        if (regno >= r && regno < endregno)
-                         reg_renumber[k] = -1;
+                         {
+                           if (dump_file)
+                             fprintf (dump_file,
+                                      "Local Reg %d now on stack\n", k);
+                           reg_renumber[k] = -1;
+                         }
                      }
 
                  best_reg = regno;
@@ -2281,7 +2298,7 @@ set_up_bb_rts_numbers (void)
   int i;
   int *rts_order;
   
-  rts_order = xmalloc (sizeof (int) * (n_basic_blocks - NUM_FIXED_BLOCKS));
+  rts_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
   post_order_compute (rts_order, false);
   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
     BB_INFO_BY_INDEX (rts_order [i])->rts_number = i;
@@ -2482,7 +2499,7 @@ make_accurate_live_analysis (void)
 }
 /* Run old register allocator.  Return TRUE if we must exit
    rest_of_compilation upon return.  */
-static void
+static unsigned int
 rest_of_handle_global_alloc (void)
 {
   bool failure;
@@ -2491,7 +2508,7 @@ rest_of_handle_global_alloc (void)
      pass fixing up any insns that are invalid.  */
 
   if (optimize)
-    failure = global_alloc (dump_file);
+    failure = global_alloc ();
   else
     {
       build_insn_chain (get_insns ());
@@ -2507,6 +2524,7 @@ rest_of_handle_global_alloc (void)
 
   gcc_assert (reload_completed || failure);
   reload_completed = !failure;
+  return 0;
 }
 
 struct tree_opt_pass pass_global_alloc =