Mercurial > hg > CbC > CbC_gcc
annotate gcc/ira-lives.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* IRA processing allocno lives to build allocno live ranges. |
111 | 2 Copyright (C) 2006-2017 Free Software Foundation, Inc. |
0 | 3 Contributed by Vladimir Makarov <vmakarov@redhat.com>. |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
111 | 24 #include "backend.h" |
0 | 25 #include "target.h" |
111 | 26 #include "rtl.h" |
27 #include "predict.h" | |
28 #include "df.h" | |
29 #include "memmodel.h" | |
30 #include "tm_p.h" | |
0 | 31 #include "insn-config.h" |
111 | 32 #include "regs.h" |
33 #include "ira.h" | |
34 #include "ira-int.h" | |
0 | 35 #include "sparseset.h" |
36 | |
37 /* The code in this file is similar to one in global but the code | |
38 works on the allocno basis and creates live ranges instead of | |
39 pseudo-register conflicts. */ | |
40 | |
41 /* Program points are enumerated by numbers from range | |
42 0..IRA_MAX_POINT-1. There are approximately two times more program | |
43 points than insns. Program points are places in the program where | |
44 liveness info can be changed. In most general case (there are more | |
45 complicated cases too) some program points correspond to places | |
46 where input operand dies and other ones correspond to places where | |
47 output operands are born. */ | |
48 int ira_max_point; | |
49 | |
50 /* Arrays of size IRA_MAX_POINT mapping a program point to the allocno | |
51 live ranges with given start/finish point. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
52 live_range_t *ira_start_point_ranges, *ira_finish_point_ranges; |
0 | 53 |
54 /* Number of the current program point. */ | |
55 static int curr_point; | |
56 | |
57 /* Point where register pressure excess started or -1 if there is no | |
58 register pressure excess. Excess pressure for a register class at | |
59 some point means that there are more allocnos of given register | |
60 class living at the point than number of hard-registers of the | |
111 | 61 class available for the allocation. It is defined only for |
62 pressure classes. */ | |
0 | 63 static int high_pressure_start_point[N_REG_CLASSES]; |
64 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
65 /* Objects live at current point in the scan. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
66 static sparseset objects_live; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
67 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
68 /* A temporary bitmap used in functions that wish to avoid visiting an allocno |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
69 multiple times. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
70 static sparseset allocnos_processed; |
0 | 71 |
72 /* Set of hard regs (except eliminable ones) currently live. */ | |
73 static HARD_REG_SET hard_regs_live; | |
74 | |
75 /* The loop tree node corresponding to the current basic block. */ | |
76 static ira_loop_tree_node_t curr_bb_node; | |
77 | |
78 /* The number of the last processed call. */ | |
79 static int last_call_num; | |
80 /* The number of last call at which given allocno was saved. */ | |
81 static int *allocno_saved_at_call; | |
82 | |
111 | 83 /* The value of get_preferred_alternatives for the current instruction, |
84 supplemental to recog_data. */ | |
85 static alternative_mask preferred_alternatives; | |
86 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
87 /* Record the birth of hard register REGNO, updating hard_regs_live and |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
88 hard reg conflict information for living allocnos. */ |
0 | 89 static void |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
90 make_hard_regno_born (int regno) |
0 | 91 { |
92 unsigned int i; | |
93 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
94 SET_HARD_REG_BIT (hard_regs_live, regno); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
95 EXECUTE_IF_SET_IN_SPARSESET (objects_live, i) |
0 | 96 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
97 ira_object_t obj = ira_object_id_map[i]; |
111 | 98 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
99 SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
100 SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno); |
0 | 101 } |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
102 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
103 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
104 /* Process the death of hard register REGNO. This updates |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
105 hard_regs_live. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
106 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
107 make_hard_regno_dead (int regno) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
108 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
109 CLEAR_HARD_REG_BIT (hard_regs_live, regno); |
0 | 110 } |
111 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
112 /* Record the birth of object OBJ. Set a bit for it in objects_live, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
113 start a new live range for it if necessary and update hard register |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
114 conflicts. */ |
0 | 115 static void |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
116 make_object_born (ira_object_t obj) |
0 | 117 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
118 live_range_t lr = OBJECT_LIVE_RANGES (obj); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
119 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
120 sparseset_set_bit (objects_live, OBJECT_CONFLICT_ID (obj)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
121 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
122 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
123 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
124 if (lr == NULL |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
125 || (lr->finish != curr_point && lr->finish + 1 != curr_point)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
126 ira_add_live_range_to_object (obj, curr_point, -1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
127 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
128 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
129 /* Update ALLOCNO_EXCESS_PRESSURE_POINTS_NUM for the allocno |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
130 associated with object OBJ. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
131 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
132 update_allocno_pressure_excess_length (ira_object_t obj) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
133 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
134 ira_allocno_t a = OBJECT_ALLOCNO (obj); |
0 | 135 int start, i; |
111 | 136 enum reg_class aclass, pclass, cl; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
137 live_range_t p; |
0 | 138 |
111 | 139 aclass = ALLOCNO_CLASS (a); |
140 pclass = ira_pressure_class_translate[aclass]; | |
0 | 141 for (i = 0; |
111 | 142 (cl = ira_reg_class_super_classes[pclass][i]) != LIM_REG_CLASSES; |
0 | 143 i++) |
144 { | |
111 | 145 if (! ira_reg_pressure_class_p[cl]) |
146 continue; | |
0 | 147 if (high_pressure_start_point[cl] < 0) |
148 continue; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
149 p = OBJECT_LIVE_RANGES (obj); |
0 | 150 ira_assert (p != NULL); |
151 start = (high_pressure_start_point[cl] > p->start | |
152 ? high_pressure_start_point[cl] : p->start); | |
153 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) += curr_point - start + 1; | |
154 } | |
155 } | |
156 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
157 /* Process the death of object OBJ, which is associated with allocno |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
158 A. This finishes the current live range for it. */ |
0 | 159 static void |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
160 make_object_dead (ira_object_t obj) |
0 | 161 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
162 live_range_t lr; |
0 | 163 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
164 sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (obj)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
165 lr = OBJECT_LIVE_RANGES (obj); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
166 ira_assert (lr != NULL); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
167 lr->finish = curr_point; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
168 update_allocno_pressure_excess_length (obj); |
0 | 169 } |
170 | |
111 | 171 /* The current register pressures for each pressure class for the current |
0 | 172 basic block. */ |
173 static int curr_reg_pressure[N_REG_CLASSES]; | |
174 | |
111 | 175 /* Record that register pressure for PCLASS increased by N registers. |
176 Update the current register pressure, maximal register pressure for | |
177 the current BB and the start point of the register pressure | |
178 excess. */ | |
0 | 179 static void |
111 | 180 inc_register_pressure (enum reg_class pclass, int n) |
0 | 181 { |
182 int i; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
183 enum reg_class cl; |
0 | 184 |
185 for (i = 0; | |
111 | 186 (cl = ira_reg_class_super_classes[pclass][i]) != LIM_REG_CLASSES; |
0 | 187 i++) |
188 { | |
111 | 189 if (! ira_reg_pressure_class_p[cl]) |
190 continue; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
191 curr_reg_pressure[cl] += n; |
0 | 192 if (high_pressure_start_point[cl] < 0 |
111 | 193 && (curr_reg_pressure[cl] > ira_class_hard_regs_num[cl])) |
0 | 194 high_pressure_start_point[cl] = curr_point; |
195 if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl]) | |
196 curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl]; | |
197 } | |
198 } | |
199 | |
111 | 200 /* Record that register pressure for PCLASS has decreased by NREGS |
201 registers; update current register pressure, start point of the | |
202 register pressure excess, and register pressure excess length for | |
203 living allocnos. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
204 |
0 | 205 static void |
111 | 206 dec_register_pressure (enum reg_class pclass, int nregs) |
0 | 207 { |
208 int i; | |
209 unsigned int j; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
210 enum reg_class cl; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
211 bool set_p = false; |
0 | 212 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
213 for (i = 0; |
111 | 214 (cl = ira_reg_class_super_classes[pclass][i]) != LIM_REG_CLASSES; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
215 i++) |
0 | 216 { |
111 | 217 if (! ira_reg_pressure_class_p[cl]) |
218 continue; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
219 curr_reg_pressure[cl] -= nregs; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
220 ira_assert (curr_reg_pressure[cl] >= 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
221 if (high_pressure_start_point[cl] >= 0 |
111 | 222 && curr_reg_pressure[cl] <= ira_class_hard_regs_num[cl]) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
223 set_p = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
224 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
225 if (set_p) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
226 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
227 EXECUTE_IF_SET_IN_SPARSESET (objects_live, j) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
228 update_allocno_pressure_excess_length (ira_object_id_map[j]); |
0 | 229 for (i = 0; |
111 | 230 (cl = ira_reg_class_super_classes[pclass][i]) != LIM_REG_CLASSES; |
0 | 231 i++) |
111 | 232 { |
233 if (! ira_reg_pressure_class_p[cl]) | |
234 continue; | |
235 if (high_pressure_start_point[cl] >= 0 | |
236 && curr_reg_pressure[cl] <= ira_class_hard_regs_num[cl]) | |
237 high_pressure_start_point[cl] = -1; | |
238 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
239 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
240 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
241 |
111 | 242 /* Determine from the objects_live bitmap whether REGNO is currently live, |
243 and occupies only one object. Return false if we have no information. */ | |
244 static bool | |
245 pseudo_regno_single_word_and_live_p (int regno) | |
246 { | |
247 ira_allocno_t a = ira_curr_regno_allocno_map[regno]; | |
248 ira_object_t obj; | |
249 | |
250 if (a == NULL) | |
251 return false; | |
252 if (ALLOCNO_NUM_OBJECTS (a) > 1) | |
253 return false; | |
254 | |
255 obj = ALLOCNO_OBJECT (a, 0); | |
256 | |
257 return sparseset_bit_p (objects_live, OBJECT_CONFLICT_ID (obj)); | |
258 } | |
259 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
260 /* Mark the pseudo register REGNO as live. Update all information about |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
261 live ranges and register pressure. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
262 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
263 mark_pseudo_regno_live (int regno) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
264 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
265 ira_allocno_t a = ira_curr_regno_allocno_map[regno]; |
111 | 266 enum reg_class pclass; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
267 int i, n, nregs; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
268 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
269 if (a == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
270 return; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
271 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
272 /* Invalidate because it is referenced. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
273 allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
274 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
275 n = ALLOCNO_NUM_OBJECTS (a); |
111 | 276 pclass = ira_pressure_class_translate[ALLOCNO_CLASS (a)]; |
277 nregs = ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
278 if (n > 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
279 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
280 /* We track every subobject separately. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
281 gcc_assert (nregs == n); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
282 nregs = 1; |
0 | 283 } |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
284 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
285 for (i = 0; i < n; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
286 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
287 ira_object_t obj = ALLOCNO_OBJECT (a, i); |
111 | 288 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
289 if (sparseset_bit_p (objects_live, OBJECT_CONFLICT_ID (obj))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
290 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
291 |
111 | 292 inc_register_pressure (pclass, nregs); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
293 make_object_born (obj); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
294 } |
0 | 295 } |
296 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
297 /* Like mark_pseudo_regno_live, but try to only mark one subword of |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
298 the pseudo as live. SUBWORD indicates which; a value of 0 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
299 indicates the low part. */ |
0 | 300 static void |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
301 mark_pseudo_regno_subword_live (int regno, int subword) |
0 | 302 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
303 ira_allocno_t a = ira_curr_regno_allocno_map[regno]; |
111 | 304 int n; |
305 enum reg_class pclass; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
306 ira_object_t obj; |
0 | 307 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
308 if (a == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
309 return; |
0 | 310 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
311 /* Invalidate because it is referenced. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
312 allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
313 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
314 n = ALLOCNO_NUM_OBJECTS (a); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
315 if (n == 1) |
0 | 316 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
317 mark_pseudo_regno_live (regno); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
318 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
319 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
320 |
111 | 321 pclass = ira_pressure_class_translate[ALLOCNO_CLASS (a)]; |
322 gcc_assert | |
323 (n == ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
324 obj = ALLOCNO_OBJECT (a, subword); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
325 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
326 if (sparseset_bit_p (objects_live, OBJECT_CONFLICT_ID (obj))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
327 return; |
0 | 328 |
111 | 329 inc_register_pressure (pclass, 1); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
330 make_object_born (obj); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
331 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
332 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
333 /* Mark the register REG as live. Store a 1 in hard_regs_live for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
334 this register, record how many consecutive hardware registers it |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
335 actually needs. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
336 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
337 mark_hard_reg_live (rtx reg) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
338 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
339 int regno = REGNO (reg); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
340 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
341 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) |
0 | 342 { |
111 | 343 int last = END_REGNO (reg); |
344 enum reg_class aclass, pclass; | |
0 | 345 |
346 while (regno < last) | |
347 { | |
348 if (! TEST_HARD_REG_BIT (hard_regs_live, regno) | |
349 && ! TEST_HARD_REG_BIT (eliminable_regset, regno)) | |
350 { | |
111 | 351 aclass = ira_hard_regno_allocno_class[regno]; |
352 pclass = ira_pressure_class_translate[aclass]; | |
353 inc_register_pressure (pclass, 1); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
354 make_hard_regno_born (regno); |
0 | 355 } |
356 regno++; | |
357 } | |
358 } | |
359 } | |
360 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
361 /* Mark a pseudo, or one of its subwords, as live. REGNO is the pseudo's |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
362 register number; ORIG_REG is the access in the insn, which may be a |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
363 subreg. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
364 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
365 mark_pseudo_reg_live (rtx orig_reg, unsigned regno) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
366 { |
111 | 367 if (read_modify_subreg_p (orig_reg)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
368 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
369 mark_pseudo_regno_subword_live (regno, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
370 subreg_lowpart_p (orig_reg) ? 0 : 1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
371 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
372 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
373 mark_pseudo_regno_live (regno); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
374 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
375 |
0 | 376 /* Mark the register referenced by use or def REF as live. */ |
377 static void | |
378 mark_ref_live (df_ref ref) | |
379 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
380 rtx reg = DF_REF_REG (ref); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
381 rtx orig_reg = reg; |
0 | 382 |
383 if (GET_CODE (reg) == SUBREG) | |
384 reg = SUBREG_REG (reg); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
385 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
386 if (REGNO (reg) >= FIRST_PSEUDO_REGISTER) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
387 mark_pseudo_reg_live (orig_reg, REGNO (reg)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
388 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
389 mark_hard_reg_live (reg); |
0 | 390 } |
391 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
392 /* Mark the pseudo register REGNO as dead. Update all information about |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
393 live ranges and register pressure. */ |
0 | 394 static void |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
395 mark_pseudo_regno_dead (int regno) |
0 | 396 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
397 ira_allocno_t a = ira_curr_regno_allocno_map[regno]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
398 int n, i, nregs; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
399 enum reg_class cl; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
400 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
401 if (a == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
402 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
403 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
404 /* Invalidate because it is referenced. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
405 allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; |
0 | 406 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
407 n = ALLOCNO_NUM_OBJECTS (a); |
111 | 408 cl = ira_pressure_class_translate[ALLOCNO_CLASS (a)]; |
409 nregs = ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
410 if (n > 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
411 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
412 /* We track every subobject separately. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
413 gcc_assert (nregs == n); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
414 nregs = 1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
415 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
416 for (i = 0; i < n; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
417 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
418 ira_object_t obj = ALLOCNO_OBJECT (a, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
419 if (!sparseset_bit_p (objects_live, OBJECT_CONFLICT_ID (obj))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
420 continue; |
0 | 421 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
422 dec_register_pressure (cl, nregs); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
423 make_object_dead (obj); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
424 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
425 } |
0 | 426 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
427 /* Like mark_pseudo_regno_dead, but called when we know that only part of the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
428 register dies. SUBWORD indicates which; a value of 0 indicates the low part. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
429 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
430 mark_pseudo_regno_subword_dead (int regno, int subword) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
431 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
432 ira_allocno_t a = ira_curr_regno_allocno_map[regno]; |
111 | 433 int n; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
434 enum reg_class cl; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
435 ira_object_t obj; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
436 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
437 if (a == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
438 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
439 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
440 /* Invalidate because it is referenced. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
441 allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
442 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
443 n = ALLOCNO_NUM_OBJECTS (a); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
444 if (n == 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
445 /* The allocno as a whole doesn't die in this case. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
446 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
447 |
111 | 448 cl = ira_pressure_class_translate[ALLOCNO_CLASS (a)]; |
449 gcc_assert | |
450 (n == ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
451 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
452 obj = ALLOCNO_OBJECT (a, subword); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
453 if (!sparseset_bit_p (objects_live, OBJECT_CONFLICT_ID (obj))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
454 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
455 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
456 dec_register_pressure (cl, 1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
457 make_object_dead (obj); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
458 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
459 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
460 /* Mark the hard register REG as dead. Store a 0 in hard_regs_live for the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
461 register. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
462 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
463 mark_hard_reg_dead (rtx reg) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
464 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
465 int regno = REGNO (reg); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
466 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
467 if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) |
0 | 468 { |
111 | 469 int last = END_REGNO (reg); |
470 enum reg_class aclass, pclass; | |
0 | 471 |
472 while (regno < last) | |
473 { | |
474 if (TEST_HARD_REG_BIT (hard_regs_live, regno)) | |
475 { | |
111 | 476 aclass = ira_hard_regno_allocno_class[regno]; |
477 pclass = ira_pressure_class_translate[aclass]; | |
478 dec_register_pressure (pclass, 1); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
479 make_hard_regno_dead (regno); |
0 | 480 } |
481 regno++; | |
482 } | |
483 } | |
484 } | |
485 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
486 /* Mark a pseudo, or one of its subwords, as dead. REGNO is the pseudo's |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
487 register number; ORIG_REG is the access in the insn, which may be a |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
488 subreg. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
489 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
490 mark_pseudo_reg_dead (rtx orig_reg, unsigned regno) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
491 { |
111 | 492 if (read_modify_subreg_p (orig_reg)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
493 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
494 mark_pseudo_regno_subword_dead (regno, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
495 subreg_lowpart_p (orig_reg) ? 0 : 1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
496 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
497 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
498 mark_pseudo_regno_dead (regno); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
499 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
500 |
0 | 501 /* Mark the register referenced by definition DEF as dead, if the |
502 definition is a total one. */ | |
503 static void | |
504 mark_ref_dead (df_ref def) | |
505 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
506 rtx reg = DF_REF_REG (def); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
507 rtx orig_reg = reg; |
0 | 508 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
509 if (DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)) |
0 | 510 return; |
511 | |
512 if (GET_CODE (reg) == SUBREG) | |
513 reg = SUBREG_REG (reg); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
514 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
515 if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
516 && (GET_CODE (orig_reg) != SUBREG |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
517 || REGNO (reg) < FIRST_PSEUDO_REGISTER |
111 | 518 || !read_modify_subreg_p (orig_reg))) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
519 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
520 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
521 if (REGNO (reg) >= FIRST_PSEUDO_REGISTER) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
522 mark_pseudo_reg_dead (orig_reg, REGNO (reg)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
523 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
524 mark_hard_reg_dead (reg); |
0 | 525 } |
526 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
527 /* If REG is a pseudo or a subreg of it, and the class of its allocno |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
528 intersects CL, make a conflict with pseudo DREG. ORIG_DREG is the |
111 | 529 rtx actually accessed, it may be identical to DREG or a subreg of it. |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
530 Advance the current program point before making the conflict if |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
531 ADVANCE_P. Return TRUE if we will need to advance the current |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
532 program point. */ |
0 | 533 static bool |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
534 make_pseudo_conflict (rtx reg, enum reg_class cl, rtx dreg, rtx orig_dreg, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
535 bool advance_p) |
0 | 536 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
537 rtx orig_reg = reg; |
0 | 538 ira_allocno_t a; |
539 | |
540 if (GET_CODE (reg) == SUBREG) | |
541 reg = SUBREG_REG (reg); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
542 |
0 | 543 if (! REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER) |
544 return advance_p; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
545 |
0 | 546 a = ira_curr_regno_allocno_map[REGNO (reg)]; |
111 | 547 if (! reg_classes_intersect_p (cl, ALLOCNO_CLASS (a))) |
0 | 548 return advance_p; |
549 | |
550 if (advance_p) | |
551 curr_point++; | |
552 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
553 mark_pseudo_reg_live (orig_reg, REGNO (reg)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
554 mark_pseudo_reg_live (orig_dreg, REGNO (dreg)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
555 mark_pseudo_reg_dead (orig_reg, REGNO (reg)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
556 mark_pseudo_reg_dead (orig_dreg, REGNO (dreg)); |
0 | 557 |
558 return false; | |
559 } | |
560 | |
561 /* Check and make if necessary conflicts for pseudo DREG of class | |
562 DEF_CL of the current insn with input operand USE of class USE_CL. | |
111 | 563 ORIG_DREG is the rtx actually accessed, it may be identical to |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
564 DREG or a subreg of it. Advance the current program point before |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
565 making the conflict if ADVANCE_P. Return TRUE if we will need to |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
566 advance the current program point. */ |
0 | 567 static bool |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
568 check_and_make_def_use_conflict (rtx dreg, rtx orig_dreg, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
569 enum reg_class def_cl, int use, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
570 enum reg_class use_cl, bool advance_p) |
0 | 571 { |
572 if (! reg_classes_intersect_p (def_cl, use_cl)) | |
573 return advance_p; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
574 |
0 | 575 advance_p = make_pseudo_conflict (recog_data.operand[use], |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
576 use_cl, dreg, orig_dreg, advance_p); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
577 |
0 | 578 /* Reload may end up swapping commutative operands, so you |
579 have to take both orderings into account. The | |
580 constraints for the two operands can be completely | |
581 different. (Indeed, if the constraints for the two | |
582 operands are the same for all alternatives, there's no | |
583 point marking them as commutative.) */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
584 if (use < recog_data.n_operands - 1 |
0 | 585 && recog_data.constraints[use][0] == '%') |
586 advance_p | |
587 = make_pseudo_conflict (recog_data.operand[use + 1], | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
588 use_cl, dreg, orig_dreg, advance_p); |
0 | 589 if (use >= 1 |
590 && recog_data.constraints[use - 1][0] == '%') | |
591 advance_p | |
592 = make_pseudo_conflict (recog_data.operand[use - 1], | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
593 use_cl, dreg, orig_dreg, advance_p); |
0 | 594 return advance_p; |
595 } | |
596 | |
597 /* Check and make if necessary conflicts for definition DEF of class | |
598 DEF_CL of the current insn with input operands. Process only | |
599 constraints of alternative ALT. */ | |
600 static void | |
601 check_and_make_def_conflict (int alt, int def, enum reg_class def_cl) | |
602 { | |
603 int use, use_match; | |
604 ira_allocno_t a; | |
605 enum reg_class use_cl, acl; | |
606 bool advance_p; | |
607 rtx dreg = recog_data.operand[def]; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
608 rtx orig_dreg = dreg; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
609 |
0 | 610 if (def_cl == NO_REGS) |
611 return; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
612 |
0 | 613 if (GET_CODE (dreg) == SUBREG) |
614 dreg = SUBREG_REG (dreg); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
615 |
0 | 616 if (! REG_P (dreg) || REGNO (dreg) < FIRST_PSEUDO_REGISTER) |
617 return; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
618 |
0 | 619 a = ira_curr_regno_allocno_map[REGNO (dreg)]; |
111 | 620 acl = ALLOCNO_CLASS (a); |
0 | 621 if (! reg_classes_intersect_p (acl, def_cl)) |
622 return; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
623 |
0 | 624 advance_p = true; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
625 |
111 | 626 int n_operands = recog_data.n_operands; |
627 const operand_alternative *op_alt = &recog_op_alt[alt * n_operands]; | |
628 for (use = 0; use < n_operands; use++) | |
0 | 629 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
630 int alt1; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
631 |
0 | 632 if (use == def || recog_data.operand_type[use] == OP_OUT) |
36 | 633 continue; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
634 |
111 | 635 if (op_alt[use].anything_ok) |
0 | 636 use_cl = ALL_REGS; |
637 else | |
111 | 638 use_cl = op_alt[use].cl; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
639 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
640 /* If there's any alternative that allows USE to match DEF, do not |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
641 record a conflict. If that causes us to create an invalid |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
642 instruction due to the earlyclobber, reload must fix it up. */ |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
643 for (alt1 = 0; alt1 < recog_data.n_alternatives; alt1++) |
111 | 644 { |
645 if (!TEST_BIT (preferred_alternatives, alt1)) | |
646 continue; | |
647 const operand_alternative *op_alt1 | |
648 = &recog_op_alt[alt1 * n_operands]; | |
649 if (op_alt1[use].matches == def | |
650 || (use < n_operands - 1 | |
651 && recog_data.constraints[use][0] == '%' | |
652 && op_alt1[use + 1].matches == def) | |
653 || (use >= 1 | |
654 && recog_data.constraints[use - 1][0] == '%' | |
655 && op_alt1[use - 1].matches == def)) | |
656 break; | |
657 } | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
658 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
659 if (alt1 < recog_data.n_alternatives) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
660 continue; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
661 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
662 advance_p = check_and_make_def_use_conflict (dreg, orig_dreg, def_cl, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
663 use, use_cl, advance_p); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
664 |
111 | 665 if ((use_match = op_alt[use].matches) >= 0) |
0 | 666 { |
667 if (use_match == def) | |
36 | 668 continue; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
669 |
111 | 670 if (op_alt[use_match].anything_ok) |
0 | 671 use_cl = ALL_REGS; |
672 else | |
111 | 673 use_cl = op_alt[use_match].cl; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
674 advance_p = check_and_make_def_use_conflict (dreg, orig_dreg, def_cl, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
675 use, use_cl, advance_p); |
0 | 676 } |
677 } | |
678 } | |
679 | |
680 /* Make conflicts of early clobber pseudo registers of the current | |
681 insn with its inputs. Avoid introducing unnecessary conflicts by | |
682 checking classes of the constraints and pseudos because otherwise | |
683 significant code degradation is possible for some targets. */ | |
684 static void | |
685 make_early_clobber_and_input_conflicts (void) | |
686 { | |
687 int alt; | |
688 int def, def_match; | |
689 enum reg_class def_cl; | |
690 | |
111 | 691 int n_alternatives = recog_data.n_alternatives; |
692 int n_operands = recog_data.n_operands; | |
693 const operand_alternative *op_alt = recog_op_alt; | |
694 for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands) | |
695 if (TEST_BIT (preferred_alternatives, alt)) | |
696 for (def = 0; def < n_operands; def++) | |
697 { | |
698 def_cl = NO_REGS; | |
699 if (op_alt[def].earlyclobber) | |
700 { | |
701 if (op_alt[def].anything_ok) | |
702 def_cl = ALL_REGS; | |
703 else | |
704 def_cl = op_alt[def].cl; | |
705 check_and_make_def_conflict (alt, def, def_cl); | |
706 } | |
707 if ((def_match = op_alt[def].matches) >= 0 | |
708 && (op_alt[def_match].earlyclobber | |
709 || op_alt[def].earlyclobber)) | |
710 { | |
711 if (op_alt[def_match].anything_ok) | |
712 def_cl = ALL_REGS; | |
713 else | |
714 def_cl = op_alt[def_match].cl; | |
715 check_and_make_def_conflict (alt, def, def_cl); | |
716 } | |
717 } | |
0 | 718 } |
719 | |
720 /* Mark early clobber hard registers of the current INSN as live (if | |
721 LIVE_P) or dead. Return true if there are such registers. */ | |
722 static bool | |
111 | 723 mark_hard_reg_early_clobbers (rtx_insn *insn, bool live_p) |
0 | 724 { |
111 | 725 df_ref def; |
0 | 726 bool set_p = false; |
727 | |
111 | 728 FOR_EACH_INSN_DEF (def, insn) |
729 if (DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER)) | |
0 | 730 { |
111 | 731 rtx dreg = DF_REF_REG (def); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
732 |
0 | 733 if (GET_CODE (dreg) == SUBREG) |
734 dreg = SUBREG_REG (dreg); | |
735 if (! REG_P (dreg) || REGNO (dreg) >= FIRST_PSEUDO_REGISTER) | |
736 continue; | |
737 | |
738 /* Hard register clobbers are believed to be early clobber | |
739 because there is no way to say that non-operand hard | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
740 register clobbers are not early ones. */ |
0 | 741 if (live_p) |
111 | 742 mark_ref_live (def); |
0 | 743 else |
111 | 744 mark_ref_dead (def); |
0 | 745 set_p = true; |
746 } | |
747 | |
748 return set_p; | |
749 } | |
750 | |
751 /* Checks that CONSTRAINTS permits to use only one hard register. If | |
752 it is so, the function returns the class of the hard register. | |
753 Otherwise it returns NO_REGS. */ | |
754 static enum reg_class | |
755 single_reg_class (const char *constraints, rtx op, rtx equiv_const) | |
756 { | |
111 | 757 int c; |
0 | 758 enum reg_class cl, next_cl; |
111 | 759 enum constraint_num cn; |
0 | 760 |
761 cl = NO_REGS; | |
111 | 762 alternative_mask preferred = preferred_alternatives; |
763 for (; (c = *constraints); constraints += CONSTRAINT_LEN (c, constraints)) | |
0 | 764 if (c == '#') |
111 | 765 preferred &= ~ALTERNATIVE_BIT (0); |
0 | 766 else if (c == ',') |
111 | 767 preferred >>= 1; |
768 else if (preferred & 1) | |
0 | 769 switch (c) |
770 { | |
111 | 771 case 'g': |
772 return NO_REGS; | |
773 | |
774 default: | |
775 /* ??? Is this the best way to handle memory constraints? */ | |
776 cn = lookup_constraint (constraints); | |
777 if (insn_extra_memory_constraint (cn) | |
778 || insn_extra_special_memory_constraint (cn) | |
779 || insn_extra_address_constraint (cn)) | |
0 | 780 return NO_REGS; |
111 | 781 if (constraint_satisfied_p (op, cn) |
0 | 782 || (equiv_const != NULL_RTX |
783 && CONSTANT_P (equiv_const) | |
111 | 784 && constraint_satisfied_p (equiv_const, cn))) |
0 | 785 return NO_REGS; |
111 | 786 next_cl = reg_class_for_constraint (cn); |
787 if (next_cl == NO_REGS) | |
788 break; | |
789 if (cl == NO_REGS | |
790 ? ira_class_singleton[next_cl][GET_MODE (op)] < 0 | |
791 : (ira_class_singleton[cl][GET_MODE (op)] | |
792 != ira_class_singleton[next_cl][GET_MODE (op)])) | |
0 | 793 return NO_REGS; |
794 cl = next_cl; | |
795 break; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
796 |
0 | 797 case '0': case '1': case '2': case '3': case '4': |
798 case '5': case '6': case '7': case '8': case '9': | |
799 next_cl | |
800 = single_reg_class (recog_data.constraints[c - '0'], | |
801 recog_data.operand[c - '0'], NULL_RTX); | |
111 | 802 if (cl == NO_REGS |
803 ? ira_class_singleton[next_cl][GET_MODE (op)] < 0 | |
804 : (ira_class_singleton[cl][GET_MODE (op)] | |
805 != ira_class_singleton[next_cl][GET_MODE (op)])) | |
0 | 806 return NO_REGS; |
807 cl = next_cl; | |
808 break; | |
809 } | |
810 return cl; | |
811 } | |
812 | |
813 /* The function checks that operand OP_NUM of the current insn can use | |
814 only one hard register. If it is so, the function returns the | |
815 class of the hard register. Otherwise it returns NO_REGS. */ | |
816 static enum reg_class | |
817 single_reg_operand_class (int op_num) | |
818 { | |
819 if (op_num < 0 || recog_data.n_alternatives == 0) | |
820 return NO_REGS; | |
821 return single_reg_class (recog_data.constraints[op_num], | |
822 recog_data.operand[op_num], NULL_RTX); | |
823 } | |
824 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
825 /* The function sets up hard register set *SET to hard registers which |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
826 might be used by insn reloads because the constraints are too |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
827 strict. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
828 void |
111 | 829 ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set, |
830 alternative_mask preferred) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
831 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
832 int i, c, regno = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
833 enum reg_class cl; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
834 rtx op; |
111 | 835 machine_mode mode; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
836 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
837 CLEAR_HARD_REG_SET (*set); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
838 for (i = 0; i < recog_data.n_operands; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
839 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
840 op = recog_data.operand[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
841 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
842 if (GET_CODE (op) == SUBREG) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
843 op = SUBREG_REG (op); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
844 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
845 if (GET_CODE (op) == SCRATCH |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
846 || (REG_P (op) && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
847 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
848 const char *p = recog_data.constraints[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
849 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
850 mode = (GET_CODE (op) == SCRATCH |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
851 ? GET_MODE (op) : PSEUDO_REGNO_MODE (regno)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
852 cl = NO_REGS; |
111 | 853 for (; (c = *p); p += CONSTRAINT_LEN (c, p)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
854 if (c == '#') |
111 | 855 preferred &= ~ALTERNATIVE_BIT (0); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
856 else if (c == ',') |
111 | 857 preferred >>= 1; |
858 else if (preferred & 1) | |
859 { | |
860 cl = reg_class_for_constraint (lookup_constraint (p)); | |
861 if (cl != NO_REGS) | |
862 { | |
863 /* There is no register pressure problem if all of the | |
864 regs in this class are fixed. */ | |
865 int regno = ira_class_singleton[cl][mode]; | |
866 if (regno >= 0) | |
867 add_to_hard_reg_set (set, mode, regno); | |
868 } | |
869 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
870 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
871 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
872 } |
0 | 873 /* Processes input operands, if IN_P, or output operands otherwise of |
874 the current insn with FREQ to find allocno which can use only one | |
875 hard register and makes other currently living allocnos conflicting | |
876 with the hard register. */ | |
877 static void | |
878 process_single_reg_class_operands (bool in_p, int freq) | |
879 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
880 int i, regno; |
0 | 881 unsigned int px; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
882 enum reg_class cl; |
0 | 883 rtx operand; |
884 ira_allocno_t operand_a, a; | |
885 | |
886 for (i = 0; i < recog_data.n_operands; i++) | |
887 { | |
888 operand = recog_data.operand[i]; | |
889 if (in_p && recog_data.operand_type[i] != OP_IN | |
890 && recog_data.operand_type[i] != OP_INOUT) | |
891 continue; | |
892 if (! in_p && recog_data.operand_type[i] != OP_OUT | |
893 && recog_data.operand_type[i] != OP_INOUT) | |
894 continue; | |
895 cl = single_reg_operand_class (i); | |
896 if (cl == NO_REGS) | |
897 continue; | |
898 | |
899 operand_a = NULL; | |
900 | |
901 if (GET_CODE (operand) == SUBREG) | |
902 operand = SUBREG_REG (operand); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
903 |
0 | 904 if (REG_P (operand) |
905 && (regno = REGNO (operand)) >= FIRST_PSEUDO_REGISTER) | |
906 { | |
111 | 907 enum reg_class aclass; |
0 | 908 |
909 operand_a = ira_curr_regno_allocno_map[regno]; | |
111 | 910 aclass = ALLOCNO_CLASS (operand_a); |
911 if (ira_class_subset_p[cl][aclass]) | |
0 | 912 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
913 /* View the desired allocation of OPERAND as: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
914 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
915 (REG:YMODE YREGNO), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
916 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
917 a simplification of: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
918 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
919 (subreg:YMODE (reg:XMODE XREGNO) OFFSET). */ |
111 | 920 machine_mode ymode, xmode; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
921 int xregno, yregno; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
922 HOST_WIDE_INT offset; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
923 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
924 xmode = recog_data.operand_mode[i]; |
111 | 925 xregno = ira_class_singleton[cl][xmode]; |
926 gcc_assert (xregno >= 0); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
927 ymode = ALLOCNO_MODE (operand_a); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
928 offset = subreg_lowpart_offset (ymode, xmode); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
929 yregno = simplify_subreg_regno (xregno, xmode, offset, ymode); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
930 if (yregno >= 0 |
111 | 931 && ira_class_hard_reg_index[aclass][yregno] >= 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
932 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
933 int cost; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
934 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
935 ira_allocate_and_set_costs |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
936 (&ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a), |
111 | 937 aclass, 0); |
938 ira_init_register_move_cost_if_necessary (xmode); | |
939 cost = freq * (in_p | |
940 ? ira_register_move_cost[xmode][aclass][cl] | |
941 : ira_register_move_cost[xmode][cl][aclass]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
942 ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a) |
111 | 943 [ira_class_hard_reg_index[aclass][yregno]] -= cost; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
944 } |
0 | 945 } |
946 } | |
947 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
948 EXECUTE_IF_SET_IN_SPARSESET (objects_live, px) |
0 | 949 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
950 ira_object_t obj = ira_object_id_map[px]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
951 a = OBJECT_ALLOCNO (obj); |
0 | 952 if (a != operand_a) |
953 { | |
954 /* We could increase costs of A instead of making it | |
955 conflicting with the hard register. But it works worse | |
956 because it will be spilled in reload in anyway. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
957 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), |
0 | 958 reg_class_contents[cl]); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
959 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), |
0 | 960 reg_class_contents[cl]); |
961 } | |
962 } | |
963 } | |
964 } | |
965 | |
111 | 966 /* Look through the CALL_INSN_FUNCTION_USAGE of a call insn INSN, and see if |
967 we find a SET rtx that we can use to deduce that a register can be cheaply | |
968 caller-saved. Return such a register, or NULL_RTX if none is found. */ | |
969 static rtx | |
970 find_call_crossed_cheap_reg (rtx_insn *insn) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
971 { |
111 | 972 rtx cheap_reg = NULL_RTX; |
973 rtx exp = CALL_INSN_FUNCTION_USAGE (insn); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
974 |
111 | 975 while (exp != NULL) |
976 { | |
977 rtx x = XEXP (exp, 0); | |
978 if (GET_CODE (x) == SET) | |
979 { | |
980 exp = x; | |
981 break; | |
982 } | |
983 exp = XEXP (exp, 1); | |
984 } | |
985 if (exp != NULL) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
986 { |
111 | 987 basic_block bb = BLOCK_FOR_INSN (insn); |
988 rtx reg = SET_SRC (exp); | |
989 rtx_insn *prev = PREV_INSN (insn); | |
990 while (prev && !(INSN_P (prev) | |
991 && BLOCK_FOR_INSN (prev) != bb)) | |
992 { | |
993 if (NONDEBUG_INSN_P (prev)) | |
994 { | |
995 rtx set = single_set (prev); | |
996 | |
997 if (set && rtx_equal_p (SET_DEST (set), reg)) | |
998 { | |
999 rtx src = SET_SRC (set); | |
1000 if (!REG_P (src) || HARD_REGISTER_P (src) | |
1001 || !pseudo_regno_single_word_and_live_p (REGNO (src))) | |
1002 break; | |
1003 if (!modified_between_p (src, prev, insn)) | |
1004 cheap_reg = src; | |
1005 break; | |
1006 } | |
1007 if (set && rtx_equal_p (SET_SRC (set), reg)) | |
1008 { | |
1009 rtx dest = SET_DEST (set); | |
1010 if (!REG_P (dest) || HARD_REGISTER_P (dest) | |
1011 || !pseudo_regno_single_word_and_live_p (REGNO (dest))) | |
1012 break; | |
1013 if (!modified_between_p (dest, prev, insn)) | |
1014 cheap_reg = dest; | |
1015 break; | |
1016 } | |
1017 | |
1018 if (reg_set_p (reg, prev)) | |
1019 break; | |
1020 } | |
1021 prev = PREV_INSN (prev); | |
1022 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1023 } |
111 | 1024 return cheap_reg; |
1025 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1026 |
0 | 1027 /* Process insns of the basic block given by its LOOP_TREE_NODE to |
1028 update allocno live ranges, allocno hard register conflicts, | |
1029 intersected calls, and register pressure info for allocnos for the | |
1030 basic block for and regions containing the basic block. */ | |
1031 static void | |
1032 process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) | |
1033 { | |
1034 int i, freq; | |
1035 unsigned int j; | |
1036 basic_block bb; | |
111 | 1037 rtx_insn *insn; |
0 | 1038 bitmap_iterator bi; |
1039 bitmap reg_live_out; | |
1040 unsigned int px; | |
1041 bool set_p; | |
1042 | |
1043 bb = loop_tree_node->bb; | |
1044 if (bb != NULL) | |
1045 { | |
111 | 1046 for (i = 0; i < ira_pressure_classes_num; i++) |
0 | 1047 { |
111 | 1048 curr_reg_pressure[ira_pressure_classes[i]] = 0; |
1049 high_pressure_start_point[ira_pressure_classes[i]] = -1; | |
0 | 1050 } |
1051 curr_bb_node = loop_tree_node; | |
111 | 1052 reg_live_out = df_get_live_out (bb); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1053 sparseset_clear (objects_live); |
0 | 1054 REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out); |
1055 AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset); | |
1056 AND_COMPL_HARD_REG_SET (hard_regs_live, ira_no_alloc_regs); | |
1057 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1058 if (TEST_HARD_REG_BIT (hard_regs_live, i)) | |
1059 { | |
111 | 1060 enum reg_class aclass, pclass, cl; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1061 |
111 | 1062 aclass = ira_allocno_class_translate[REGNO_REG_CLASS (i)]; |
1063 pclass = ira_pressure_class_translate[aclass]; | |
0 | 1064 for (j = 0; |
111 | 1065 (cl = ira_reg_class_super_classes[pclass][j]) |
0 | 1066 != LIM_REG_CLASSES; |
1067 j++) | |
1068 { | |
111 | 1069 if (! ira_reg_pressure_class_p[cl]) |
1070 continue; | |
0 | 1071 curr_reg_pressure[cl]++; |
1072 if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl]) | |
1073 curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl]; | |
1074 ira_assert (curr_reg_pressure[cl] | |
111 | 1075 <= ira_class_hard_regs_num[cl]); |
0 | 1076 } |
1077 } | |
1078 EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1079 mark_pseudo_regno_live (j); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1080 |
0 | 1081 freq = REG_FREQ_FROM_BB (bb); |
1082 if (freq == 0) | |
1083 freq = 1; | |
1084 | |
1085 /* Invalidate all allocno_saved_at_call entries. */ | |
1086 last_call_num++; | |
1087 | |
1088 /* Scan the code of this basic block, noting which allocnos and | |
1089 hard regs are born or die. | |
1090 | |
1091 Note that this loop treats uninitialized values as live until | |
1092 the beginning of the block. For example, if an instruction | |
1093 uses (reg:DI foo), and only (subreg:SI (reg:DI foo) 0) is ever | |
1094 set, FOO will remain live until the beginning of the block. | |
1095 Likewise if FOO is not set at all. This is unnecessarily | |
1096 pessimistic, but it probably doesn't matter much in practice. */ | |
1097 FOR_BB_INSNS_REVERSE (bb, insn) | |
1098 { | |
111 | 1099 ira_allocno_t a; |
1100 df_ref def, use; | |
0 | 1101 bool call_p; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1102 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1103 if (!NONDEBUG_INSN_P (insn)) |
0 | 1104 continue; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1105 |
0 | 1106 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) |
1107 fprintf (ira_dump_file, " Insn %u(l%d): point = %d\n", | |
111 | 1108 INSN_UID (insn), loop_tree_node->parent->loop_num, |
0 | 1109 curr_point); |
1110 | |
111 | 1111 call_p = CALL_P (insn); |
1112 #ifdef REAL_PIC_OFFSET_TABLE_REGNUM | |
1113 int regno; | |
1114 bool clear_pic_use_conflict_p = false; | |
1115 /* Processing insn usage in call insn can create conflict | |
1116 with pic pseudo and pic hard reg and that is wrong. | |
1117 Check this situation and fix it at the end of the insn | |
1118 processing. */ | |
1119 if (call_p && pic_offset_table_rtx != NULL_RTX | |
1120 && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER | |
1121 && (a = ira_curr_regno_allocno_map[regno]) != NULL) | |
1122 clear_pic_use_conflict_p | |
1123 = (find_regno_fusage (insn, USE, REAL_PIC_OFFSET_TABLE_REGNUM) | |
1124 && ! TEST_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS | |
1125 (ALLOCNO_OBJECT (a, 0)), | |
1126 REAL_PIC_OFFSET_TABLE_REGNUM)); | |
1127 #endif | |
1128 | |
0 | 1129 /* Mark each defined value as live. We need to do this for |
1130 unused values because they still conflict with quantities | |
1131 that are live at the time of the definition. | |
1132 | |
1133 Ignore DF_REF_MAY_CLOBBERs on a call instruction. Such | |
1134 references represent the effect of the called function | |
1135 on a call-clobbered register. Marking the register as | |
1136 live would stop us from allocating it to a call-crossing | |
1137 allocno. */ | |
111 | 1138 FOR_EACH_INSN_DEF (def, insn) |
1139 if (!call_p || !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)) | |
1140 mark_ref_live (def); | |
0 | 1141 |
1142 /* If INSN has multiple outputs, then any value used in one | |
1143 of the outputs conflicts with the other outputs. Model this | |
1144 by making the used value live during the output phase. | |
1145 | |
1146 It is unsafe to use !single_set here since it will ignore | |
1147 an unused output. Just because an output is unused does | |
1148 not mean the compiler can assume the side effect will not | |
1149 occur. Consider if ALLOCNO appears in the address of an | |
1150 output and we reload the output. If we allocate ALLOCNO | |
1151 to the same hard register as an unused output we could | |
1152 set the hard register before the output reload insn. */ | |
1153 if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn)) | |
111 | 1154 FOR_EACH_INSN_USE (use, insn) |
0 | 1155 { |
1156 int i; | |
1157 rtx reg; | |
1158 | |
111 | 1159 reg = DF_REF_REG (use); |
0 | 1160 for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) |
1161 { | |
1162 rtx set; | |
1163 | |
1164 set = XVECEXP (PATTERN (insn), 0, i); | |
1165 if (GET_CODE (set) == SET | |
1166 && reg_overlap_mentioned_p (reg, SET_DEST (set))) | |
1167 { | |
1168 /* After the previous loop, this is a no-op if | |
1169 REG is contained within SET_DEST (SET). */ | |
111 | 1170 mark_ref_live (use); |
0 | 1171 break; |
1172 } | |
1173 } | |
1174 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1175 |
0 | 1176 extract_insn (insn); |
111 | 1177 preferred_alternatives = get_preferred_alternatives (insn); |
1178 preprocess_constraints (insn); | |
0 | 1179 process_single_reg_class_operands (false, freq); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1180 |
0 | 1181 /* See which defined values die here. */ |
111 | 1182 FOR_EACH_INSN_DEF (def, insn) |
1183 if (!call_p || !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)) | |
1184 mark_ref_dead (def); | |
0 | 1185 |
1186 if (call_p) | |
1187 { | |
111 | 1188 /* Try to find a SET in the CALL_INSN_FUNCTION_USAGE, and from |
1189 there, try to find a pseudo that is live across the call but | |
1190 can be cheaply reconstructed from the return value. */ | |
1191 rtx cheap_reg = find_call_crossed_cheap_reg (insn); | |
1192 if (cheap_reg != NULL_RTX) | |
1193 add_reg_note (insn, REG_RETURNED, cheap_reg); | |
1194 | |
0 | 1195 last_call_num++; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1196 sparseset_clear (allocnos_processed); |
0 | 1197 /* The current set of live allocnos are live across the call. */ |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1198 EXECUTE_IF_SET_IN_SPARSESET (objects_live, i) |
0 | 1199 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1200 ira_object_t obj = ira_object_id_map[i]; |
111 | 1201 a = OBJECT_ALLOCNO (obj); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1202 int num = ALLOCNO_NUM (a); |
111 | 1203 HARD_REG_SET this_call_used_reg_set; |
1204 | |
1205 get_call_reg_set_usage (insn, &this_call_used_reg_set, | |
1206 call_used_reg_set); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1207 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1208 /* Don't allocate allocnos that cross setjmps or any |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1209 call, if this function receives a nonlocal |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1210 goto. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1211 if (cfun->has_nonlocal_label |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1212 || find_reg_note (insn, REG_SETJMP, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1213 NULL_RTX) != NULL_RTX) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1214 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1215 SET_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1216 SET_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1217 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1218 if (can_throw_internal (insn)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1219 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1220 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), |
111 | 1221 this_call_used_reg_set); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1222 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), |
111 | 1223 this_call_used_reg_set); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1224 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1225 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1226 if (sparseset_bit_p (allocnos_processed, num)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1227 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1228 sparseset_set_bit (allocnos_processed, num); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1229 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1230 if (allocno_saved_at_call[num] != last_call_num) |
111 | 1231 /* Here we are mimicking caller-save.c behavior |
0 | 1232 which does not save hard register at a call if |
1233 it was saved on previous call in the same basic | |
1234 block and the hard register was not mentioned | |
1235 between the two calls. */ | |
1236 ALLOCNO_CALL_FREQ (a) += freq; | |
1237 /* Mark it as saved at the next call. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1238 allocno_saved_at_call[num] = last_call_num + 1; |
0 | 1239 ALLOCNO_CALLS_CROSSED_NUM (a)++; |
111 | 1240 IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a), |
1241 this_call_used_reg_set); | |
1242 if (cheap_reg != NULL_RTX | |
1243 && ALLOCNO_REGNO (a) == (int) REGNO (cheap_reg)) | |
1244 ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a)++; | |
0 | 1245 } |
1246 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1247 |
0 | 1248 make_early_clobber_and_input_conflicts (); |
1249 | |
1250 curr_point++; | |
111 | 1251 |
0 | 1252 /* Mark each used value as live. */ |
111 | 1253 FOR_EACH_INSN_USE (use, insn) |
1254 mark_ref_live (use); | |
0 | 1255 |
1256 process_single_reg_class_operands (true, freq); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1257 |
0 | 1258 set_p = mark_hard_reg_early_clobbers (insn, true); |
1259 | |
1260 if (set_p) | |
1261 { | |
1262 mark_hard_reg_early_clobbers (insn, false); | |
1263 | |
1264 /* Mark each hard reg as live again. For example, a | |
1265 hard register can be in clobber and in an insn | |
1266 input. */ | |
111 | 1267 FOR_EACH_INSN_USE (use, insn) |
0 | 1268 { |
111 | 1269 rtx ureg = DF_REF_REG (use); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1270 |
0 | 1271 if (GET_CODE (ureg) == SUBREG) |
1272 ureg = SUBREG_REG (ureg); | |
1273 if (! REG_P (ureg) || REGNO (ureg) >= FIRST_PSEUDO_REGISTER) | |
1274 continue; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1275 |
111 | 1276 mark_ref_live (use); |
0 | 1277 } |
1278 } | |
1279 | |
111 | 1280 #ifdef REAL_PIC_OFFSET_TABLE_REGNUM |
1281 if (clear_pic_use_conflict_p) | |
1282 { | |
1283 regno = REGNO (pic_offset_table_rtx); | |
1284 a = ira_curr_regno_allocno_map[regno]; | |
1285 CLEAR_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (ALLOCNO_OBJECT (a, 0)), | |
1286 REAL_PIC_OFFSET_TABLE_REGNUM); | |
1287 CLEAR_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS | |
1288 (ALLOCNO_OBJECT (a, 0)), | |
1289 REAL_PIC_OFFSET_TABLE_REGNUM); | |
1290 } | |
1291 #endif | |
0 | 1292 curr_point++; |
1293 } | |
1294 | |
1295 if (bb_has_eh_pred (bb)) | |
1296 for (j = 0; ; ++j) | |
1297 { | |
1298 unsigned int regno = EH_RETURN_DATA_REGNO (j); | |
1299 if (regno == INVALID_REGNUM) | |
1300 break; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1301 make_hard_regno_born (regno); |
0 | 1302 } |
1303 | |
1304 /* Allocnos can't go in stack regs at the start of a basic block | |
1305 that is reached by an abnormal edge. Likewise for call | |
1306 clobbered regs, because caller-save, fixup_abnormal_edges and | |
1307 possibly the table driven EH machinery are not quite ready to | |
1308 handle such allocnos live across such edges. */ | |
1309 if (bb_has_abnormal_pred (bb)) | |
1310 { | |
1311 #ifdef STACK_REGS | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1312 EXECUTE_IF_SET_IN_SPARSESET (objects_live, px) |
0 | 1313 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1314 ira_allocno_t a = OBJECT_ALLOCNO (ira_object_id_map[px]); |
111 | 1315 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1316 ALLOCNO_NO_STACK_REG_P (a) = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1317 ALLOCNO_TOTAL_NO_STACK_REG_P (a) = true; |
0 | 1318 } |
1319 for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1320 make_hard_regno_born (px); |
0 | 1321 #endif |
1322 /* No need to record conflicts for call clobbered regs if we | |
1323 have nonlocal labels around, as we don't ever try to | |
1324 allocate such regs in this case. */ | |
111 | 1325 if (!cfun->has_nonlocal_label |
1326 && has_abnormal_call_or_eh_pred_edge_p (bb)) | |
0 | 1327 for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) |
111 | 1328 if (call_used_regs[px] |
1329 #ifdef REAL_PIC_OFFSET_TABLE_REGNUM | |
1330 /* We should create a conflict of PIC pseudo with | |
1331 PIC hard reg as PIC hard reg can have a wrong | |
1332 value after jump described by the abnormal edge. | |
1333 In this case we can not allocate PIC hard reg to | |
1334 PIC pseudo as PIC pseudo will also have a wrong | |
1335 value. This code is not critical as LRA can fix | |
1336 it but it is better to have the right allocation | |
1337 earlier. */ | |
1338 || (px == REAL_PIC_OFFSET_TABLE_REGNUM | |
1339 && pic_offset_table_rtx != NULL_RTX | |
1340 && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) | |
1341 #endif | |
1342 ) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1343 make_hard_regno_born (px); |
0 | 1344 } |
1345 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1346 EXECUTE_IF_SET_IN_SPARSESET (objects_live, i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1347 make_object_dead (ira_object_id_map[i]); |
0 | 1348 |
1349 curr_point++; | |
1350 | |
1351 } | |
111 | 1352 /* Propagate register pressure to upper loop tree nodes. */ |
0 | 1353 if (loop_tree_node != ira_loop_tree_root) |
111 | 1354 for (i = 0; i < ira_pressure_classes_num; i++) |
0 | 1355 { |
111 | 1356 enum reg_class pclass; |
0 | 1357 |
111 | 1358 pclass = ira_pressure_classes[i]; |
1359 if (loop_tree_node->reg_pressure[pclass] | |
1360 > loop_tree_node->parent->reg_pressure[pclass]) | |
1361 loop_tree_node->parent->reg_pressure[pclass] | |
1362 = loop_tree_node->reg_pressure[pclass]; | |
0 | 1363 } |
1364 } | |
1365 | |
1366 /* Create and set up IRA_START_POINT_RANGES and | |
1367 IRA_FINISH_POINT_RANGES. */ | |
1368 static void | |
1369 create_start_finish_chains (void) | |
1370 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1371 ira_object_t obj; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1372 ira_object_iterator oi; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1373 live_range_t r; |
0 | 1374 |
1375 ira_start_point_ranges | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1376 = (live_range_t *) ira_allocate (ira_max_point * sizeof (live_range_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1377 memset (ira_start_point_ranges, 0, ira_max_point * sizeof (live_range_t)); |
0 | 1378 ira_finish_point_ranges |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1379 = (live_range_t *) ira_allocate (ira_max_point * sizeof (live_range_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1380 memset (ira_finish_point_ranges, 0, ira_max_point * sizeof (live_range_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1381 FOR_EACH_OBJECT (obj, oi) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1382 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1383 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1384 r->start_next = ira_start_point_ranges[r->start]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1385 ira_start_point_ranges[r->start] = r; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1386 r->finish_next = ira_finish_point_ranges[r->finish]; |
0 | 1387 ira_finish_point_ranges[r->finish] = r; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1388 } |
0 | 1389 } |
1390 | |
1391 /* Rebuild IRA_START_POINT_RANGES and IRA_FINISH_POINT_RANGES after | |
1392 new live ranges and program points were added as a result if new | |
1393 insn generation. */ | |
1394 void | |
1395 ira_rebuild_start_finish_chains (void) | |
1396 { | |
1397 ira_free (ira_finish_point_ranges); | |
1398 ira_free (ira_start_point_ranges); | |
1399 create_start_finish_chains (); | |
1400 } | |
1401 | |
1402 /* Compress allocno live ranges by removing program points where | |
1403 nothing happens. */ | |
1404 static void | |
1405 remove_some_program_points_and_update_live_ranges (void) | |
1406 { | |
1407 unsigned i; | |
1408 int n; | |
1409 int *map; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1410 ira_object_t obj; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1411 ira_object_iterator oi; |
111 | 1412 live_range_t r, prev_r, next_r; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1413 sbitmap_iterator sbi; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1414 bool born_p, dead_p, prev_born_p, prev_dead_p; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1415 |
111 | 1416 auto_sbitmap born (ira_max_point); |
1417 auto_sbitmap dead (ira_max_point); | |
1418 bitmap_clear (born); | |
1419 bitmap_clear (dead); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1420 FOR_EACH_OBJECT (obj, oi) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1421 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1422 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1423 ira_assert (r->start <= r->finish); |
111 | 1424 bitmap_set_bit (born, r->start); |
1425 bitmap_set_bit (dead, r->finish); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1426 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1427 |
111 | 1428 auto_sbitmap born_or_dead (ira_max_point); |
1429 bitmap_ior (born_or_dead, born, dead); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1430 map = (int *) ira_allocate (sizeof (int) * ira_max_point); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1431 n = -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1432 prev_born_p = prev_dead_p = false; |
111 | 1433 EXECUTE_IF_SET_IN_BITMAP (born_or_dead, 0, i, sbi) |
0 | 1434 { |
111 | 1435 born_p = bitmap_bit_p (born, i); |
1436 dead_p = bitmap_bit_p (dead, i); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1437 if ((prev_born_p && ! prev_dead_p && born_p && ! dead_p) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1438 || (prev_dead_p && ! prev_born_p && dead_p && ! born_p)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1439 map[i] = n; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1440 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1441 map[i] = ++n; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1442 prev_born_p = born_p; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1443 prev_dead_p = dead_p; |
0 | 1444 } |
111 | 1445 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1446 n++; |
0 | 1447 if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL) |
1448 fprintf (ira_dump_file, "Compressing live ranges: from %d to %d - %d%%\n", | |
1449 ira_max_point, n, 100 * n / ira_max_point); | |
1450 ira_max_point = n; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1451 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1452 FOR_EACH_OBJECT (obj, oi) |
111 | 1453 for (r = OBJECT_LIVE_RANGES (obj), prev_r = NULL; r != NULL; r = next_r) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1454 { |
111 | 1455 next_r = r->next; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1456 r->start = map[r->start]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1457 r->finish = map[r->finish]; |
111 | 1458 if (prev_r == NULL || prev_r->start > r->finish + 1) |
1459 { | |
1460 prev_r = r; | |
1461 continue; | |
1462 } | |
1463 prev_r->start = r->start; | |
1464 prev_r->next = next_r; | |
1465 ira_finish_live_range (r); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1466 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1467 |
0 | 1468 ira_free (map); |
1469 } | |
1470 | |
1471 /* Print live ranges R to file F. */ | |
1472 void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1473 ira_print_live_range_list (FILE *f, live_range_t r) |
0 | 1474 { |
1475 for (; r != NULL; r = r->next) | |
1476 fprintf (f, " [%d..%d]", r->start, r->finish); | |
1477 fprintf (f, "\n"); | |
1478 } | |
1479 | |
111 | 1480 DEBUG_FUNCTION void |
1481 debug (live_range &ref) | |
1482 { | |
1483 ira_print_live_range_list (stderr, &ref); | |
1484 } | |
1485 | |
1486 DEBUG_FUNCTION void | |
1487 debug (live_range *ptr) | |
1488 { | |
1489 if (ptr) | |
1490 debug (*ptr); | |
1491 else | |
1492 fprintf (stderr, "<nil>\n"); | |
1493 } | |
1494 | |
0 | 1495 /* Print live ranges R to stderr. */ |
1496 void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1497 ira_debug_live_range_list (live_range_t r) |
0 | 1498 { |
1499 ira_print_live_range_list (stderr, r); | |
1500 } | |
1501 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1502 /* Print live ranges of object OBJ to file F. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1503 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1504 print_object_live_ranges (FILE *f, ira_object_t obj) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1505 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1506 ira_print_live_range_list (f, OBJECT_LIVE_RANGES (obj)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1507 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1508 |
0 | 1509 /* Print live ranges of allocno A to file F. */ |
1510 static void | |
1511 print_allocno_live_ranges (FILE *f, ira_allocno_t a) | |
1512 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1513 int n = ALLOCNO_NUM_OBJECTS (a); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1514 int i; |
111 | 1515 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1516 for (i = 0; i < n; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1517 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1518 fprintf (f, " a%d(r%d", ALLOCNO_NUM (a), ALLOCNO_REGNO (a)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1519 if (n > 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1520 fprintf (f, " [%d]", i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1521 fprintf (f, "):"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1522 print_object_live_ranges (f, ALLOCNO_OBJECT (a, i)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1523 } |
0 | 1524 } |
1525 | |
1526 /* Print live ranges of allocno A to stderr. */ | |
1527 void | |
1528 ira_debug_allocno_live_ranges (ira_allocno_t a) | |
1529 { | |
1530 print_allocno_live_ranges (stderr, a); | |
1531 } | |
1532 | |
1533 /* Print live ranges of all allocnos to file F. */ | |
1534 static void | |
1535 print_live_ranges (FILE *f) | |
1536 { | |
1537 ira_allocno_t a; | |
1538 ira_allocno_iterator ai; | |
1539 | |
1540 FOR_EACH_ALLOCNO (a, ai) | |
1541 print_allocno_live_ranges (f, a); | |
1542 } | |
1543 | |
1544 /* Print live ranges of all allocnos to stderr. */ | |
1545 void | |
1546 ira_debug_live_ranges (void) | |
1547 { | |
1548 print_live_ranges (stderr); | |
1549 } | |
1550 | |
1551 /* The main entry function creates live ranges, set up | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1552 CONFLICT_HARD_REGS and TOTAL_CONFLICT_HARD_REGS for objects, and |
0 | 1553 calculate register pressure info. */ |
1554 void | |
1555 ira_create_allocno_live_ranges (void) | |
1556 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1557 objects_live = sparseset_alloc (ira_objects_num); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1558 allocnos_processed = sparseset_alloc (ira_allocnos_num); |
0 | 1559 curr_point = 0; |
1560 last_call_num = 0; | |
1561 allocno_saved_at_call | |
1562 = (int *) ira_allocate (ira_allocnos_num * sizeof (int)); | |
1563 memset (allocno_saved_at_call, 0, ira_allocnos_num * sizeof (int)); | |
1564 ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, | |
1565 process_bb_node_lives); | |
1566 ira_max_point = curr_point; | |
1567 create_start_finish_chains (); | |
1568 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) | |
1569 print_live_ranges (ira_dump_file); | |
1570 /* Clean up. */ | |
1571 ira_free (allocno_saved_at_call); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1572 sparseset_free (objects_live); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1573 sparseset_free (allocnos_processed); |
0 | 1574 } |
1575 | |
1576 /* Compress allocno live ranges. */ | |
1577 void | |
1578 ira_compress_allocno_live_ranges (void) | |
1579 { | |
1580 remove_some_program_points_and_update_live_ranges (); | |
1581 ira_rebuild_start_finish_chains (); | |
1582 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) | |
1583 { | |
1584 fprintf (ira_dump_file, "Ranges after the compression:\n"); | |
1585 print_live_ranges (ira_dump_file); | |
1586 } | |
1587 } | |
1588 | |
1589 /* Free arrays IRA_START_POINT_RANGES and IRA_FINISH_POINT_RANGES. */ | |
1590 void | |
1591 ira_finish_allocno_live_ranges (void) | |
1592 { | |
1593 ira_free (ira_finish_point_ranges); | |
1594 ira_free (ira_start_point_ranges); | |
1595 } |