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