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;