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