comparison gcc/ira-conflicts.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 conflict builder. 1 /* IRA conflict builder.
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
29 #include "tm_p.h" 29 #include "tm_p.h"
30 #include "insn-config.h" 30 #include "insn-config.h"
31 #include "regs.h" 31 #include "regs.h"
32 #include "ira.h" 32 #include "ira.h"
33 #include "ira-int.h" 33 #include "ira-int.h"
34 #include "params.h"
35 #include "sparseset.h" 34 #include "sparseset.h"
36 #include "addresses.h" 35 #include "addresses.h"
37 36
38 /* This file contains code responsible for allocno conflict creation, 37 /* This file contains code responsible for allocno conflict creation,
39 allocno copy creation and allocno info accumulation on upper level 38 allocno copy creation and allocno info accumulation on upper level
111 conflict_bit_vec_words_num 110 conflict_bit_vec_words_num
112 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS) 111 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
113 / IRA_INT_BITS); 112 / IRA_INT_BITS);
114 allocated_words_num += conflict_bit_vec_words_num; 113 allocated_words_num += conflict_bit_vec_words_num;
115 if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE) 114 if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
116 > (uint64_t) IRA_MAX_CONFLICT_TABLE_SIZE * 1024 * 1024) 115 > (uint64_t) param_ira_max_conflict_table_size * 1024 * 1024)
117 { 116 {
118 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL) 117 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
119 fprintf 118 fprintf
120 (ira_dump_file, 119 (ira_dump_file,
121 "+++Conflict table will be too big(>%dMB) -- don't use it\n", 120 "+++Conflict table will be too big(>%dMB) -- don't use it\n",
122 IRA_MAX_CONFLICT_TABLE_SIZE); 121 param_ira_max_conflict_table_size);
123 return false; 122 return false;
124 } 123 }
125 } 124 }
126 125
127 conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *) 126 conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
287 return false; 286 return false;
288 } 287 }
289 288
290 if (! IN_RANGE (allocno_preferenced_hard_regno, 289 if (! IN_RANGE (allocno_preferenced_hard_regno,
291 0, FIRST_PSEUDO_REGISTER - 1)) 290 0, FIRST_PSEUDO_REGISTER - 1))
292 /* Can not be tied. */ 291 /* Cannot be tied. */
293 return false; 292 return false;
294 rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno); 293 rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
295 mode = ALLOCNO_MODE (a); 294 mode = ALLOCNO_MODE (a);
296 aclass = ALLOCNO_CLASS (a); 295 aclass = ALLOCNO_CLASS (a);
297 if (only_regs_p && insn != NULL_RTX 296 if (only_regs_p && insn != NULL_RTX
298 && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode]) 297 && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
299 /* It is already taken into account in ira-costs.c. */ 298 /* It is already taken into account in ira-costs.c. */
300 return false; 299 return false;
301 index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno]; 300 index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
302 if (index < 0) 301 if (index < 0)
303 /* Can not be tied. It is not in the allocno class. */ 302 /* Cannot be tied. It is not in the allocno class. */
304 return false; 303 return false;
305 ira_init_register_move_cost_if_necessary (mode); 304 ira_init_register_move_cost_if_necessary (mode);
306 if (HARD_REGISTER_P (reg1)) 305 if (HARD_REGISTER_P (reg1))
307 cost = ira_register_move_cost[mode][aclass][rclass] * freq; 306 cost = ira_register_move_cost[mode][aclass][rclass] * freq;
308 else 307 else
323 } 322 }
324 while (a != NULL); 323 while (a != NULL);
325 return true; 324 return true;
326 } 325 }
327 326
328 /* Process all of the output registers of the current insn which are 327 /* Return true if output operand OUTPUT and input operand INPUT of
329 not bound (BOUND_P) and the input register REG (its operand number 328 INSN can use the same register class for at least one alternative.
329 INSN is already described in recog_data and recog_op_alt. */
330 static bool
331 can_use_same_reg_p (rtx_insn *insn, int output, int input)
332 {
333 alternative_mask preferred = get_preferred_alternatives (insn);
334 for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
335 {
336 if (!TEST_BIT (preferred, nalt))
337 continue;
338
339 const operand_alternative *op_alt
340 = &recog_op_alt[nalt * recog_data.n_operands];
341 if (op_alt[input].matches == output)
342 return true;
343
344 if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
345 != NO_REGS)
346 return true;
347 }
348 return false;
349 }
350
351 /* Process all of the output registers of the current insn (INSN) which
352 are not bound (BOUND_P) and the input register REG (its operand number
330 OP_NUM) which dies in the insn as if there were a move insn between 353 OP_NUM) which dies in the insn as if there were a move insn between
331 them with frequency FREQ. */ 354 them with frequency FREQ. */
332 static void 355 static void
333 process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p) 356 process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
357 bool *bound_p)
334 { 358 {
335 int i; 359 int i;
336 rtx another_reg; 360 rtx another_reg;
337 361
338 gcc_assert (REG_SUBREG_P (reg)); 362 gcc_assert (REG_SUBREG_P (reg));
340 { 364 {
341 another_reg = recog_data.operand[i]; 365 another_reg = recog_data.operand[i];
342 366
343 if (!REG_SUBREG_P (another_reg) || op_num == i 367 if (!REG_SUBREG_P (another_reg) || op_num == i
344 || recog_data.operand_type[i] != OP_OUT 368 || recog_data.operand_type[i] != OP_OUT
345 || bound_p[i]) 369 || bound_p[i]
370 || (!can_use_same_reg_p (insn, i, op_num)
371 && (recog_data.constraints[op_num][0] != '%'
372 || !can_use_same_reg_p (insn, i, op_num + 1))
373 && (op_num == 0
374 || recog_data.constraints[op_num - 1][0] != '%'
375 || !can_use_same_reg_p (insn, i, op_num - 1))))
346 continue; 376 continue;
347 377
348 process_regs_for_copy (reg, another_reg, false, NULL, freq); 378 process_regs_for_copy (reg, another_reg, false, NULL, freq);
349 } 379 }
350 } 380 }
356 add_insn_allocno_copies (rtx_insn *insn) 386 add_insn_allocno_copies (rtx_insn *insn)
357 { 387 {
358 rtx set, operand, dup; 388 rtx set, operand, dup;
359 bool bound_p[MAX_RECOG_OPERANDS]; 389 bool bound_p[MAX_RECOG_OPERANDS];
360 int i, n, freq; 390 int i, n, freq;
361 HARD_REG_SET alts; 391 alternative_mask alts;
362 392
363 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); 393 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
364 if (freq == 0) 394 if (freq == 0)
365 freq = 1; 395 freq = 1;
366 if ((set = single_set (insn)) != NULL_RTX 396 if ((set = single_set (insn)) != NULL_RTX
377 } 407 }
378 /* Fast check of possibility of constraint or shuffle copies. If 408 /* Fast check of possibility of constraint or shuffle copies. If
379 there are no dead registers, there will be no such copies. */ 409 there are no dead registers, there will be no such copies. */
380 if (! find_reg_note (insn, REG_DEAD, NULL_RTX)) 410 if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
381 return; 411 return;
382 ira_setup_alts (insn, alts); 412 alts = ira_setup_alts (insn);
383 for (i = 0; i < recog_data.n_operands; i++) 413 for (i = 0; i < recog_data.n_operands; i++)
384 bound_p[i] = false; 414 bound_p[i] = false;
385 for (i = 0; i < recog_data.n_operands; i++) 415 for (i = 0; i < recog_data.n_operands; i++)
386 { 416 {
387 operand = recog_data.operand[i]; 417 operand = recog_data.operand[i];
410 /* If an operand dies, prefer its hard register for the output 440 /* If an operand dies, prefer its hard register for the output
411 operands by decreasing the hard register cost or creating 441 operands by decreasing the hard register cost or creating
412 the corresponding allocno copies. The cost will not 442 the corresponding allocno copies. The cost will not
413 correspond to a real move insn cost, so make the frequency 443 correspond to a real move insn cost, so make the frequency
414 smaller. */ 444 smaller. */
415 process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p); 445 process_reg_shuffles (insn, operand, i, freq < 8 ? 1 : freq / 8,
446 bound_p);
416 } 447 }
417 } 448 }
418 449
419 /* Add copies originated from BB given by LOOP_TREE_NODE. */ 450 /* Add copies originated from BB given by LOOP_TREE_NODE. */
420 static void 451 static void
578 609
579 /* Print hard reg set SET with TITLE to FILE. */ 610 /* Print hard reg set SET with TITLE to FILE. */
580 static void 611 static void
581 print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set) 612 print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
582 { 613 {
583 int i, start; 614 int i, start, end;
584 615
585 fputs (title, file); 616 fputs (title, file);
586 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++) 617 for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
587 { 618 {
588 if (TEST_HARD_REG_BIT (set, i)) 619 bool reg_included = TEST_HARD_REG_BIT (set, i);
620
621 if (reg_included)
589 { 622 {
590 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1)) 623 if (start == -1)
591 start = i; 624 start = i;
625 end = i;
592 } 626 }
593 if (start >= 0 627 if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
594 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
595 { 628 {
596 if (start == i - 1) 629 if (start == end)
597 fprintf (file, " %d", start); 630 fprintf (file, " %d", start);
598 else if (start == i - 2) 631 else if (start == end + 1)
599 fprintf (file, " %d %d", start, start + 1); 632 fprintf (file, " %d %d", start, end);
600 else 633 else
601 fprintf (file, " %d-%d", start, i - 1); 634 fprintf (file, " %d-%d", start, end);
602 start = -1; 635 start = -1;
603 } 636 }
604 } 637 }
605 putc ('\n', file); 638 putc ('\n', file);
606 } 639 }
631 ira_object_t obj = ALLOCNO_OBJECT (a, i); 664 ira_object_t obj = ALLOCNO_OBJECT (a, i);
632 ira_object_t conflict_obj; 665 ira_object_t conflict_obj;
633 ira_object_conflict_iterator oci; 666 ira_object_conflict_iterator oci;
634 667
635 if (OBJECT_CONFLICT_ARRAY (obj) == NULL) 668 if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
636 continue; 669 {
670 fprintf (file, "\n;; total conflict hard regs:\n");
671 fprintf (file, ";; conflict hard regs:\n\n");
672 continue;
673 }
674
637 if (n > 1) 675 if (n > 1)
638 fprintf (file, "\n;; subobject %d:", i); 676 fprintf (file, "\n;; subobject %d:", i);
639 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci) 677 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
640 { 678 {
641 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj); 679 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
653 fprintf (file, ",l%d", 691 fprintf (file, ",l%d",
654 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num); 692 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
655 putc (')', file); 693 putc (')', file);
656 } 694 }
657 } 695 }
658 COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); 696 conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
659 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); 697 & ~ira_no_alloc_regs
660 AND_HARD_REG_SET (conflicting_hard_regs, 698 & reg_class_contents[ALLOCNO_CLASS (a)]);
661 reg_class_contents[ALLOCNO_CLASS (a)]);
662 print_hard_reg_set (file, "\n;; total conflict hard regs:", 699 print_hard_reg_set (file, "\n;; total conflict hard regs:",
663 conflicting_hard_regs); 700 conflicting_hard_regs);
664 701
665 COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj)); 702 conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj)
666 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); 703 & ~ira_no_alloc_regs
667 AND_HARD_REG_SET (conflicting_hard_regs, 704 & reg_class_contents[ALLOCNO_CLASS (a)]);
668 reg_class_contents[ALLOCNO_CLASS (a)]);
669 print_hard_reg_set (file, ";; conflict hard regs:", 705 print_hard_reg_set (file, ";; conflict hard regs:",
670 conflicting_hard_regs); 706 conflicting_hard_regs);
671 putc ('\n', file); 707 putc ('\n', file);
672 } 708 }
673 709
681 ira_allocno_t a; 717 ira_allocno_t a;
682 ira_allocno_iterator ai; 718 ira_allocno_iterator ai;
683 719
684 FOR_EACH_ALLOCNO (a, ai) 720 FOR_EACH_ALLOCNO (a, ai)
685 print_allocno_conflicts (file, reg_p, a); 721 print_allocno_conflicts (file, reg_p, a);
722 putc ('\n', file);
686 } 723 }
687 724
688 /* Print information about allocno or only regno (if REG_P) conflicts 725 /* Print information about allocno or only regno (if REG_P) conflicts
689 to stderr. */ 726 to stderr. */
690 void 727 void
732 } 769 }
733 base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH); 770 base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
734 if (! targetm.class_likely_spilled_p (base)) 771 if (! targetm.class_likely_spilled_p (base))
735 CLEAR_HARD_REG_SET (temp_hard_reg_set); 772 CLEAR_HARD_REG_SET (temp_hard_reg_set);
736 else 773 else
737 { 774 temp_hard_reg_set = reg_class_contents[base] & ~ira_no_alloc_regs;
738 COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]);
739 AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
740 AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
741 }
742 FOR_EACH_ALLOCNO (a, ai) 775 FOR_EACH_ALLOCNO (a, ai)
743 { 776 {
744 int i, n = ALLOCNO_NUM_OBJECTS (a); 777 int i, n = ALLOCNO_NUM_OBJECTS (a);
745 778
746 for (i = 0; i < n; i++) 779 for (i = 0; i < n; i++)
747 { 780 {
748 ira_object_t obj = ALLOCNO_OBJECT (a, i); 781 ira_object_t obj = ALLOCNO_OBJECT (a, i);
749 machine_mode obj_mode = obj->allocno->mode;
750 rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)]; 782 rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
751 783
752 if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) 784 /* For debugging purposes don't put user defined variables in
753 /* For debugging purposes don't put user defined variables in 785 callee-clobbered registers. However, do allow parameters
754 callee-clobbered registers. However, do allow parameters 786 in callee-clobbered registers to improve debugging. This
755 in callee-clobbered registers to improve debugging. This 787 is a bit of a fragile hack. */
756 is a bit of a fragile hack. */ 788 if (optimize == 0
757 || (optimize == 0 789 && REG_USERVAR_P (allocno_reg)
758 && REG_USERVAR_P (allocno_reg) 790 && ! reg_is_parm_p (allocno_reg))
759 && ! reg_is_parm_p (allocno_reg)))
760 { 791 {
761 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), 792 HARD_REG_SET new_conflict_regs = crtl->abi->full_reg_clobbers ();
762 call_used_reg_set); 793 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
763 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), 794 OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
764 call_used_reg_set);
765 } 795 }
766 else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) 796
797 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
767 { 798 {
768 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), 799 HARD_REG_SET new_conflict_regs = ira_need_caller_save_regs (a);
769 no_caller_save_reg_set); 800 if (flag_caller_saves)
770 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), 801 new_conflict_regs &= (~savable_regs | temp_hard_reg_set);
771 temp_hard_reg_set); 802 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
772 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), 803 OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
773 no_caller_save_reg_set);
774 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
775 temp_hard_reg_set);
776 } 804 }
777 805
778 /* Now we deal with paradoxical subreg cases where certain registers 806 /* Now we deal with paradoxical subreg cases where certain registers
779 cannot be accessed in the widest mode. */ 807 cannot be accessed in the widest mode. */
780 machine_mode outer_mode = ALLOCNO_WMODE (a); 808 machine_mode outer_mode = ALLOCNO_WMODE (a);
797 SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), 825 SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
798 inner_regno); 826 inner_regno);
799 } 827 }
800 } 828 }
801 } 829 }
802
803 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
804 {
805 int regno;
806
807 /* Allocnos bigger than the saved part of call saved
808 regs must conflict with them. */
809 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
810 if (!TEST_HARD_REG_BIT (call_used_reg_set, regno)
811 && targetm.hard_regno_call_part_clobbered (regno,
812 obj_mode))
813 {
814 SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
815 SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
816 regno);
817 }
818 }
819 } 830 }
820 } 831 }
821 if (optimize && ira_conflicts_p 832 if (optimize && ira_conflicts_p
822 && internal_flag_ira_verbose > 2 && ira_dump_file != NULL) 833 && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
823 print_conflicts (ira_dump_file, false); 834 print_conflicts (ira_dump_file, false);