comparison gcc/ira-color.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* IRA allocation based on graph coloring. 1 /* IRA allocation based on graph coloring.
2 Copyright (C) 2006-2018 Free Software Foundation, Inc. 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>. 3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
149 /* Allocnos in thread forms a cycle list through the following 149 /* Allocnos in thread forms a cycle list through the following
150 member. */ 150 member. */
151 ira_allocno_t next_thread_allocno; 151 ira_allocno_t next_thread_allocno;
152 /* All thread frequency. Defined only for first thread allocno. */ 152 /* All thread frequency. Defined only for first thread allocno. */
153 int thread_freq; 153 int thread_freq;
154 /* Sum of frequencies of hard register preferences of the allocno. */
155 int hard_reg_prefs;
154 }; 156 };
155 157
156 /* See above. */ 158 /* See above. */
157 typedef struct allocno_color_data *allocno_color_data_t; 159 typedef struct allocno_color_data *allocno_color_data_t;
158 160
216 /* Compares allocno hard registers V1 and V2. */ 218 /* Compares allocno hard registers V1 and V2. */
217 inline bool 219 inline bool
218 allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1, 220 allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1,
219 const allocno_hard_regs *hv2) 221 const allocno_hard_regs *hv2)
220 { 222 {
221 return hard_reg_set_equal_p (hv1->set, hv2->set); 223 return hv1->set == hv2->set;
222 } 224 }
223 225
224 /* Hash table of unique allocno hard registers. */ 226 /* Hash table of unique allocno hard registers. */
225 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab; 227 static hash_table<allocno_hard_regs_hasher> *allocno_hard_regs_htab;
226 228
259 { 261 {
260 struct allocno_hard_regs temp; 262 struct allocno_hard_regs temp;
261 allocno_hard_regs_t hv; 263 allocno_hard_regs_t hv;
262 264
263 gcc_assert (! hard_reg_set_empty_p (set)); 265 gcc_assert (! hard_reg_set_empty_p (set));
264 COPY_HARD_REG_SET (temp.set, set); 266 temp.set = set;
265 if ((hv = find_hard_regs (&temp)) != NULL) 267 if ((hv = find_hard_regs (&temp)) != NULL)
266 hv->cost += cost; 268 hv->cost += cost;
267 else 269 else
268 { 270 {
269 hv = ((struct allocno_hard_regs *) 271 hv = ((struct allocno_hard_regs *)
270 ira_allocate (sizeof (struct allocno_hard_regs))); 272 ira_allocate (sizeof (struct allocno_hard_regs)));
271 COPY_HARD_REG_SET (hv->set, set); 273 hv->set = set;
272 hv->cost = cost; 274 hv->cost = cost;
273 allocno_hard_regs_vec.safe_push (hv); 275 allocno_hard_regs_vec.safe_push (hv);
274 insert_hard_regs (hv); 276 insert_hard_regs (hv);
275 } 277 }
276 return hv; 278 return hv;
369 allocno_hard_regs_t hv2; 371 allocno_hard_regs_t hv2;
370 372
371 start = hard_regs_node_vec.length (); 373 start = hard_regs_node_vec.length ();
372 for (node = *roots; node != NULL; node = node->next) 374 for (node = *roots; node != NULL; node = node->next)
373 { 375 {
374 if (hard_reg_set_equal_p (hv->set, node->hard_regs->set)) 376 if (hv->set == node->hard_regs->set)
375 return; 377 return;
376 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set)) 378 if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
377 { 379 {
378 add_allocno_hard_regs_to_forest (&node->first, hv); 380 add_allocno_hard_regs_to_forest (&node->first, hv);
379 return; 381 return;
380 } 382 }
381 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set)) 383 if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
382 hard_regs_node_vec.safe_push (node); 384 hard_regs_node_vec.safe_push (node);
383 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set)) 385 else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
384 { 386 {
385 COPY_HARD_REG_SET (temp_set, hv->set); 387 temp_set = hv->set & node->hard_regs->set;
386 AND_HARD_REG_SET (temp_set, node->hard_regs->set);
387 hv2 = add_allocno_hard_regs (temp_set, hv->cost); 388 hv2 = add_allocno_hard_regs (temp_set, hv->cost);
388 add_allocno_hard_regs_to_forest (&node->first, hv2); 389 add_allocno_hard_regs_to_forest (&node->first, hv2);
389 } 390 }
390 } 391 }
391 if (hard_regs_node_vec.length () 392 if (hard_regs_node_vec.length ()
396 for (i = start; 397 for (i = start;
397 i < hard_regs_node_vec.length (); 398 i < hard_regs_node_vec.length ();
398 i++) 399 i++)
399 { 400 {
400 node = hard_regs_node_vec[i]; 401 node = hard_regs_node_vec[i];
401 IOR_HARD_REG_SET (temp_set, node->hard_regs->set); 402 temp_set |= node->hard_regs->set;
402 } 403 }
403 hv = add_allocno_hard_regs (temp_set, hv->cost); 404 hv = add_allocno_hard_regs (temp_set, hv->cost);
404 new_node = create_new_allocno_hard_regs_node (hv); 405 new_node = create_new_allocno_hard_regs_node (hv);
405 prev = NULL; 406 prev = NULL;
406 for (i = start; 407 for (i = start;
477 478
478 /* Print hard reg set SET to F. */ 479 /* Print hard reg set SET to F. */
479 static void 480 static void
480 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p) 481 print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
481 { 482 {
482 int i, start; 483 int i, start, end;
483 484
484 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++) 485 for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
485 { 486 {
486 if (TEST_HARD_REG_BIT (set, i)) 487 bool reg_included = TEST_HARD_REG_BIT (set, i);
487 { 488
488 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1)) 489 if (reg_included)
490 {
491 if (start == -1)
489 start = i; 492 start = i;
490 } 493 end = i;
491 if (start >= 0 494 }
492 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i))) 495 if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
493 { 496 {
494 if (start == i - 1) 497 if (start == end)
495 fprintf (f, " %d", start); 498 fprintf (f, " %d", start);
496 else if (start == i - 2) 499 else if (start == end + 1)
497 fprintf (f, " %d %d", start, start + 1); 500 fprintf (f, " %d %d", start, end);
498 else 501 else
499 fprintf (f, " %d-%d", start, i - 1); 502 fprintf (f, " %d-%d", start, end);
500 start = -1; 503 start = -1;
501 } 504 }
502 } 505 }
503 if (new_line_p) 506 if (new_line_p)
504 fprintf (f, "\n"); 507 fprintf (f, "\n");
715 continue; 718 continue;
716 hv = (add_allocno_hard_regs 719 hv = (add_allocno_hard_regs
717 (allocno_data->profitable_hard_regs, 720 (allocno_data->profitable_hard_regs,
718 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))); 721 ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
719 } 722 }
720 SET_HARD_REG_SET (temp); 723 temp = ~ira_no_alloc_regs;
721 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
722 add_allocno_hard_regs (temp, 0); 724 add_allocno_hard_regs (temp, 0);
723 qsort (allocno_hard_regs_vec.address () + start, 725 qsort (allocno_hard_regs_vec.address () + start,
724 allocno_hard_regs_vec.length () - start, 726 allocno_hard_regs_vec.length () - start,
725 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare); 727 sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
726 for (i = start; 728 for (i = start;
831 HARD_REG_SET node_set; 833 HARD_REG_SET node_set;
832 834
833 nobj = ALLOCNO_NUM_OBJECTS (a); 835 nobj = ALLOCNO_NUM_OBJECTS (a);
834 data = ALLOCNO_COLOR_DATA (a); 836 data = ALLOCNO_COLOR_DATA (a);
835 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start; 837 subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
836 COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs); 838 profitable_hard_regs = data->profitable_hard_regs;
837 node = data->hard_regs_node; 839 node = data->hard_regs_node;
838 node_preorder_num = node->preorder_num; 840 node_preorder_num = node->preorder_num;
839 COPY_HARD_REG_SET (node_set, node->hard_regs->set); 841 node_set = node->hard_regs->set;
840 node_check_tick++; 842 node_check_tick++;
841 for (k = 0; k < nobj; k++) 843 for (k = 0; k < nobj; k++)
842 { 844 {
843 ira_object_t obj = ALLOCNO_OBJECT (a, k); 845 ira_object_t obj = ALLOCNO_OBJECT (a, k);
844 ira_object_t conflict_obj; 846 ira_object_t conflict_obj;
857 || ! hard_reg_set_intersect_p (profitable_hard_regs, 859 || ! hard_reg_set_intersect_p (profitable_hard_regs,
858 conflict_data 860 conflict_data
859 ->profitable_hard_regs)) 861 ->profitable_hard_regs))
860 continue; 862 continue;
861 conflict_node = conflict_data->hard_regs_node; 863 conflict_node = conflict_data->hard_regs_node;
862 COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set); 864 conflict_node_set = conflict_node->hard_regs->set;
863 if (hard_reg_set_subset_p (node_set, conflict_node_set)) 865 if (hard_reg_set_subset_p (node_set, conflict_node_set))
864 temp_node = node; 866 temp_node = node;
865 else 867 else
866 { 868 {
867 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set)); 869 ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
895 { 897 {
896 HARD_REG_SET temp_set; 898 HARD_REG_SET temp_set;
897 int j, n, hard_regno; 899 int j, n, hard_regno;
898 enum reg_class aclass; 900 enum reg_class aclass;
899 901
900 COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set); 902 temp_set = temp_node->hard_regs->set & profitable_hard_regs;
901 AND_HARD_REG_SET (temp_set, profitable_hard_regs);
902 aclass = ALLOCNO_CLASS (a); 903 aclass = ALLOCNO_CLASS (a);
903 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--) 904 for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
904 { 905 {
905 hard_regno = ira_class_hard_regs[aclass][j]; 906 hard_regno = ira_class_hard_regs[aclass][j];
906 if (TEST_HARD_REG_BIT (temp_set, hard_regno)) 907 if (TEST_HARD_REG_BIT (temp_set, hard_regno))
1040 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a))) 1041 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
1041 CLEAR_HARD_REG_SET (data->profitable_hard_regs); 1042 CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1042 else 1043 else
1043 { 1044 {
1044 mode = ALLOCNO_MODE (a); 1045 mode = ALLOCNO_MODE (a);
1045 COPY_HARD_REG_SET (data->profitable_hard_regs, 1046 data->profitable_hard_regs
1046 ira_useful_class_mode_regs[aclass][mode]); 1047 = ira_useful_class_mode_regs[aclass][mode];
1047 nobj = ALLOCNO_NUM_OBJECTS (a); 1048 nobj = ALLOCNO_NUM_OBJECTS (a);
1048 for (k = 0; k < nobj; k++) 1049 for (k = 0; k < nobj; k++)
1049 { 1050 {
1050 ira_object_t obj = ALLOCNO_OBJECT (a, k); 1051 ira_object_t obj = ALLOCNO_OBJECT (a, k);
1051 1052
1052 AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, 1053 data->profitable_hard_regs
1053 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); 1054 &= ~OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1054 } 1055 }
1055 } 1056 }
1056 } 1057 }
1057 /* Exclude hard regs already assigned for conflicting objects. */ 1058 /* Exclude hard regs already assigned for conflicting objects. */
1058 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi) 1059 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1089 CLEAR_HARD_REG_BIT 1090 CLEAR_HARD_REG_BIT
1090 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, 1091 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1091 hard_regno + num); 1092 hard_regno + num);
1092 } 1093 }
1093 else 1094 else
1094 AND_COMPL_HARD_REG_SET 1095 ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs
1095 (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, 1096 &= ~ira_reg_mode_hard_regset[hard_regno][mode];
1096 ira_reg_mode_hard_regset[hard_regno][mode]);
1097 } 1097 }
1098 } 1098 }
1099 } 1099 }
1100 /* Exclude too costly hard regs. */ 1100 /* Exclude too costly hard regs. */
1101 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi) 1101 EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1106 a = ira_allocnos[i]; 1106 a = ira_allocnos[i];
1107 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS 1107 if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1108 || empty_profitable_hard_regs (a)) 1108 || empty_profitable_hard_regs (a))
1109 continue; 1109 continue;
1110 data = ALLOCNO_COLOR_DATA (a); 1110 data = ALLOCNO_COLOR_DATA (a);
1111 mode = ALLOCNO_MODE (a);
1112 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL 1111 if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1113 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL) 1112 || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1114 { 1113 {
1115 class_size = ira_class_hard_regs_num[aclass]; 1114 class_size = ira_class_hard_regs_num[aclass];
1116 for (j = 0; j < class_size; j++) 1115 for (j = 0; j < class_size; j++)
1375 will try to minimize the data movement. Also for some 1374 will try to minimize the data movement. Also for some
1376 register classes bigger modes might be invalid, 1375 register classes bigger modes might be invalid,
1377 e.g. DImode for AREG on x86. For such cases the 1376 e.g. DImode for AREG on x86. For such cases the
1378 register move cost will be maximal. */ 1377 register move cost will be maximal. */
1379 mode = narrower_subreg_mode (mode, ALLOCNO_MODE (cp->second)); 1378 mode = narrower_subreg_mode (mode, ALLOCNO_MODE (cp->second));
1379 ira_init_register_move_cost_if_necessary (mode);
1380 1380
1381 cost = (cp->second == allocno 1381 cost = (cp->second == allocno
1382 ? ira_register_move_cost[mode][rclass][aclass] 1382 ? ira_register_move_cost[mode][rclass][aclass]
1383 : ira_register_move_cost[mode][aclass][rclass]); 1383 : ira_register_move_cost[mode][aclass][rclass]);
1384 if (decr_p) 1384 if (decr_p)
1573 } 1573 }
1574 1574
1575 /* Set up conflicting (through CONFLICT_REGS) for each object of 1575 /* Set up conflicting (through CONFLICT_REGS) for each object of
1576 allocno A and the start allocno profitable regs (through 1576 allocno A and the start allocno profitable regs (through
1577 START_PROFITABLE_REGS). Remember that the start profitable regs 1577 START_PROFITABLE_REGS). Remember that the start profitable regs
1578 exclude hard regs which can not hold value of mode of allocno A. 1578 exclude hard regs which cannot hold value of mode of allocno A.
1579 This covers mostly cases when multi-register value should be 1579 This covers mostly cases when multi-register value should be
1580 aligned. */ 1580 aligned. */
1581 static inline void 1581 static inline void
1582 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p, 1582 get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1583 HARD_REG_SET *conflict_regs, 1583 HARD_REG_SET *conflict_regs,
1588 1588
1589 nwords = ALLOCNO_NUM_OBJECTS (a); 1589 nwords = ALLOCNO_NUM_OBJECTS (a);
1590 for (i = 0; i < nwords; i++) 1590 for (i = 0; i < nwords; i++)
1591 { 1591 {
1592 obj = ALLOCNO_OBJECT (a, i); 1592 obj = ALLOCNO_OBJECT (a, i);
1593 COPY_HARD_REG_SET (conflict_regs[i], 1593 conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
1594 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1595 } 1594 }
1596 if (retry_p) 1595 if (retry_p)
1597 { 1596 *start_profitable_regs
1598 COPY_HARD_REG_SET (*start_profitable_regs, 1597 = (reg_class_contents[ALLOCNO_CLASS (a)]
1599 reg_class_contents[ALLOCNO_CLASS (a)]); 1598 &~ (ira_prohibited_class_mode_regs
1600 AND_COMPL_HARD_REG_SET (*start_profitable_regs, 1599 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]));
1601 ira_prohibited_class_mode_regs
1602 [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1603 }
1604 else 1600 else
1605 COPY_HARD_REG_SET (*start_profitable_regs, 1601 *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs;
1606 ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1607 } 1602 }
1608 1603
1609 /* Return true if HARD_REGNO is ok for assigning to allocno A with 1604 /* Return true if HARD_REGNO is ok for assigning to allocno A with
1610 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */ 1605 PROFITABLE_REGS and whose objects have CONFLICT_REGS. */
1611 static inline bool 1606 static inline bool
1658 int nregs = 0; 1653 int nregs = 0;
1659 1654
1660 ira_assert (hard_regno >= 0); 1655 ira_assert (hard_regno >= 0);
1661 for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--) 1656 for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
1662 if (!allocated_hardreg_p[hard_regno + i] 1657 if (!allocated_hardreg_p[hard_regno + i]
1663 && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i) 1658 && !crtl->abi->clobbers_full_reg_p (hard_regno + i)
1664 && !LOCAL_REGNO (hard_regno + i)) 1659 && !LOCAL_REGNO (hard_regno + i))
1665 nregs++; 1660 nregs++;
1666 return nregs; 1661 return nregs;
1667 } 1662 }
1668 1663
1802 else 1797 else
1803 SET_HARD_REG_BIT (conflicting_regs[word], 1798 SET_HARD_REG_BIT (conflicting_regs[word],
1804 hard_regno + num); 1799 hard_regno + num);
1805 } 1800 }
1806 else 1801 else
1807 IOR_HARD_REG_SET 1802 conflicting_regs[word]
1808 (conflicting_regs[word], 1803 |= ira_reg_mode_hard_regset[hard_regno][mode];
1809 ira_reg_mode_hard_regset[hard_regno][mode]);
1810 if (hard_reg_set_subset_p (profitable_hard_regs, 1804 if (hard_reg_set_subset_p (profitable_hard_regs,
1811 conflicting_regs[word])) 1805 conflicting_regs[word]))
1812 goto fail; 1806 goto fail;
1813 } 1807 }
1814 } 1808 }
2181 init_allocno_threads (void) 2175 init_allocno_threads (void)
2182 { 2176 {
2183 ira_allocno_t a; 2177 ira_allocno_t a;
2184 unsigned int j; 2178 unsigned int j;
2185 bitmap_iterator bi; 2179 bitmap_iterator bi;
2180 ira_pref_t pref;
2186 2181
2187 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi) 2182 EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2188 { 2183 {
2189 a = ira_allocnos[j]; 2184 a = ira_allocnos[j];
2190 /* Set up initial thread data: */ 2185 /* Set up initial thread data: */
2191 ALLOCNO_COLOR_DATA (a)->first_thread_allocno 2186 ALLOCNO_COLOR_DATA (a)->first_thread_allocno
2192 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a; 2187 = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
2193 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a); 2188 ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
2189 ALLOCNO_COLOR_DATA (a)->hard_reg_prefs = 0;
2190 for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref)
2191 ALLOCNO_COLOR_DATA (a)->hard_reg_prefs += pref->freq;
2194 } 2192 }
2195 } 2193 }
2196 2194
2197 2195
2198 2196
2259 int diff, freq1, freq2, a1_num, a2_num, pref1, pref2; 2257 int diff, freq1, freq2, a1_num, a2_num, pref1, pref2;
2260 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno; 2258 ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
2261 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno; 2259 ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
2262 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2); 2260 int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
2263 2261
2262 /* Push allocnos with minimal hard_reg_prefs first. */
2263 pref1 = ALLOCNO_COLOR_DATA (a1)->hard_reg_prefs;
2264 pref2 = ALLOCNO_COLOR_DATA (a2)->hard_reg_prefs;
2265 if ((diff = pref1 - pref2) != 0)
2266 return diff;
2267 /* Push allocnos with minimal conflict_allocno_hard_prefs first. */
2268 pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
2269 pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
2270 if ((diff = pref1 - pref2) != 0)
2271 return diff;
2264 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq; 2272 freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
2265 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq; 2273 freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
2266 if ((diff = freq1 - freq2) != 0) 2274 if ((diff = freq1 - freq2) != 0)
2267 return diff; 2275 return diff;
2268 2276
2270 return diff; 2278 return diff;
2271 2279
2272 /* Push pseudos requiring less hard registers first. It means that 2280 /* Push pseudos requiring less hard registers first. It means that
2273 we will assign pseudos requiring more hard registers first 2281 we will assign pseudos requiring more hard registers first
2274 avoiding creation small holes in free hard register file into 2282 avoiding creation small holes in free hard register file into
2275 which the pseudos requiring more hard registers can not fit. */ 2283 which the pseudos requiring more hard registers cannot fit. */
2276 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)] 2284 if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
2277 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0) 2285 - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
2278 return diff; 2286 return diff;
2279 2287
2280 freq1 = ALLOCNO_FREQ (a1); 2288 freq1 = ALLOCNO_FREQ (a1);
2283 return diff; 2291 return diff;
2284 2292
2285 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num; 2293 a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
2286 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num; 2294 a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
2287 if ((diff = a2_num - a1_num) != 0) 2295 if ((diff = a2_num - a1_num) != 0)
2288 return diff;
2289 /* Push allocnos with minimal conflict_allocno_hard_prefs first. */
2290 pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
2291 pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
2292 if ((diff = pref1 - pref2) != 0)
2293 return diff; 2296 return diff;
2294 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1); 2297 return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
2295 } 2298 }
2296 2299
2297 /* Sort bucket *BUCKET_PTR and return the result through 2300 /* Sort bucket *BUCKET_PTR and return the result through
2697 " Allocno a%dr%d of %s(%d) has %d avail. regs ", 2700 " Allocno a%dr%d of %s(%d) has %d avail. regs ",
2698 ALLOCNO_NUM (a), ALLOCNO_REGNO (a), 2701 ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2699 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n); 2702 reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2700 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false); 2703 print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2701 fprintf (ira_dump_file, ", %snode: ", 2704 fprintf (ira_dump_file, ", %snode: ",
2702 hard_reg_set_equal_p (data->profitable_hard_regs, 2705 data->profitable_hard_regs == data->hard_regs_node->hard_regs->set
2703 data->hard_regs_node->hard_regs->set)
2704 ? "" : "^"); 2706 ? "" : "^");
2705 print_hard_reg_set (ira_dump_file, 2707 print_hard_reg_set (ira_dump_file,
2706 data->hard_regs_node->hard_regs->set, false); 2708 data->hard_regs_node->hard_regs->set, false);
2707 for (i = 0; i < nwords; i++) 2709 for (i = 0; i < nwords; i++)
2708 { 2710 {
2827 if (ALLOCNO_HARD_REGNO (cp->first) != hard_regno) 2829 if (ALLOCNO_HARD_REGNO (cp->first) != hard_regno)
2828 continue; 2830 continue;
2829 } 2831 }
2830 else 2832 else
2831 gcc_unreachable (); 2833 gcc_unreachable ();
2834 ira_init_register_move_cost_if_necessary (allocno_mode);
2832 cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass]; 2835 cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass];
2833 } 2836 }
2834 return cost; 2837 return cost;
2835 } 2838 }
2836 2839
4386 4389
4387 n = ALLOCNO_NUM_OBJECTS (a); 4390 n = ALLOCNO_NUM_OBJECTS (a);
4388 for (i = 0; i < n; i++) 4391 for (i = 0; i < n; i++)
4389 { 4392 {
4390 ira_object_t obj = ALLOCNO_OBJECT (a, i); 4393 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4391 COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); 4394 saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
4392 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs); 4395 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs;
4393 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) 4396 if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
4394 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), 4397 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ira_need_caller_save_regs (a);
4395 call_used_reg_set);
4396 } 4398 }
4397 ALLOCNO_ASSIGNED_P (a) = false; 4399 ALLOCNO_ASSIGNED_P (a) = false;
4398 aclass = ALLOCNO_CLASS (a); 4400 aclass = ALLOCNO_CLASS (a);
4399 update_curr_costs (a); 4401 update_curr_costs (a);
4400 assign_hard_reg (a, true); 4402 assign_hard_reg (a, true);
4409 -= (ALLOCNO_MEMORY_COST (a) 4411 -= (ALLOCNO_MEMORY_COST (a)
4410 - (ALLOCNO_HARD_REG_COSTS (a) == NULL 4412 - (ALLOCNO_HARD_REG_COSTS (a) == NULL
4411 ? ALLOCNO_CLASS_COST (a) 4413 ? ALLOCNO_CLASS_COST (a)
4412 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index 4414 : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
4413 [aclass][hard_regno]])); 4415 [aclass][hard_regno]]));
4414 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 4416 if (ira_need_caller_save_p (a, hard_regno))
4415 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
4416 call_used_reg_set))
4417 { 4417 {
4418 ira_assert (flag_caller_saves); 4418 ira_assert (flag_caller_saves);
4419 caller_save_needed = 1; 4419 caller_save_needed = 1;
4420 } 4420 }
4421 } 4421 }
4433 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL) 4433 else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4434 fprintf (ira_dump_file, "\n"); 4434 fprintf (ira_dump_file, "\n");
4435 for (i = 0; i < n; i++) 4435 for (i = 0; i < n; i++)
4436 { 4436 {
4437 ira_object_t obj = ALLOCNO_OBJECT (a, i); 4437 ira_object_t obj = ALLOCNO_OBJECT (a, i);
4438 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]); 4438 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = saved[i];
4439 } 4439 }
4440 return reg_renumber[regno] >= 0; 4440 return reg_renumber[regno] >= 0;
4441 } 4441 }
4442 4442
4443 /* Sort pseudos according their usage frequencies (putting most 4443 /* Sort pseudos according their usage frequencies (putting most
4518 /* Try to assign hard registers to pseudos from 4518 /* Try to assign hard registers to pseudos from
4519 SPILLED_PSEUDO_REGS. */ 4519 SPILLED_PSEUDO_REGS. */
4520 for (i = 0; i < num; i++) 4520 for (i = 0; i < num; i++)
4521 { 4521 {
4522 regno = spilled_pseudo_regs[i]; 4522 regno = spilled_pseudo_regs[i];
4523 COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs); 4523 forbidden_regs = (bad_spill_regs
4524 IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]); 4524 | pseudo_forbidden_regs[regno]
4525 IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]); 4525 | pseudo_previous_regs[regno]);
4526 gcc_assert (reg_renumber[regno] < 0); 4526 gcc_assert (reg_renumber[regno] < 0);
4527 a = ira_regno_allocno_map[regno]; 4527 a = ira_regno_allocno_map[regno];
4528 ira_mark_allocation_change (regno); 4528 ira_mark_allocation_change (regno);
4529 ira_assert (reg_renumber[regno] < 0); 4529 ira_assert (reg_renumber[regno] < 0);
4530 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL) 4530 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4556 int cost, best_cost; 4556 int cost, best_cost;
4557 ira_copy_t cp, next_cp; 4557 ira_copy_t cp, next_cp;
4558 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno]; 4558 ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4559 rtx x; 4559 rtx x;
4560 bitmap_iterator bi; 4560 bitmap_iterator bi;
4561 struct ira_spilled_reg_stack_slot *slot = NULL; 4561 class ira_spilled_reg_stack_slot *slot = NULL;
4562 4562
4563 ira_assert (! ira_use_lra_p); 4563 ira_assert (! ira_use_lra_p);
4564 4564
4565 ira_assert (known_eq (inherent_size, PSEUDO_REGNO_BYTES (regno)) 4565 ira_assert (known_eq (inherent_size, PSEUDO_REGNO_BYTES (regno))
4566 && known_le (inherent_size, total_size) 4566 && known_le (inherent_size, total_size)
4668 TOTAL_SIZE was allocated for REGNO. We store this info for 4668 TOTAL_SIZE was allocated for REGNO. We store this info for
4669 subsequent ira_reuse_stack_slot calls. */ 4669 subsequent ira_reuse_stack_slot calls. */
4670 void 4670 void
4671 ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size) 4671 ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size)
4672 { 4672 {
4673 struct ira_spilled_reg_stack_slot *slot; 4673 class ira_spilled_reg_stack_slot *slot;
4674 int slot_num; 4674 int slot_num;
4675 ira_allocno_t allocno; 4675 ira_allocno_t allocno;
4676 4676
4677 ira_assert (! ira_use_lra_p); 4677 ira_assert (! ira_use_lra_p);
4678 4678
4698 /* Return spill cost for pseudo-registers whose numbers are in array 4698 /* Return spill cost for pseudo-registers whose numbers are in array
4699 REGNOS (with a negative number as an end marker) for reload with 4699 REGNOS (with a negative number as an end marker) for reload with
4700 given IN and OUT for INSN. Return also number points (through 4700 given IN and OUT for INSN. Return also number points (through
4701 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and 4701 EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4702 the register pressure is high, number of references of the 4702 the register pressure is high, number of references of the
4703 pseudo-registers (through NREFS), number of callee-clobbered 4703 pseudo-registers (through NREFS), the number of psuedo registers
4704 hard-registers occupied by the pseudo-registers (through 4704 whose allocated register wouldn't need saving in the prologue
4705 CALL_USED_COUNT), and the first hard regno occupied by the 4705 (through CALL_USED_COUNT), and the first hard regno occupied by the
4706 pseudo-registers (through FIRST_HARD_REGNO). */ 4706 pseudo-registers (through FIRST_HARD_REGNO). */
4707 static int 4707 static int
4708 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn, 4708 calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn,
4709 int *excess_pressure_live_length, 4709 int *excess_pressure_live_length,
4710 int *nrefs, int *call_used_count, int *first_hard_regno) 4710 int *nrefs, int *call_used_count, int *first_hard_regno)
4711 { 4711 {
4712 int i, cost, regno, hard_regno, j, count, saved_cost, nregs; 4712 int i, cost, regno, hard_regno, count, saved_cost;
4713 bool in_p, out_p; 4713 bool in_p, out_p;
4714 int length; 4714 int length;
4715 ira_allocno_t a; 4715 ira_allocno_t a;
4716 4716
4717 *nrefs = 0; 4717 *nrefs = 0;
4724 hard_regno = reg_renumber[regno]; 4724 hard_regno = reg_renumber[regno];
4725 ira_assert (hard_regno >= 0); 4725 ira_assert (hard_regno >= 0);
4726 a = ira_regno_allocno_map[regno]; 4726 a = ira_regno_allocno_map[regno];
4727 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a); 4727 length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4728 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a); 4728 cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4729 nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (a)); 4729 if (in_hard_reg_set_p (crtl->abi->full_reg_clobbers (),
4730 for (j = 0; j < nregs; j++) 4730 ALLOCNO_MODE (a), hard_regno))
4731 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4732 break;
4733 if (j == nregs)
4734 count++; 4731 count++;
4735 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno; 4732 in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4736 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno; 4733 out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4737 if ((in_p || out_p) 4734 if ((in_p || out_p)
4738 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX) 4735 && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4850 only allocno live ranges. The algorithm is close to Chow's 4847 only allocno live ranges. The algorithm is close to Chow's
4851 priority coloring. */ 4848 priority coloring. */
4852 static void 4849 static void
4853 fast_allocation (void) 4850 fast_allocation (void)
4854 { 4851 {
4855 int i, j, k, num, class_size, hard_regno; 4852 int i, j, k, num, class_size, hard_regno, best_hard_regno, cost, min_cost;
4853 int *costs;
4856 #ifdef STACK_REGS 4854 #ifdef STACK_REGS
4857 bool no_stack_reg_p; 4855 bool no_stack_reg_p;
4858 #endif 4856 #endif
4859 enum reg_class aclass; 4857 enum reg_class aclass;
4860 machine_mode mode; 4858 machine_mode mode;
4884 nr = ALLOCNO_NUM_OBJECTS (a); 4882 nr = ALLOCNO_NUM_OBJECTS (a);
4885 CLEAR_HARD_REG_SET (conflict_hard_regs); 4883 CLEAR_HARD_REG_SET (conflict_hard_regs);
4886 for (l = 0; l < nr; l++) 4884 for (l = 0; l < nr; l++)
4887 { 4885 {
4888 ira_object_t obj = ALLOCNO_OBJECT (a, l); 4886 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4889 IOR_HARD_REG_SET (conflict_hard_regs, 4887 conflict_hard_regs |= OBJECT_CONFLICT_HARD_REGS (obj);
4890 OBJECT_CONFLICT_HARD_REGS (obj));
4891 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) 4888 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4892 for (j = r->start; j <= r->finish; j++) 4889 for (j = r->start; j <= r->finish; j++)
4893 IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]); 4890 conflict_hard_regs |= used_hard_regs[j];
4894 } 4891 }
4895 aclass = ALLOCNO_CLASS (a); 4892 aclass = ALLOCNO_CLASS (a);
4896 ALLOCNO_ASSIGNED_P (a) = true; 4893 ALLOCNO_ASSIGNED_P (a) = true;
4897 ALLOCNO_HARD_REGNO (a) = -1; 4894 ALLOCNO_HARD_REGNO (a) = -1;
4898 if (hard_reg_set_subset_p (reg_class_contents[aclass], 4895 if (hard_reg_set_subset_p (reg_class_contents[aclass],
4901 mode = ALLOCNO_MODE (a); 4898 mode = ALLOCNO_MODE (a);
4902 #ifdef STACK_REGS 4899 #ifdef STACK_REGS
4903 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a); 4900 no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4904 #endif 4901 #endif
4905 class_size = ira_class_hard_regs_num[aclass]; 4902 class_size = ira_class_hard_regs_num[aclass];
4903 costs = ALLOCNO_HARD_REG_COSTS (a);
4904 min_cost = INT_MAX;
4905 best_hard_regno = -1;
4906 for (j = 0; j < class_size; j++) 4906 for (j = 0; j < class_size; j++)
4907 { 4907 {
4908 hard_regno = ira_class_hard_regs[aclass][j]; 4908 hard_regno = ira_class_hard_regs[aclass][j];
4909 #ifdef STACK_REGS 4909 #ifdef STACK_REGS
4910 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno 4910 if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4913 #endif 4913 #endif
4914 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs) 4914 if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4915 || (TEST_HARD_REG_BIT 4915 || (TEST_HARD_REG_BIT
4916 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno))) 4916 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4917 continue; 4917 continue;
4918 ALLOCNO_HARD_REGNO (a) = hard_regno; 4918 if (costs == NULL)
4919 for (l = 0; l < nr; l++)
4920 { 4919 {
4921 ira_object_t obj = ALLOCNO_OBJECT (a, l); 4920 best_hard_regno = hard_regno;
4922 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) 4921 break;
4923 for (k = r->start; k <= r->finish; k++)
4924 IOR_HARD_REG_SET (used_hard_regs[k],
4925 ira_reg_mode_hard_regset[hard_regno][mode]);
4926 } 4922 }
4927 break; 4923 cost = costs[j];
4924 if (min_cost > cost)
4925 {
4926 min_cost = cost;
4927 best_hard_regno = hard_regno;
4928 }
4929 }
4930 if (best_hard_regno < 0)
4931 continue;
4932 ALLOCNO_HARD_REGNO (a) = hard_regno = best_hard_regno;
4933 for (l = 0; l < nr; l++)
4934 {
4935 ira_object_t obj = ALLOCNO_OBJECT (a, l);
4936 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4937 for (k = r->start; k <= r->finish; k++)
4938 used_hard_regs[k] |= ira_reg_mode_hard_regset[hard_regno][mode];
4928 } 4939 }
4929 } 4940 }
4930 ira_free (sorted_allocnos); 4941 ira_free (sorted_allocnos);
4931 ira_free (used_hard_regs); 4942 ira_free (used_hard_regs);
4932 ira_free (allocno_priorities); 4943 ira_free (allocno_priorities);