comparison gcc/ira-conflicts.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* IRA conflict builder. 1 /* IRA conflict builder.
2 Copyright (C) 2006, 2007, 2008, 2009 2 Copyright (C) 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>. 4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
300 return -1; 300 return -1;
301 } 301 }
302 return dup; 302 return dup;
303 } 303 }
304 304
305 /* Return the operand which should be, in any case, the same as
306 operand with number OP_NUM. If USE_COMMUT_OP_P is TRUE, the
307 function makes temporarily commutative operand exchange before
308 this. */
309 static rtx
310 get_dup (int op_num, bool use_commut_op_p)
311 {
312 int n = get_dup_num (op_num, use_commut_op_p);
313
314 if (n < 0)
315 return NULL_RTX;
316 else
317 return recog_data.operand[n];
318 }
319
320 /* Check that X is REG or SUBREG of REG. */ 305 /* Check that X is REG or SUBREG of REG. */
321 #define REG_SUBREG_P(x) \ 306 #define REG_SUBREG_P(x) \
322 (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x)))) 307 (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
323 308
324 /* Return X if X is a REG, otherwise it should be SUBREG of REG and 309 /* Return X if X is a REG, otherwise it should be SUBREG of REG and
430 break; 415 break;
431 } 416 }
432 return true; 417 return true;
433 } 418 }
434 419
435 /* Process all of the output registers of the current insn and 420 /* Process all of the output registers of the current insn which are
436 the input register REG (its operand number OP_NUM) which dies in the 421 not bound (BOUND_P) and the input register REG (its operand number
437 insn as if there were a move insn between them with frequency 422 OP_NUM) which dies in the insn as if there were a move insn between
438 FREQ. */ 423 them with frequency FREQ. */
439 static void 424 static void
440 process_reg_shuffles (rtx reg, int op_num, int freq) 425 process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
441 { 426 {
442 int i; 427 int i;
443 rtx another_reg; 428 rtx another_reg;
444 429
445 gcc_assert (REG_SUBREG_P (reg)); 430 gcc_assert (REG_SUBREG_P (reg));
446 for (i = 0; i < recog_data.n_operands; i++) 431 for (i = 0; i < recog_data.n_operands; i++)
447 { 432 {
448 another_reg = recog_data.operand[i]; 433 another_reg = recog_data.operand[i];
449 434
450 if (!REG_SUBREG_P (another_reg) || op_num == i 435 if (!REG_SUBREG_P (another_reg) || op_num == i
451 || recog_data.operand_type[i] != OP_OUT) 436 || recog_data.operand_type[i] != OP_OUT
437 || bound_p[i])
452 continue; 438 continue;
453 439
454 process_regs_for_copy (reg, another_reg, false, NULL_RTX, freq); 440 process_regs_for_copy (reg, another_reg, false, NULL_RTX, freq);
455 } 441 }
456 } 442 }
461 static void 447 static void
462 add_insn_allocno_copies (rtx insn) 448 add_insn_allocno_copies (rtx insn)
463 { 449 {
464 rtx set, operand, dup; 450 rtx set, operand, dup;
465 const char *str; 451 const char *str;
466 bool commut_p, bound_p; 452 bool commut_p, bound_p[MAX_RECOG_OPERANDS];
467 int i, j, freq; 453 int i, j, n, freq;
468 454
469 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); 455 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
470 if (freq == 0) 456 if (freq == 0)
471 freq = 1; 457 freq = 1;
472 if ((set = single_set (insn)) != NULL_RTX 458 if ((set = single_set (insn)) != NULL_RTX
473 && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set)) 459 && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
474 && ! side_effects_p (set) 460 && ! side_effects_p (set)
475 && find_reg_note (insn, REG_DEAD, 461 && find_reg_note (insn, REG_DEAD,
476 REG_P (SET_SRC (set)) 462 REG_P (SET_SRC (set))
477 ? SET_SRC (set) 463 ? SET_SRC (set)
478 : SUBREG_REG (SET_SRC (set))) != NULL_RTX) 464 : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
479 process_regs_for_copy (SET_DEST (set), SET_SRC (set), false, insn, freq); 465 {
480 else 466 process_regs_for_copy (SET_DEST (set), SET_SRC (set), false, insn, freq);
481 { 467 return;
482 extract_insn (insn); 468 }
483 for (i = 0; i < recog_data.n_operands; i++) 469 /* Fast check of possibility of constraint or shuffle copies. If
484 { 470 there are no dead registers, there will be no such copies. */
485 operand = recog_data.operand[i]; 471 if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
486 if (REG_SUBREG_P (operand) 472 return;
487 && find_reg_note (insn, REG_DEAD, 473 extract_insn (insn);
488 REG_P (operand) 474 for (i = 0; i < recog_data.n_operands; i++)
489 ? operand : SUBREG_REG (operand)) != NULL_RTX) 475 bound_p[i] = false;
490 { 476 for (i = 0; i < recog_data.n_operands; i++)
491 str = recog_data.constraints[i]; 477 {
492 while (*str == ' ' || *str == '\t') 478 operand = recog_data.operand[i];
493 str++; 479 if (! REG_SUBREG_P (operand))
494 bound_p = false; 480 continue;
495 for (j = 0, commut_p = false; j < 2; j++, commut_p = true) 481 str = recog_data.constraints[i];
496 if ((dup = get_dup (i, commut_p)) != NULL_RTX 482 while (*str == ' ' || *str == '\t')
497 && REG_SUBREG_P (dup) 483 str++;
498 && process_regs_for_copy (operand, dup, true, 484 for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
499 NULL_RTX, freq)) 485 if ((n = get_dup_num (i, commut_p)) >= 0)
500 bound_p = true; 486 {
501 if (bound_p) 487 bound_p[n] = true;
502 continue; 488 dup = recog_data.operand[n];
503 /* If an operand dies, prefer its hard register for the 489 if (REG_SUBREG_P (dup)
504 output operands by decreasing the hard register cost 490 && find_reg_note (insn, REG_DEAD,
505 or creating the corresponding allocno copies. The 491 REG_P (operand)
506 cost will not correspond to a real move insn cost, so 492 ? operand
507 make the frequency smaller. */ 493 : SUBREG_REG (operand)) != NULL_RTX)
508 process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8); 494 process_regs_for_copy (operand, dup, true, NULL_RTX, freq);
509 } 495 }
510 } 496 }
497 for (i = 0; i < recog_data.n_operands; i++)
498 {
499 operand = recog_data.operand[i];
500 if (REG_SUBREG_P (operand)
501 && find_reg_note (insn, REG_DEAD,
502 REG_P (operand)
503 ? operand : SUBREG_REG (operand)) != NULL_RTX)
504 /* If an operand dies, prefer its hard register for the output
505 operands by decreasing the hard register cost or creating
506 the corresponding allocno copies. The cost will not
507 correspond to a real move insn cost, so make the frequency
508 smaller. */
509 process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
511 } 510 }
512 } 511 }
513 512
514 /* Add copies originated from BB given by LOOP_TREE_NODE. */ 513 /* Add copies originated from BB given by LOOP_TREE_NODE. */
515 static void 514 static void
683 } 682 }
684 } 683 }
685 putc ('\n', file); 684 putc ('\n', file);
686 } 685 }
687 686
687 static void
688 print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
689 {
690 HARD_REG_SET conflicting_hard_regs;
691 ira_allocno_t conflict_a;
692 ira_allocno_conflict_iterator aci;
693 basic_block bb;
694
695 if (reg_p)
696 fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
697 else
698 {
699 fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
700 if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
701 fprintf (file, "b%d", bb->index);
702 else
703 fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
704 putc (')', file);
705 }
706 fputs (" conflicts:", file);
707 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
708 FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
709 {
710 if (reg_p)
711 fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
712 else
713 {
714 fprintf (file, " a%d(r%d,", ALLOCNO_NUM (conflict_a),
715 ALLOCNO_REGNO (conflict_a));
716 if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
717 fprintf (file, "b%d)", bb->index);
718 else
719 fprintf (file, "l%d)",
720 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
721 }
722 }
723 COPY_HARD_REG_SET (conflicting_hard_regs,
724 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
725 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
726 AND_HARD_REG_SET (conflicting_hard_regs,
727 reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
728 print_hard_reg_set (file, "\n;; total conflict hard regs:",
729 conflicting_hard_regs);
730 COPY_HARD_REG_SET (conflicting_hard_regs,
731 ALLOCNO_CONFLICT_HARD_REGS (a));
732 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
733 AND_HARD_REG_SET (conflicting_hard_regs,
734 reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
735 print_hard_reg_set (file, ";; conflict hard regs:",
736 conflicting_hard_regs);
737 putc ('\n', file);
738 }
739
688 /* Print information about allocno or only regno (if REG_P) conflicts 740 /* Print information about allocno or only regno (if REG_P) conflicts
689 to FILE. */ 741 to FILE. */
690 static void 742 static void
691 print_conflicts (FILE *file, bool reg_p) 743 print_conflicts (FILE *file, bool reg_p)
692 { 744 {
693 ira_allocno_t a; 745 ira_allocno_t a;
694 ira_allocno_iterator ai; 746 ira_allocno_iterator ai;
695 HARD_REG_SET conflicting_hard_regs;
696 747
697 FOR_EACH_ALLOCNO (a, ai) 748 FOR_EACH_ALLOCNO (a, ai)
698 { 749 print_allocno_conflicts (file, reg_p, a);
699 ira_allocno_t conflict_a;
700 ira_allocno_conflict_iterator aci;
701 basic_block bb;
702
703 if (reg_p)
704 fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
705 else
706 {
707 fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
708 if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
709 fprintf (file, "b%d", bb->index);
710 else
711 fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
712 putc (')', file);
713 }
714 fputs (" conflicts:", file);
715 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
716 FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
717 {
718 if (reg_p)
719 fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
720 else
721 {
722 fprintf (file, " a%d(r%d,", ALLOCNO_NUM (conflict_a),
723 ALLOCNO_REGNO (conflict_a));
724 if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
725 fprintf (file, "b%d)", bb->index);
726 else
727 fprintf (file, "l%d)",
728 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
729 }
730 }
731 COPY_HARD_REG_SET (conflicting_hard_regs,
732 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
733 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
734 AND_HARD_REG_SET (conflicting_hard_regs,
735 reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
736 print_hard_reg_set (file, "\n;; total conflict hard regs:",
737 conflicting_hard_regs);
738 COPY_HARD_REG_SET (conflicting_hard_regs,
739 ALLOCNO_CONFLICT_HARD_REGS (a));
740 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
741 AND_HARD_REG_SET (conflicting_hard_regs,
742 reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
743 print_hard_reg_set (file, ";; conflict hard regs:",
744 conflicting_hard_regs);
745 }
746 putc ('\n', file);
747 } 750 }
748 751
749 /* Print information about allocno or only regno (if REG_P) conflicts 752 /* Print information about allocno or only regno (if REG_P) conflicts
750 to stderr. */ 753 to stderr. */
751 void 754 void