i386.c (legitimize_tls_address): Generate tls_initial_exec_64_sun only when !TARGET_X32.
[gcc.git] / gcc / ira-color.c
index c7a7033ebc145c246dedeecda4c199484c1fe20c..300c3b8f92256b754e79133f58eb2476ef427cbb 100644 (file)
@@ -1,5 +1,5 @@
 /* IRA allocation based on graph coloring.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -53,7 +53,7 @@ struct allocno_hard_regs
   HARD_REG_SET set;
   /* Overall (spilling) cost of all allocnos with given register
      set.  */
-  long long int cost;
+  HOST_WIDEST_INT cost;
 };
 
 typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
@@ -229,7 +229,7 @@ init_allocno_hard_regs (void)
 /* Add (or update info about) allocno hard registers with SET and
    COST.  */
 static allocno_hard_regs_t
-add_allocno_hard_regs (HARD_REG_SET set, long long int cost)
+add_allocno_hard_regs (HARD_REG_SET set, HOST_WIDEST_INT cost)
 {
   struct allocno_hard_regs temp;
   allocno_hard_regs_t hv;
@@ -498,7 +498,7 @@ print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
        fprintf (f, " ");
       fprintf (f, "%d:(", node->preorder_num);
       print_hard_reg_set (f, node->hard_regs->set, false);
-      fprintf (f, ")@%lld\n", node->hard_regs->cost);
+      fprintf (f, ")@" HOST_WIDEST_INT_PRINT_DEC "\n", node->hard_regs->cost);
       print_hard_regs_subforest (f, node->first, level + 1);
     }
 }
@@ -821,7 +821,6 @@ setup_left_conflict_sizes_p (ira_allocno_t a)
   node_preorder_num = node->preorder_num;
   COPY_HARD_REG_SET (node_set, node->hard_regs->set);
   node_check_tick++;
-  curr_allocno_process++;
   for (k = 0; k < nobj; k++)
     {
       ira_object_t obj = ALLOCNO_OBJECT (a, k);
@@ -838,12 +837,10 @@ setup_left_conflict_sizes_p (ira_allocno_t a)
 
          conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
          if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
-             || conflict_data->last_process == curr_allocno_process
              || ! hard_reg_set_intersect_p (profitable_hard_regs,
                                             conflict_data
                                             ->profitable_hard_regs))
            continue;
-         conflict_data->last_process = curr_allocno_process;
          conflict_node = conflict_data->hard_regs_node;
          COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
          if (hard_reg_set_subset_p (node_set, conflict_node_set))
@@ -1067,7 +1064,7 @@ setup_profitable_hard_regs (void)
                {
                  int num = OBJECT_SUBWORD (conflict_obj);
                  
-                 if (WORDS_BIG_ENDIAN)
+                 if (REG_WORDS_BIG_ENDIAN)
                    CLEAR_HARD_REG_BIT
                      (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
                       hard_regno + nobj - num - 1);
@@ -1451,7 +1448,7 @@ check_hard_reg_p (ira_allocno_t a, int hard_regno,
       
       if (nregs == nwords)
        {
-         if (WORDS_BIG_ENDIAN)
+         if (REG_WORDS_BIG_ENDIAN)
            set_to_test_start = nwords - j - 1;
          else
            set_to_test_start = j;
@@ -1610,7 +1607,7 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
                    {
                      int num = OBJECT_SUBWORD (conflict_obj);
 
-                     if (WORDS_BIG_ENDIAN)
+                     if (REG_WORDS_BIG_ENDIAN)
                        SET_HARD_REG_BIT (conflicting_regs[word],
                                          hard_regno + n_objects - num - 1);
                      else
@@ -1670,7 +1667,6 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
       update_conflict_hard_regno_costs (full_costs, aclass, false);
     }
   min_cost = min_full_cost = INT_MAX;
-
   /* We don't care about giving callee saved registers to allocnos no
      living through calls because call clobbered registers are
      allocated first (it is usual practice to put them first in
@@ -1797,8 +1793,14 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
   ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
   ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
   int diff, a1_freq, a2_freq, a1_num, a2_num;
-
-  if ((diff = (int) ALLOCNO_CLASS (a2) - ALLOCNO_CLASS (a1)) != 0)
+  int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
+
+  /* Push pseudos requiring less hard registers first.  It means that
+     we will assign pseudos requiring more hard registers first
+     avoiding creation small holes in free hard register file into
+     which the pseudos requiring more hard registers can not fit.  */
+  if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
+              - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
     return diff;
   a1_freq = ALLOCNO_FREQ (a1);
   a2_freq = ALLOCNO_FREQ (a2);
@@ -2005,7 +2007,7 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
   edge e;
   VEC (edge, heap) *edges;
 
-  ira_assert (loop_node->loop != NULL
+  ira_assert (current_loops != NULL && loop_node->loop != NULL
              && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
   freq = 0;
   if (! exit_p)
@@ -2656,14 +2658,19 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
   edge e;
   edge_iterator ei;
 
-  ira_assert (loop_tree_node->loop != NULL);
-  fprintf (ira_dump_file,
-          "\n  Loop %d (parent %d, header bb%d, depth %d)\n    bbs:",
-          loop_tree_node->loop->num,
-          (loop_tree_node->parent == NULL
-           ? -1 : loop_tree_node->parent->loop->num),
-          loop_tree_node->loop->header->index,
-          loop_depth (loop_tree_node->loop));
+  if (loop_tree_node->parent == NULL)
+    fprintf (ira_dump_file,
+            "\n  Loop 0 (parent -1, header bb%d, depth 0)\n    bbs:",
+            NUM_FIXED_BLOCKS);
+  else
+    {
+      ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
+      fprintf (ira_dump_file,
+              "\n  Loop %d (parent %d, header bb%d, depth %d)\n    bbs:",
+              loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
+              loop_tree_node->loop->header->index,
+              loop_depth (loop_tree_node->loop));
+    }
   for (subloop_node = loop_tree_node->children;
        subloop_node != NULL;
        subloop_node = subloop_node->next)
@@ -2675,7 +2682,7 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
              && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
                  != loop_tree_node))
            fprintf (ira_dump_file, "(->%d:l%d)",
-                    e->dest->index, dest_loop_node->loop->num);
+                    e->dest->index, dest_loop_node->loop_num);
       }
   fprintf (ira_dump_file, "\n    all:");
   EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
@@ -2934,8 +2941,9 @@ move_spill_restore (void)
                 copies and the reload pass can spill the allocno set
                 by copy although the allocno will not get memory
                 slot.  */
-             || ira_reg_equiv_invariant_p[regno]
-             || ira_reg_equiv_const[regno] != NULL_RTX
+             || (regno < ira_reg_equiv_len
+                 && (ira_reg_equiv_invariant_p[regno]
+                     || ira_reg_equiv_const[regno] != NULL_RTX))
              || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
            continue;
          mode = ALLOCNO_MODE (a);
@@ -3005,7 +3013,7 @@ move_spill_restore (void)
                  fprintf
                    (ira_dump_file,
                     "      Moving spill/restore for a%dr%d up from loop %d",
-                    ALLOCNO_NUM (a), regno, loop_node->loop->num);
+                    ALLOCNO_NUM (a), regno, loop_node->loop_num);
                  fprintf (ira_dump_file, " - profit %d\n", -cost);
                }
              changed_p = true;