Mercurial > hg > CbC > CbC_gcc
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); |