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