Mercurial > hg > CbC > CbC_gcc
comparison gcc/regrename.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 /* Register renaming for the GNU compiler. | 1 /* Register renaming for the GNU compiler. |
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, |
3 Free Software Foundation, Inc. | 3 2010 Free Software Foundation, Inc. |
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 | 7 GCC is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by | 8 under the terms of the GNU General Public License as published by |
507 add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x)); | 507 add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x)); |
508 for (chain = open_chains; chain; chain = chain->next_chain) | 508 for (chain = open_chains; chain; chain = chain->next_chain) |
509 add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x)); | 509 add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x)); |
510 } | 510 } |
511 | 511 |
512 /* Create a new chain for THIS_NREGS registers starting at THIS_REGNO, | |
513 and record its occurrence in *LOC, which is being written to in INSN. | |
514 This access requires a register of class CL. */ | |
515 | |
516 static void | |
517 create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc, | |
518 rtx insn, enum reg_class cl) | |
519 { | |
520 struct du_head *head = XOBNEW (&rename_obstack, struct du_head); | |
521 struct du_chain *this_du; | |
522 int nregs; | |
523 | |
524 head->next_chain = open_chains; | |
525 open_chains = head; | |
526 head->regno = this_regno; | |
527 head->nregs = this_nregs; | |
528 head->need_caller_save_reg = 0; | |
529 head->cannot_rename = 0; | |
530 head->terminated = 0; | |
531 | |
532 VEC_safe_push (du_head_p, heap, id_to_chain, head); | |
533 head->id = current_id++; | |
534 | |
535 bitmap_initialize (&head->conflicts, &bitmap_default_obstack); | |
536 bitmap_copy (&head->conflicts, &open_chains_set); | |
537 mark_conflict (open_chains, head->id); | |
538 | |
539 /* Since we're tracking this as a chain now, remove it from the | |
540 list of conflicting live hard registers and track it in | |
541 live_in_chains instead. */ | |
542 nregs = head->nregs; | |
543 while (nregs-- > 0) | |
544 { | |
545 SET_HARD_REG_BIT (live_in_chains, head->regno + nregs); | |
546 CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs); | |
547 } | |
548 | |
549 COPY_HARD_REG_SET (head->hard_conflicts, live_hard_regs); | |
550 bitmap_set_bit (&open_chains_set, head->id); | |
551 | |
552 open_chains = head; | |
553 | |
554 if (dump_file) | |
555 { | |
556 fprintf (dump_file, "Creating chain %s (%d)", | |
557 reg_names[head->regno], head->id); | |
558 if (insn != NULL_RTX) | |
559 fprintf (dump_file, " at insn %d", INSN_UID (insn)); | |
560 fprintf (dump_file, "\n"); | |
561 } | |
562 | |
563 if (insn == NULL_RTX) | |
564 { | |
565 head->first = head->last = NULL; | |
566 return; | |
567 } | |
568 | |
569 this_du = XOBNEW (&rename_obstack, struct du_chain); | |
570 head->first = head->last = this_du; | |
571 | |
572 this_du->next_use = 0; | |
573 this_du->loc = loc; | |
574 this_du->insn = insn; | |
575 this_du->cl = cl; | |
576 } | |
577 | |
512 static void | 578 static void |
513 scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, | 579 scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, |
514 enum op_type type) | 580 enum op_type type) |
515 { | 581 { |
516 struct du_head **p; | 582 struct du_head **p; |
520 unsigned this_nregs = hard_regno_nregs[this_regno][mode]; | 586 unsigned this_nregs = hard_regno_nregs[this_regno][mode]; |
521 | 587 |
522 if (action == mark_write) | 588 if (action == mark_write) |
523 { | 589 { |
524 if (type == OP_OUT) | 590 if (type == OP_OUT) |
525 { | 591 create_new_chain (this_regno, this_nregs, loc, insn, cl); |
526 struct du_head *head = XOBNEW (&rename_obstack, struct du_head); | |
527 struct du_chain *this_du = XOBNEW (&rename_obstack, struct du_chain); | |
528 int nregs; | |
529 | |
530 head->next_chain = open_chains; | |
531 open_chains = head; | |
532 head->first = head->last = this_du; | |
533 head->regno = this_regno; | |
534 head->nregs = this_nregs; | |
535 head->need_caller_save_reg = 0; | |
536 head->cannot_rename = 0; | |
537 head->terminated = 0; | |
538 | |
539 VEC_safe_push (du_head_p, heap, id_to_chain, head); | |
540 head->id = current_id++; | |
541 | |
542 bitmap_initialize (&head->conflicts, &bitmap_default_obstack); | |
543 bitmap_copy (&head->conflicts, &open_chains_set); | |
544 mark_conflict (open_chains, head->id); | |
545 | |
546 /* Since we're tracking this as a chain now, remove it from the | |
547 list of conflicting live hard registers and track it in | |
548 live_in_chains instead. */ | |
549 nregs = head->nregs; | |
550 while (nregs-- > 0) | |
551 { | |
552 SET_HARD_REG_BIT (live_in_chains, head->regno + nregs); | |
553 CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs); | |
554 } | |
555 | |
556 COPY_HARD_REG_SET (head->hard_conflicts, live_hard_regs); | |
557 bitmap_set_bit (&open_chains_set, head->id); | |
558 | |
559 open_chains = head; | |
560 | |
561 this_du->next_use = 0; | |
562 this_du->loc = loc; | |
563 this_du->insn = insn; | |
564 this_du->cl = cl; | |
565 | |
566 if (dump_file) | |
567 fprintf (dump_file, | |
568 "Creating chain %s (%d) at insn %d (%s)\n", | |
569 reg_names[head->regno], head->id, INSN_UID (insn), | |
570 scan_actions_name[(int) action]); | |
571 } | |
572 return; | 592 return; |
573 } | 593 } |
574 | 594 |
575 if ((type == OP_OUT) != (action == terminate_write || action == mark_access)) | 595 if ((type == OP_OUT) != (action == terminate_write || action == mark_access)) |
576 return; | 596 return; |
634 this_du = XOBNEW (&rename_obstack, struct du_chain); | 654 this_du = XOBNEW (&rename_obstack, struct du_chain); |
635 this_du->next_use = 0; | 655 this_du->next_use = 0; |
636 this_du->loc = loc; | 656 this_du->loc = loc; |
637 this_du->insn = insn; | 657 this_du->insn = insn; |
638 this_du->cl = cl; | 658 this_du->cl = cl; |
639 head->last->next_use = this_du; | 659 if (head->first == NULL) |
660 head->first = this_du; | |
661 else | |
662 head->last->next_use = this_du; | |
640 head->last = this_du; | 663 head->last = this_du; |
641 | 664 |
642 } | 665 } |
643 /* Avoid adding the same location in a DEBUG_INSN multiple times, | 666 /* Avoid adding the same location in a DEBUG_INSN multiple times, |
644 which could happen with non-exact overlap. */ | 667 which could happen with non-exact overlap. */ |
887 (GET_CODE (PATTERN (insn)) == COND_EXEC | 910 (GET_CODE (PATTERN (insn)) == COND_EXEC |
888 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT); | 911 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT); |
889 return; | 912 return; |
890 | 913 |
891 case STRICT_LOW_PART: | 914 case STRICT_LOW_PART: |
892 scan_rtx (insn, &XEXP (x, 0), cl, action, OP_INOUT); | 915 scan_rtx (insn, &XEXP (x, 0), cl, action, |
916 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT); | |
893 return; | 917 return; |
894 | 918 |
895 case ZERO_EXTRACT: | 919 case ZERO_EXTRACT: |
896 case SIGN_EXTRACT: | 920 case SIGN_EXTRACT: |
897 scan_rtx (insn, &XEXP (x, 0), cl, action, | 921 scan_rtx (insn, &XEXP (x, 0), cl, action, |
898 type == OP_IN ? OP_IN : OP_INOUT); | 922 (type == OP_IN ? OP_IN : |
923 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT)); | |
899 scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN); | 924 scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN); |
900 scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN); | 925 scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN); |
901 return; | 926 return; |
902 | 927 |
903 case POST_INC: | 928 case POST_INC: |
1112 when the first SET makes a register live. */ | 1137 when the first SET makes a register live. */ |
1113 | 1138 |
1114 predicated = GET_CODE (PATTERN (insn)) == COND_EXEC; | 1139 predicated = GET_CODE (PATTERN (insn)) == COND_EXEC; |
1115 for (i = 0; i < n_ops; ++i) | 1140 for (i = 0; i < n_ops; ++i) |
1116 { | 1141 { |
1142 rtx op = recog_data.operand[i]; | |
1117 int matches = recog_op_alt[i][alt].matches; | 1143 int matches = recog_op_alt[i][alt].matches; |
1118 if (matches >= 0) | 1144 if (matches >= 0) |
1119 recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl; | 1145 recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl; |
1120 if (matches >= 0 || recog_op_alt[i][alt].matched >= 0 | 1146 if (matches >= 0 || recog_op_alt[i][alt].matched >= 0 |
1121 || (predicated && recog_data.operand_type[i] == OP_OUT | 1147 || (predicated && recog_data.operand_type[i] == OP_OUT)) |
1122 && verify_reg_tracked (recog_data.operand[i]))) | |
1123 { | 1148 { |
1124 rtx op = recog_data.operand[i]; | |
1125 recog_data.operand_type[i] = OP_INOUT; | 1149 recog_data.operand_type[i] = OP_INOUT; |
1126 /* A special case to deal with instruction patterns that | 1150 /* A special case to deal with instruction patterns that |
1127 have matching operands with different modes. If we're | 1151 have matching operands with different modes. If we're |
1128 not already tracking such a reg, we won't start here, | 1152 not already tracking such a reg, we won't start here, |
1129 and we must instead make sure to make the operand visible | 1153 and we must instead make sure to make the operand visible |
1134 && !verify_reg_in_set (op, &live_in_chains)) | 1158 && !verify_reg_in_set (op, &live_in_chains)) |
1135 { | 1159 { |
1136 untracked_operands |= 1 << i; | 1160 untracked_operands |= 1 << i; |
1137 untracked_operands |= 1 << matches; | 1161 untracked_operands |= 1 << matches; |
1138 } | 1162 } |
1163 } | |
1164 /* If there's an in-out operand with a register that is not | |
1165 being tracked at all yet, open a chain. */ | |
1166 if (recog_data.operand_type[i] == OP_INOUT | |
1167 && !(untracked_operands & (1 << i)) | |
1168 && REG_P (op) | |
1169 && !verify_reg_tracked (op)) | |
1170 { | |
1171 enum machine_mode mode = GET_MODE (op); | |
1172 unsigned this_regno = REGNO (op); | |
1173 unsigned this_nregs = hard_regno_nregs[this_regno][mode]; | |
1174 create_new_chain (this_regno, this_nregs, NULL, NULL_RTX, | |
1175 NO_REGS); | |
1139 } | 1176 } |
1140 } | 1177 } |
1141 | 1178 |
1142 if (fail_current_block) | 1179 if (fail_current_block) |
1143 break; | 1180 break; |