annotate gcc/lra-assigns.c @ 143:76e1cf5455ef

add cbc_gc test
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 19:24:05 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Assign reload pseudos.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
10 version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
15 for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 /* This file's main objective is to assign hard registers to reload
kono
parents:
diff changeset
23 pseudos. It also tries to allocate hard registers to other
kono
parents:
diff changeset
24 pseudos, but at a lower priority than the reload pseudos. The pass
kono
parents:
diff changeset
25 does not transform the RTL.
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 We must allocate a hard register to every reload pseudo. We try to
kono
parents:
diff changeset
28 increase the chances of finding a viable allocation by assigning
kono
parents:
diff changeset
29 the pseudos in order of fewest available hard registers first. If
kono
parents:
diff changeset
30 we still fail to find a hard register, we spill other (non-reload)
kono
parents:
diff changeset
31 pseudos in order to make room.
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 find_hard_regno_for finds hard registers for allocation without
kono
parents:
diff changeset
34 spilling. spill_for does the same with spilling. Both functions
kono
parents:
diff changeset
35 use a cost model to determine the most profitable choice of hard
kono
parents:
diff changeset
36 and spill registers.
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 Once we have finished allocating reload pseudos, we also try to
kono
parents:
diff changeset
39 assign registers to other (non-reload) pseudos. This is useful if
kono
parents:
diff changeset
40 hard registers were freed up by the spilling just described.
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 We try to assign hard registers by collecting pseudos into threads.
kono
parents:
diff changeset
43 These threads contain reload and inheritance pseudos that are
kono
parents:
diff changeset
44 connected by copies (move insns). Doing this improves the chances
kono
parents:
diff changeset
45 of pseudos in the thread getting the same hard register and, as a
kono
parents:
diff changeset
46 result, of allowing some move insns to be deleted.
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 When we assign a hard register to a pseudo, we decrease the cost of
kono
parents:
diff changeset
49 using the same hard register for pseudos that are connected by
kono
parents:
diff changeset
50 copies.
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 If two hard registers have the same frequency-derived cost, we
kono
parents:
diff changeset
53 prefer hard registers with higher priorities. The mapping of
kono
parents:
diff changeset
54 registers to priorities is controlled by the register_priority
kono
parents:
diff changeset
55 target hook. For example, x86-64 has a few register priorities:
kono
parents:
diff changeset
56 hard registers with and without REX prefixes have different
kono
parents:
diff changeset
57 priorities. This permits us to generate smaller code as insns
kono
parents:
diff changeset
58 without REX prefixes are shorter.
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 If a few hard registers are still equally good for the assignment,
kono
parents:
diff changeset
61 we choose the least used hard register. It is called leveling and
kono
parents:
diff changeset
62 may be profitable for some targets.
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 Only insns with changed allocation pseudos are processed on the
kono
parents:
diff changeset
65 next constraint pass.
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 The pseudo live-ranges are used to find conflicting pseudos.
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 For understanding the code, it is important to keep in mind that
kono
parents:
diff changeset
70 inheritance, split, and reload pseudos created since last
kono
parents:
diff changeset
71 constraint pass have regno >= lra_constraint_new_regno_start.
kono
parents:
diff changeset
72 Inheritance and split pseudos created on any pass are in the
kono
parents:
diff changeset
73 corresponding bitmaps. Inheritance and split pseudos since the
kono
parents:
diff changeset
74 last constraint pass have also the corresponding non-negative
kono
parents:
diff changeset
75 restore_regno. */
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 #include "config.h"
kono
parents:
diff changeset
78 #include "system.h"
kono
parents:
diff changeset
79 #include "coretypes.h"
kono
parents:
diff changeset
80 #include "backend.h"
kono
parents:
diff changeset
81 #include "target.h"
kono
parents:
diff changeset
82 #include "rtl.h"
kono
parents:
diff changeset
83 #include "tree.h"
kono
parents:
diff changeset
84 #include "predict.h"
kono
parents:
diff changeset
85 #include "df.h"
kono
parents:
diff changeset
86 #include "memmodel.h"
kono
parents:
diff changeset
87 #include "tm_p.h"
kono
parents:
diff changeset
88 #include "insn-config.h"
kono
parents:
diff changeset
89 #include "regs.h"
kono
parents:
diff changeset
90 #include "ira.h"
kono
parents:
diff changeset
91 #include "recog.h"
kono
parents:
diff changeset
92 #include "rtl-error.h"
kono
parents:
diff changeset
93 #include "sparseset.h"
kono
parents:
diff changeset
94 #include "params.h"
kono
parents:
diff changeset
95 #include "lra.h"
kono
parents:
diff changeset
96 #include "lra-int.h"
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 /* Current iteration number of the pass and current iteration number
kono
parents:
diff changeset
99 of the pass after the latest spill pass when any former reload
kono
parents:
diff changeset
100 pseudo was spilled. */
kono
parents:
diff changeset
101 int lra_assignment_iter;
kono
parents:
diff changeset
102 int lra_assignment_iter_after_spill;
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 /* Flag of spilling former reload pseudos on this pass. */
kono
parents:
diff changeset
105 static bool former_reload_pseudo_spill_p;
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 /* Array containing corresponding values of function
kono
parents:
diff changeset
108 lra_get_allocno_class. It is used to speed up the code. */
kono
parents:
diff changeset
109 static enum reg_class *regno_allocno_class_array;
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 /* Array containing lengths of pseudo live ranges. It is used to
kono
parents:
diff changeset
112 speed up the code. */
kono
parents:
diff changeset
113 static int *regno_live_length;
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 /* Information about the thread to which a pseudo belongs. Threads are
kono
parents:
diff changeset
116 a set of connected reload and inheritance pseudos with the same set of
kono
parents:
diff changeset
117 available hard registers. Lone registers belong to their own threads. */
kono
parents:
diff changeset
118 struct regno_assign_info
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 /* First/next pseudo of the same thread. */
kono
parents:
diff changeset
121 int first, next;
kono
parents:
diff changeset
122 /* Frequency of the thread (execution frequency of only reload
kono
parents:
diff changeset
123 pseudos in the thread when the thread contains a reload pseudo).
kono
parents:
diff changeset
124 Defined only for the first thread pseudo. */
kono
parents:
diff changeset
125 int freq;
kono
parents:
diff changeset
126 };
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 /* Map regno to the corresponding regno assignment info. */
kono
parents:
diff changeset
129 static struct regno_assign_info *regno_assign_info;
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 /* All inherited, subreg or optional pseudos created before last spill
kono
parents:
diff changeset
132 sub-pass. Such pseudos are permitted to get memory instead of hard
kono
parents:
diff changeset
133 regs. */
kono
parents:
diff changeset
134 static bitmap_head non_reload_pseudos;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 /* Process a pseudo copy with execution frequency COPY_FREQ connecting
kono
parents:
diff changeset
137 REGNO1 and REGNO2 to form threads. */
kono
parents:
diff changeset
138 static void
kono
parents:
diff changeset
139 process_copy_to_form_thread (int regno1, int regno2, int copy_freq)
kono
parents:
diff changeset
140 {
kono
parents:
diff changeset
141 int last, regno1_first, regno2_first;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 lra_assert (regno1 >= lra_constraint_new_regno_start
kono
parents:
diff changeset
144 && regno2 >= lra_constraint_new_regno_start);
kono
parents:
diff changeset
145 regno1_first = regno_assign_info[regno1].first;
kono
parents:
diff changeset
146 regno2_first = regno_assign_info[regno2].first;
kono
parents:
diff changeset
147 if (regno1_first != regno2_first)
kono
parents:
diff changeset
148 {
kono
parents:
diff changeset
149 for (last = regno2_first;
kono
parents:
diff changeset
150 regno_assign_info[last].next >= 0;
kono
parents:
diff changeset
151 last = regno_assign_info[last].next)
kono
parents:
diff changeset
152 regno_assign_info[last].first = regno1_first;
kono
parents:
diff changeset
153 regno_assign_info[last].first = regno1_first;
kono
parents:
diff changeset
154 regno_assign_info[last].next = regno_assign_info[regno1_first].next;
kono
parents:
diff changeset
155 regno_assign_info[regno1_first].next = regno2_first;
kono
parents:
diff changeset
156 regno_assign_info[regno1_first].freq
kono
parents:
diff changeset
157 += regno_assign_info[regno2_first].freq;
kono
parents:
diff changeset
158 }
kono
parents:
diff changeset
159 regno_assign_info[regno1_first].freq -= 2 * copy_freq;
kono
parents:
diff changeset
160 lra_assert (regno_assign_info[regno1_first].freq >= 0);
kono
parents:
diff changeset
161 }
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 /* Initialize REGNO_ASSIGN_INFO and form threads. */
kono
parents:
diff changeset
164 static void
kono
parents:
diff changeset
165 init_regno_assign_info (void)
kono
parents:
diff changeset
166 {
kono
parents:
diff changeset
167 int i, regno1, regno2, max_regno = max_reg_num ();
kono
parents:
diff changeset
168 lra_copy_t cp;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 regno_assign_info = XNEWVEC (struct regno_assign_info, max_regno);
kono
parents:
diff changeset
171 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
172 {
kono
parents:
diff changeset
173 regno_assign_info[i].first = i;
kono
parents:
diff changeset
174 regno_assign_info[i].next = -1;
kono
parents:
diff changeset
175 regno_assign_info[i].freq = lra_reg_info[i].freq;
kono
parents:
diff changeset
176 }
kono
parents:
diff changeset
177 /* Form the threads. */
kono
parents:
diff changeset
178 for (i = 0; (cp = lra_get_copy (i)) != NULL; i++)
kono
parents:
diff changeset
179 if ((regno1 = cp->regno1) >= lra_constraint_new_regno_start
kono
parents:
diff changeset
180 && (regno2 = cp->regno2) >= lra_constraint_new_regno_start
kono
parents:
diff changeset
181 && reg_renumber[regno1] < 0 && lra_reg_info[regno1].nrefs != 0
kono
parents:
diff changeset
182 && reg_renumber[regno2] < 0 && lra_reg_info[regno2].nrefs != 0
kono
parents:
diff changeset
183 && (ira_class_hard_regs_num[regno_allocno_class_array[regno1]]
kono
parents:
diff changeset
184 == ira_class_hard_regs_num[regno_allocno_class_array[regno2]]))
kono
parents:
diff changeset
185 process_copy_to_form_thread (regno1, regno2, cp->freq);
kono
parents:
diff changeset
186 }
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 /* Free REGNO_ASSIGN_INFO. */
kono
parents:
diff changeset
189 static void
kono
parents:
diff changeset
190 finish_regno_assign_info (void)
kono
parents:
diff changeset
191 {
kono
parents:
diff changeset
192 free (regno_assign_info);
kono
parents:
diff changeset
193 }
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 /* The function is used to sort *reload* and *inheritance* pseudos to
kono
parents:
diff changeset
196 try to assign them hard registers. We put pseudos from the same
kono
parents:
diff changeset
197 thread always nearby. */
kono
parents:
diff changeset
198 static int
kono
parents:
diff changeset
199 reload_pseudo_compare_func (const void *v1p, const void *v2p)
kono
parents:
diff changeset
200 {
kono
parents:
diff changeset
201 int r1 = *(const int *) v1p, r2 = *(const int *) v2p;
kono
parents:
diff changeset
202 enum reg_class cl1 = regno_allocno_class_array[r1];
kono
parents:
diff changeset
203 enum reg_class cl2 = regno_allocno_class_array[r2];
kono
parents:
diff changeset
204 int diff;
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 lra_assert (r1 >= lra_constraint_new_regno_start
kono
parents:
diff changeset
207 && r2 >= lra_constraint_new_regno_start);
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 /* Prefer to assign reload registers with smaller classes first to
kono
parents:
diff changeset
210 guarantee assignment to all reload registers. */
kono
parents:
diff changeset
211 if ((diff = (ira_class_hard_regs_num[cl1]
kono
parents:
diff changeset
212 - ira_class_hard_regs_num[cl2])) != 0)
kono
parents:
diff changeset
213 return diff;
kono
parents:
diff changeset
214 /* Allocate bigger pseudos first to avoid register file
kono
parents:
diff changeset
215 fragmentation. */
kono
parents:
diff changeset
216 if ((diff
kono
parents:
diff changeset
217 = (ira_reg_class_max_nregs[cl2][lra_reg_info[r2].biggest_mode]
kono
parents:
diff changeset
218 - ira_reg_class_max_nregs[cl1][lra_reg_info[r1].biggest_mode])) != 0)
kono
parents:
diff changeset
219 return diff;
kono
parents:
diff changeset
220 if ((diff = (regno_assign_info[regno_assign_info[r2].first].freq
kono
parents:
diff changeset
221 - regno_assign_info[regno_assign_info[r1].first].freq)) != 0)
kono
parents:
diff changeset
222 return diff;
kono
parents:
diff changeset
223 /* Put pseudos from the thread nearby. */
kono
parents:
diff changeset
224 if ((diff = regno_assign_info[r1].first - regno_assign_info[r2].first) != 0)
kono
parents:
diff changeset
225 return diff;
kono
parents:
diff changeset
226 /* Prefer pseudos with longer live ranges. It sets up better
kono
parents:
diff changeset
227 prefered hard registers for the thread pseudos and decreases
kono
parents:
diff changeset
228 register-register moves between the thread pseudos. */
kono
parents:
diff changeset
229 if ((diff = regno_live_length[r2] - regno_live_length[r1]) != 0)
kono
parents:
diff changeset
230 return diff;
kono
parents:
diff changeset
231 /* If regs are equally good, sort by their numbers, so that the
kono
parents:
diff changeset
232 results of qsort leave nothing to chance. */
kono
parents:
diff changeset
233 return r1 - r2;
kono
parents:
diff changeset
234 }
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 /* The function is used to sort *non-reload* pseudos to try to assign
kono
parents:
diff changeset
237 them hard registers. The order calculation is simpler than in the
kono
parents:
diff changeset
238 previous function and based on the pseudo frequency usage. */
kono
parents:
diff changeset
239 static int
kono
parents:
diff changeset
240 pseudo_compare_func (const void *v1p, const void *v2p)
kono
parents:
diff changeset
241 {
kono
parents:
diff changeset
242 int r1 = *(const int *) v1p, r2 = *(const int *) v2p;
kono
parents:
diff changeset
243 int diff;
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 /* Assign hard reg to static chain pointer first pseudo when
kono
parents:
diff changeset
246 non-local goto is used. */
kono
parents:
diff changeset
247 if ((diff = (non_spilled_static_chain_regno_p (r2)
kono
parents:
diff changeset
248 - non_spilled_static_chain_regno_p (r1))) != 0)
kono
parents:
diff changeset
249 return diff;
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 /* Prefer to assign more frequently used registers first. */
kono
parents:
diff changeset
252 if ((diff = lra_reg_info[r2].freq - lra_reg_info[r1].freq) != 0)
kono
parents:
diff changeset
253 return diff;
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 /* If regs are equally good, sort by their numbers, so that the
kono
parents:
diff changeset
256 results of qsort leave nothing to chance. */
kono
parents:
diff changeset
257 return r1 - r2;
kono
parents:
diff changeset
258 }
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 /* Arrays of size LRA_LIVE_MAX_POINT mapping a program point to the
kono
parents:
diff changeset
261 pseudo live ranges with given start point. We insert only live
kono
parents:
diff changeset
262 ranges of pseudos interesting for assignment purposes. They are
kono
parents:
diff changeset
263 reload pseudos and pseudos assigned to hard registers. */
kono
parents:
diff changeset
264 static lra_live_range_t *start_point_ranges;
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 /* Used as a flag that a live range is not inserted in the start point
kono
parents:
diff changeset
267 chain. */
kono
parents:
diff changeset
268 static struct lra_live_range not_in_chain_mark;
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 /* Create and set up START_POINT_RANGES. */
kono
parents:
diff changeset
271 static void
kono
parents:
diff changeset
272 create_live_range_start_chains (void)
kono
parents:
diff changeset
273 {
kono
parents:
diff changeset
274 int i, max_regno;
kono
parents:
diff changeset
275 lra_live_range_t r;
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 start_point_ranges = XCNEWVEC (lra_live_range_t, lra_live_max_point);
kono
parents:
diff changeset
278 max_regno = max_reg_num ();
kono
parents:
diff changeset
279 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
280 if (i >= lra_constraint_new_regno_start || reg_renumber[i] >= 0)
kono
parents:
diff changeset
281 {
kono
parents:
diff changeset
282 for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
283 {
kono
parents:
diff changeset
284 r->start_next = start_point_ranges[r->start];
kono
parents:
diff changeset
285 start_point_ranges[r->start] = r;
kono
parents:
diff changeset
286 }
kono
parents:
diff changeset
287 }
kono
parents:
diff changeset
288 else
kono
parents:
diff changeset
289 {
kono
parents:
diff changeset
290 for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
291 r->start_next = &not_in_chain_mark;
kono
parents:
diff changeset
292 }
kono
parents:
diff changeset
293 }
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 /* Insert live ranges of pseudo REGNO into start chains if they are
kono
parents:
diff changeset
296 not there yet. */
kono
parents:
diff changeset
297 static void
kono
parents:
diff changeset
298 insert_in_live_range_start_chain (int regno)
kono
parents:
diff changeset
299 {
kono
parents:
diff changeset
300 lra_live_range_t r = lra_reg_info[regno].live_ranges;
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 if (r->start_next != &not_in_chain_mark)
kono
parents:
diff changeset
303 return;
kono
parents:
diff changeset
304 for (; r != NULL; r = r->next)
kono
parents:
diff changeset
305 {
kono
parents:
diff changeset
306 r->start_next = start_point_ranges[r->start];
kono
parents:
diff changeset
307 start_point_ranges[r->start] = r;
kono
parents:
diff changeset
308 }
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 /* Free START_POINT_RANGES. */
kono
parents:
diff changeset
312 static void
kono
parents:
diff changeset
313 finish_live_range_start_chains (void)
kono
parents:
diff changeset
314 {
kono
parents:
diff changeset
315 gcc_assert (start_point_ranges != NULL);
kono
parents:
diff changeset
316 free (start_point_ranges);
kono
parents:
diff changeset
317 start_point_ranges = NULL;
kono
parents:
diff changeset
318 }
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 /* Map: program point -> bitmap of all pseudos living at the point and
kono
parents:
diff changeset
321 assigned to hard registers. */
kono
parents:
diff changeset
322 static bitmap_head *live_hard_reg_pseudos;
kono
parents:
diff changeset
323 static bitmap_obstack live_hard_reg_pseudos_bitmap_obstack;
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 /* reg_renumber corresponding to pseudos marked in
kono
parents:
diff changeset
326 live_hard_reg_pseudos. reg_renumber might be not matched to
kono
parents:
diff changeset
327 live_hard_reg_pseudos but live_pseudos_reg_renumber always reflects
kono
parents:
diff changeset
328 live_hard_reg_pseudos. */
kono
parents:
diff changeset
329 static int *live_pseudos_reg_renumber;
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 /* Sparseset used to calculate living hard reg pseudos for some program
kono
parents:
diff changeset
332 point range. */
kono
parents:
diff changeset
333 static sparseset live_range_hard_reg_pseudos;
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 /* Sparseset used to calculate living reload/inheritance pseudos for
kono
parents:
diff changeset
336 some program point range. */
kono
parents:
diff changeset
337 static sparseset live_range_reload_inheritance_pseudos;
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 /* Allocate and initialize the data about living pseudos at program
kono
parents:
diff changeset
340 points. */
kono
parents:
diff changeset
341 static void
kono
parents:
diff changeset
342 init_lives (void)
kono
parents:
diff changeset
343 {
kono
parents:
diff changeset
344 int i, max_regno = max_reg_num ();
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 live_range_hard_reg_pseudos = sparseset_alloc (max_regno);
kono
parents:
diff changeset
347 live_range_reload_inheritance_pseudos = sparseset_alloc (max_regno);
kono
parents:
diff changeset
348 live_hard_reg_pseudos = XNEWVEC (bitmap_head, lra_live_max_point);
kono
parents:
diff changeset
349 bitmap_obstack_initialize (&live_hard_reg_pseudos_bitmap_obstack);
kono
parents:
diff changeset
350 for (i = 0; i < lra_live_max_point; i++)
kono
parents:
diff changeset
351 bitmap_initialize (&live_hard_reg_pseudos[i],
kono
parents:
diff changeset
352 &live_hard_reg_pseudos_bitmap_obstack);
kono
parents:
diff changeset
353 live_pseudos_reg_renumber = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
354 for (i = 0; i < max_regno; i++)
kono
parents:
diff changeset
355 live_pseudos_reg_renumber[i] = -1;
kono
parents:
diff changeset
356 }
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 /* Free the data about living pseudos at program points. */
kono
parents:
diff changeset
359 static void
kono
parents:
diff changeset
360 finish_lives (void)
kono
parents:
diff changeset
361 {
kono
parents:
diff changeset
362 sparseset_free (live_range_hard_reg_pseudos);
kono
parents:
diff changeset
363 sparseset_free (live_range_reload_inheritance_pseudos);
kono
parents:
diff changeset
364 free (live_hard_reg_pseudos);
kono
parents:
diff changeset
365 bitmap_obstack_release (&live_hard_reg_pseudos_bitmap_obstack);
kono
parents:
diff changeset
366 free (live_pseudos_reg_renumber);
kono
parents:
diff changeset
367 }
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 /* Update the LIVE_HARD_REG_PSEUDOS and LIVE_PSEUDOS_REG_RENUMBER
kono
parents:
diff changeset
370 entries for pseudo REGNO. Assume that the register has been
kono
parents:
diff changeset
371 spilled if FREE_P, otherwise assume that it has been assigned
kono
parents:
diff changeset
372 reg_renumber[REGNO] (if >= 0). We also insert the pseudo live
kono
parents:
diff changeset
373 ranges in the start chains when it is assumed to be assigned to a
kono
parents:
diff changeset
374 hard register because we use the chains of pseudos assigned to hard
kono
parents:
diff changeset
375 registers during allocation. */
kono
parents:
diff changeset
376 static void
kono
parents:
diff changeset
377 update_lives (int regno, bool free_p)
kono
parents:
diff changeset
378 {
kono
parents:
diff changeset
379 int p;
kono
parents:
diff changeset
380 lra_live_range_t r;
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 if (reg_renumber[regno] < 0)
kono
parents:
diff changeset
383 return;
kono
parents:
diff changeset
384 live_pseudos_reg_renumber[regno] = free_p ? -1 : reg_renumber[regno];
kono
parents:
diff changeset
385 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
386 {
kono
parents:
diff changeset
387 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
388 if (free_p)
kono
parents:
diff changeset
389 bitmap_clear_bit (&live_hard_reg_pseudos[p], regno);
kono
parents:
diff changeset
390 else
kono
parents:
diff changeset
391 {
kono
parents:
diff changeset
392 bitmap_set_bit (&live_hard_reg_pseudos[p], regno);
kono
parents:
diff changeset
393 insert_in_live_range_start_chain (regno);
kono
parents:
diff changeset
394 }
kono
parents:
diff changeset
395 }
kono
parents:
diff changeset
396 }
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 /* Sparseset used to calculate reload pseudos conflicting with a given
kono
parents:
diff changeset
399 pseudo when we are trying to find a hard register for the given
kono
parents:
diff changeset
400 pseudo. */
kono
parents:
diff changeset
401 static sparseset conflict_reload_and_inheritance_pseudos;
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 /* Map: program point -> bitmap of all reload and inheritance pseudos
kono
parents:
diff changeset
404 living at the point. */
kono
parents:
diff changeset
405 static bitmap_head *live_reload_and_inheritance_pseudos;
kono
parents:
diff changeset
406 static bitmap_obstack live_reload_and_inheritance_pseudos_bitmap_obstack;
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 /* Allocate and initialize data about living reload pseudos at any
kono
parents:
diff changeset
409 given program point. */
kono
parents:
diff changeset
410 static void
kono
parents:
diff changeset
411 init_live_reload_and_inheritance_pseudos (void)
kono
parents:
diff changeset
412 {
kono
parents:
diff changeset
413 int i, p, max_regno = max_reg_num ();
kono
parents:
diff changeset
414 lra_live_range_t r;
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 conflict_reload_and_inheritance_pseudos = sparseset_alloc (max_regno);
kono
parents:
diff changeset
417 live_reload_and_inheritance_pseudos = XNEWVEC (bitmap_head, lra_live_max_point);
kono
parents:
diff changeset
418 bitmap_obstack_initialize (&live_reload_and_inheritance_pseudos_bitmap_obstack);
kono
parents:
diff changeset
419 for (p = 0; p < lra_live_max_point; p++)
kono
parents:
diff changeset
420 bitmap_initialize (&live_reload_and_inheritance_pseudos[p],
kono
parents:
diff changeset
421 &live_reload_and_inheritance_pseudos_bitmap_obstack);
kono
parents:
diff changeset
422 for (i = lra_constraint_new_regno_start; i < max_regno; i++)
kono
parents:
diff changeset
423 {
kono
parents:
diff changeset
424 for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
425 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
426 bitmap_set_bit (&live_reload_and_inheritance_pseudos[p], i);
kono
parents:
diff changeset
427 }
kono
parents:
diff changeset
428 }
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 /* Finalize data about living reload pseudos at any given program
kono
parents:
diff changeset
431 point. */
kono
parents:
diff changeset
432 static void
kono
parents:
diff changeset
433 finish_live_reload_and_inheritance_pseudos (void)
kono
parents:
diff changeset
434 {
kono
parents:
diff changeset
435 sparseset_free (conflict_reload_and_inheritance_pseudos);
kono
parents:
diff changeset
436 free (live_reload_and_inheritance_pseudos);
kono
parents:
diff changeset
437 bitmap_obstack_release (&live_reload_and_inheritance_pseudos_bitmap_obstack);
kono
parents:
diff changeset
438 }
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 /* The value used to check that cost of given hard reg is really
kono
parents:
diff changeset
441 defined currently. */
kono
parents:
diff changeset
442 static int curr_hard_regno_costs_check = 0;
kono
parents:
diff changeset
443 /* Array used to check that cost of the corresponding hard reg (the
kono
parents:
diff changeset
444 array element index) is really defined currently. */
kono
parents:
diff changeset
445 static int hard_regno_costs_check[FIRST_PSEUDO_REGISTER];
kono
parents:
diff changeset
446 /* The current costs of allocation of hard regs. Defined only if the
kono
parents:
diff changeset
447 value of the corresponding element of the previous array is equal to
kono
parents:
diff changeset
448 CURR_HARD_REGNO_COSTS_CHECK. */
kono
parents:
diff changeset
449 static int hard_regno_costs[FIRST_PSEUDO_REGISTER];
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 /* Adjust cost of HARD_REGNO by INCR. Reset the cost first if it is
kono
parents:
diff changeset
452 not defined yet. */
kono
parents:
diff changeset
453 static inline void
kono
parents:
diff changeset
454 adjust_hard_regno_cost (int hard_regno, int incr)
kono
parents:
diff changeset
455 {
kono
parents:
diff changeset
456 if (hard_regno_costs_check[hard_regno] != curr_hard_regno_costs_check)
kono
parents:
diff changeset
457 hard_regno_costs[hard_regno] = 0;
kono
parents:
diff changeset
458 hard_regno_costs_check[hard_regno] = curr_hard_regno_costs_check;
kono
parents:
diff changeset
459 hard_regno_costs[hard_regno] += incr;
kono
parents:
diff changeset
460 }
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 /* Try to find a free hard register for pseudo REGNO. Return the
kono
parents:
diff changeset
463 hard register on success and set *COST to the cost of using
kono
parents:
diff changeset
464 that register. (If several registers have equal cost, the one with
kono
parents:
diff changeset
465 the highest priority wins.) Return -1 on failure.
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 If FIRST_P, return the first available hard reg ignoring other
kono
parents:
diff changeset
468 criteria, e.g. allocation cost. This approach results in less hard
kono
parents:
diff changeset
469 reg pool fragmentation and permit to allocate hard regs to reload
kono
parents:
diff changeset
470 pseudos in complicated situations where pseudo sizes are different.
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 If TRY_ONLY_HARD_REGNO >= 0, consider only that hard register,
kono
parents:
diff changeset
473 otherwise consider all hard registers in REGNO's class.
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 If REGNO_SET is not empty, only hard registers from the set are
kono
parents:
diff changeset
476 considered. */
kono
parents:
diff changeset
477 static int
kono
parents:
diff changeset
478 find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno,
kono
parents:
diff changeset
479 bool first_p, HARD_REG_SET regno_set)
kono
parents:
diff changeset
480 {
kono
parents:
diff changeset
481 HARD_REG_SET conflict_set;
kono
parents:
diff changeset
482 int best_cost = INT_MAX, best_priority = INT_MIN, best_usage = INT_MAX;
kono
parents:
diff changeset
483 lra_live_range_t r;
kono
parents:
diff changeset
484 int p, i, j, rclass_size, best_hard_regno, priority, hard_regno;
kono
parents:
diff changeset
485 int hr, conflict_hr, nregs;
kono
parents:
diff changeset
486 machine_mode biggest_mode;
kono
parents:
diff changeset
487 unsigned int k, conflict_regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
488 poly_int64 offset;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
489 int val, biggest_nregs, nregs_diff;
111
kono
parents:
diff changeset
490 enum reg_class rclass;
kono
parents:
diff changeset
491 bitmap_iterator bi;
kono
parents:
diff changeset
492 bool *rclass_intersect_p;
kono
parents:
diff changeset
493 HARD_REG_SET impossible_start_hard_regs, available_regs;
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 if (hard_reg_set_empty_p (regno_set))
kono
parents:
diff changeset
496 COPY_HARD_REG_SET (conflict_set, lra_no_alloc_regs);
kono
parents:
diff changeset
497 else
kono
parents:
diff changeset
498 {
kono
parents:
diff changeset
499 COMPL_HARD_REG_SET (conflict_set, regno_set);
kono
parents:
diff changeset
500 IOR_HARD_REG_SET (conflict_set, lra_no_alloc_regs);
kono
parents:
diff changeset
501 }
kono
parents:
diff changeset
502 rclass = regno_allocno_class_array[regno];
kono
parents:
diff changeset
503 rclass_intersect_p = ira_reg_classes_intersect_p[rclass];
kono
parents:
diff changeset
504 curr_hard_regno_costs_check++;
kono
parents:
diff changeset
505 sparseset_clear (conflict_reload_and_inheritance_pseudos);
kono
parents:
diff changeset
506 sparseset_clear (live_range_hard_reg_pseudos);
kono
parents:
diff changeset
507 IOR_HARD_REG_SET (conflict_set, lra_reg_info[regno].conflict_hard_regs);
kono
parents:
diff changeset
508 biggest_mode = lra_reg_info[regno].biggest_mode;
kono
parents:
diff changeset
509 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
510 {
kono
parents:
diff changeset
511 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[r->start], 0, k, bi)
kono
parents:
diff changeset
512 if (rclass_intersect_p[regno_allocno_class_array[k]])
kono
parents:
diff changeset
513 sparseset_set_bit (live_range_hard_reg_pseudos, k);
kono
parents:
diff changeset
514 EXECUTE_IF_SET_IN_BITMAP (&live_reload_and_inheritance_pseudos[r->start],
kono
parents:
diff changeset
515 0, k, bi)
kono
parents:
diff changeset
516 if (lra_reg_info[k].preferred_hard_regno1 >= 0
kono
parents:
diff changeset
517 && live_pseudos_reg_renumber[k] < 0
kono
parents:
diff changeset
518 && rclass_intersect_p[regno_allocno_class_array[k]])
kono
parents:
diff changeset
519 sparseset_set_bit (conflict_reload_and_inheritance_pseudos, k);
kono
parents:
diff changeset
520 for (p = r->start + 1; p <= r->finish; p++)
kono
parents:
diff changeset
521 {
kono
parents:
diff changeset
522 lra_live_range_t r2;
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
525 r2 != NULL;
kono
parents:
diff changeset
526 r2 = r2->start_next)
kono
parents:
diff changeset
527 {
kono
parents:
diff changeset
528 if (r2->regno >= lra_constraint_new_regno_start
kono
parents:
diff changeset
529 && lra_reg_info[r2->regno].preferred_hard_regno1 >= 0
kono
parents:
diff changeset
530 && live_pseudos_reg_renumber[r2->regno] < 0
kono
parents:
diff changeset
531 && rclass_intersect_p[regno_allocno_class_array[r2->regno]])
kono
parents:
diff changeset
532 sparseset_set_bit (conflict_reload_and_inheritance_pseudos,
kono
parents:
diff changeset
533 r2->regno);
kono
parents:
diff changeset
534 if (live_pseudos_reg_renumber[r2->regno] >= 0
kono
parents:
diff changeset
535 && rclass_intersect_p[regno_allocno_class_array[r2->regno]])
kono
parents:
diff changeset
536 sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
kono
parents:
diff changeset
537 }
kono
parents:
diff changeset
538 }
kono
parents:
diff changeset
539 }
kono
parents:
diff changeset
540 if ((hard_regno = lra_reg_info[regno].preferred_hard_regno1) >= 0)
kono
parents:
diff changeset
541 {
kono
parents:
diff changeset
542 adjust_hard_regno_cost
kono
parents:
diff changeset
543 (hard_regno, -lra_reg_info[regno].preferred_hard_regno_profit1);
kono
parents:
diff changeset
544 if ((hard_regno = lra_reg_info[regno].preferred_hard_regno2) >= 0)
kono
parents:
diff changeset
545 adjust_hard_regno_cost
kono
parents:
diff changeset
546 (hard_regno, -lra_reg_info[regno].preferred_hard_regno_profit2);
kono
parents:
diff changeset
547 }
kono
parents:
diff changeset
548 #ifdef STACK_REGS
kono
parents:
diff changeset
549 if (lra_reg_info[regno].no_stack_p)
kono
parents:
diff changeset
550 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
kono
parents:
diff changeset
551 SET_HARD_REG_BIT (conflict_set, i);
kono
parents:
diff changeset
552 #endif
kono
parents:
diff changeset
553 sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno);
kono
parents:
diff changeset
554 val = lra_reg_info[regno].val;
kono
parents:
diff changeset
555 offset = lra_reg_info[regno].offset;
kono
parents:
diff changeset
556 CLEAR_HARD_REG_SET (impossible_start_hard_regs);
kono
parents:
diff changeset
557 EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
kono
parents:
diff changeset
558 {
kono
parents:
diff changeset
559 conflict_hr = live_pseudos_reg_renumber[conflict_regno];
kono
parents:
diff changeset
560 if (lra_reg_val_equal_p (conflict_regno, val, offset))
kono
parents:
diff changeset
561 {
kono
parents:
diff changeset
562 conflict_hr = live_pseudos_reg_renumber[conflict_regno];
kono
parents:
diff changeset
563 nregs = hard_regno_nregs (conflict_hr,
kono
parents:
diff changeset
564 lra_reg_info[conflict_regno].biggest_mode);
kono
parents:
diff changeset
565 /* Remember about multi-register pseudos. For example, 2
kono
parents:
diff changeset
566 hard register pseudos can start on the same hard register
kono
parents:
diff changeset
567 but can not start on HR and HR+1/HR-1. */
kono
parents:
diff changeset
568 for (hr = conflict_hr + 1;
kono
parents:
diff changeset
569 hr < FIRST_PSEUDO_REGISTER && hr < conflict_hr + nregs;
kono
parents:
diff changeset
570 hr++)
kono
parents:
diff changeset
571 SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
kono
parents:
diff changeset
572 for (hr = conflict_hr - 1;
kono
parents:
diff changeset
573 hr >= 0 && (int) end_hard_regno (biggest_mode, hr) > conflict_hr;
kono
parents:
diff changeset
574 hr--)
kono
parents:
diff changeset
575 SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
kono
parents:
diff changeset
576 }
kono
parents:
diff changeset
577 else
kono
parents:
diff changeset
578 {
kono
parents:
diff changeset
579 machine_mode biggest_conflict_mode
kono
parents:
diff changeset
580 = lra_reg_info[conflict_regno].biggest_mode;
kono
parents:
diff changeset
581 int biggest_conflict_nregs
kono
parents:
diff changeset
582 = hard_regno_nregs (conflict_hr, biggest_conflict_mode);
kono
parents:
diff changeset
583
kono
parents:
diff changeset
584 nregs_diff
kono
parents:
diff changeset
585 = (biggest_conflict_nregs
kono
parents:
diff changeset
586 - hard_regno_nregs (conflict_hr,
kono
parents:
diff changeset
587 PSEUDO_REGNO_MODE (conflict_regno)));
kono
parents:
diff changeset
588 add_to_hard_reg_set (&conflict_set,
kono
parents:
diff changeset
589 biggest_conflict_mode,
kono
parents:
diff changeset
590 conflict_hr
kono
parents:
diff changeset
591 - (WORDS_BIG_ENDIAN ? nregs_diff : 0));
kono
parents:
diff changeset
592 if (hard_reg_set_subset_p (reg_class_contents[rclass],
kono
parents:
diff changeset
593 conflict_set))
kono
parents:
diff changeset
594 return -1;
kono
parents:
diff changeset
595 }
kono
parents:
diff changeset
596 }
kono
parents:
diff changeset
597 EXECUTE_IF_SET_IN_SPARSESET (conflict_reload_and_inheritance_pseudos,
kono
parents:
diff changeset
598 conflict_regno)
kono
parents:
diff changeset
599 if (!lra_reg_val_equal_p (conflict_regno, val, offset))
kono
parents:
diff changeset
600 {
kono
parents:
diff changeset
601 lra_assert (live_pseudos_reg_renumber[conflict_regno] < 0);
kono
parents:
diff changeset
602 if ((hard_regno
kono
parents:
diff changeset
603 = lra_reg_info[conflict_regno].preferred_hard_regno1) >= 0)
kono
parents:
diff changeset
604 {
kono
parents:
diff changeset
605 adjust_hard_regno_cost
kono
parents:
diff changeset
606 (hard_regno,
kono
parents:
diff changeset
607 lra_reg_info[conflict_regno].preferred_hard_regno_profit1);
kono
parents:
diff changeset
608 if ((hard_regno
kono
parents:
diff changeset
609 = lra_reg_info[conflict_regno].preferred_hard_regno2) >= 0)
kono
parents:
diff changeset
610 adjust_hard_regno_cost
kono
parents:
diff changeset
611 (hard_regno,
kono
parents:
diff changeset
612 lra_reg_info[conflict_regno].preferred_hard_regno_profit2);
kono
parents:
diff changeset
613 }
kono
parents:
diff changeset
614 }
kono
parents:
diff changeset
615 /* Make sure that all registers in a multi-word pseudo belong to the
kono
parents:
diff changeset
616 required class. */
kono
parents:
diff changeset
617 IOR_COMPL_HARD_REG_SET (conflict_set, reg_class_contents[rclass]);
kono
parents:
diff changeset
618 lra_assert (rclass != NO_REGS);
kono
parents:
diff changeset
619 rclass_size = ira_class_hard_regs_num[rclass];
kono
parents:
diff changeset
620 best_hard_regno = -1;
kono
parents:
diff changeset
621 hard_regno = ira_class_hard_regs[rclass][0];
kono
parents:
diff changeset
622 biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode);
kono
parents:
diff changeset
623 nregs_diff = (biggest_nregs
kono
parents:
diff changeset
624 - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno)));
kono
parents:
diff changeset
625 COPY_HARD_REG_SET (available_regs, reg_class_contents[rclass]);
kono
parents:
diff changeset
626 AND_COMPL_HARD_REG_SET (available_regs, lra_no_alloc_regs);
kono
parents:
diff changeset
627 for (i = 0; i < rclass_size; i++)
kono
parents:
diff changeset
628 {
kono
parents:
diff changeset
629 if (try_only_hard_regno >= 0)
kono
parents:
diff changeset
630 hard_regno = try_only_hard_regno;
kono
parents:
diff changeset
631 else
kono
parents:
diff changeset
632 hard_regno = ira_class_hard_regs[rclass][i];
kono
parents:
diff changeset
633 if (! overlaps_hard_reg_set_p (conflict_set,
kono
parents:
diff changeset
634 PSEUDO_REGNO_MODE (regno), hard_regno)
kono
parents:
diff changeset
635 && targetm.hard_regno_mode_ok (hard_regno,
kono
parents:
diff changeset
636 PSEUDO_REGNO_MODE (regno))
kono
parents:
diff changeset
637 /* We can not use prohibited_class_mode_regs for all classes
kono
parents:
diff changeset
638 because it is not defined for all classes. */
kono
parents:
diff changeset
639 && (ira_allocno_class_translate[rclass] != rclass
kono
parents:
diff changeset
640 || ! TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
kono
parents:
diff changeset
641 [rclass][PSEUDO_REGNO_MODE (regno)],
kono
parents:
diff changeset
642 hard_regno))
kono
parents:
diff changeset
643 && ! TEST_HARD_REG_BIT (impossible_start_hard_regs, hard_regno)
kono
parents:
diff changeset
644 && (nregs_diff == 0
kono
parents:
diff changeset
645 || (WORDS_BIG_ENDIAN
kono
parents:
diff changeset
646 ? (hard_regno - nregs_diff >= 0
kono
parents:
diff changeset
647 && TEST_HARD_REG_BIT (available_regs,
kono
parents:
diff changeset
648 hard_regno - nregs_diff))
kono
parents:
diff changeset
649 : TEST_HARD_REG_BIT (available_regs,
kono
parents:
diff changeset
650 hard_regno + nregs_diff))))
kono
parents:
diff changeset
651 {
kono
parents:
diff changeset
652 if (hard_regno_costs_check[hard_regno]
kono
parents:
diff changeset
653 != curr_hard_regno_costs_check)
kono
parents:
diff changeset
654 {
kono
parents:
diff changeset
655 hard_regno_costs_check[hard_regno] = curr_hard_regno_costs_check;
kono
parents:
diff changeset
656 hard_regno_costs[hard_regno] = 0;
kono
parents:
diff changeset
657 }
kono
parents:
diff changeset
658 for (j = 0;
kono
parents:
diff changeset
659 j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno));
kono
parents:
diff changeset
660 j++)
kono
parents:
diff changeset
661 if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j)
kono
parents:
diff changeset
662 && ! df_regs_ever_live_p (hard_regno + j))
kono
parents:
diff changeset
663 /* It needs save restore. */
kono
parents:
diff changeset
664 hard_regno_costs[hard_regno]
kono
parents:
diff changeset
665 += (2
kono
parents:
diff changeset
666 * REG_FREQ_FROM_BB (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
kono
parents:
diff changeset
667 + 1);
kono
parents:
diff changeset
668 priority = targetm.register_priority (hard_regno);
kono
parents:
diff changeset
669 if (best_hard_regno < 0 || hard_regno_costs[hard_regno] < best_cost
kono
parents:
diff changeset
670 || (hard_regno_costs[hard_regno] == best_cost
kono
parents:
diff changeset
671 && (priority > best_priority
kono
parents:
diff changeset
672 || (targetm.register_usage_leveling_p ()
kono
parents:
diff changeset
673 && priority == best_priority
kono
parents:
diff changeset
674 && best_usage > lra_hard_reg_usage[hard_regno]))))
kono
parents:
diff changeset
675 {
kono
parents:
diff changeset
676 best_hard_regno = hard_regno;
kono
parents:
diff changeset
677 best_cost = hard_regno_costs[hard_regno];
kono
parents:
diff changeset
678 best_priority = priority;
kono
parents:
diff changeset
679 best_usage = lra_hard_reg_usage[hard_regno];
kono
parents:
diff changeset
680 }
kono
parents:
diff changeset
681 }
kono
parents:
diff changeset
682 if (try_only_hard_regno >= 0 || (first_p && best_hard_regno >= 0))
kono
parents:
diff changeset
683 break;
kono
parents:
diff changeset
684 }
kono
parents:
diff changeset
685 if (best_hard_regno >= 0)
kono
parents:
diff changeset
686 *cost = best_cost - lra_reg_info[regno].freq;
kono
parents:
diff changeset
687 return best_hard_regno;
kono
parents:
diff changeset
688 }
kono
parents:
diff changeset
689
kono
parents:
diff changeset
690 /* A wrapper for find_hard_regno_for_1 (see comments for that function
kono
parents:
diff changeset
691 description). This function tries to find a hard register for
kono
parents:
diff changeset
692 preferred class first if it is worth. */
kono
parents:
diff changeset
693 static int
kono
parents:
diff changeset
694 find_hard_regno_for (int regno, int *cost, int try_only_hard_regno, bool first_p)
kono
parents:
diff changeset
695 {
kono
parents:
diff changeset
696 int hard_regno;
kono
parents:
diff changeset
697 HARD_REG_SET regno_set;
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 /* Only original pseudos can have a different preferred class. */
kono
parents:
diff changeset
700 if (try_only_hard_regno < 0 && regno < lra_new_regno_start)
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 enum reg_class pref_class = reg_preferred_class (regno);
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 if (regno_allocno_class_array[regno] != pref_class)
kono
parents:
diff changeset
705 {
kono
parents:
diff changeset
706 hard_regno = find_hard_regno_for_1 (regno, cost, -1, first_p,
kono
parents:
diff changeset
707 reg_class_contents[pref_class]);
kono
parents:
diff changeset
708 if (hard_regno >= 0)
kono
parents:
diff changeset
709 return hard_regno;
kono
parents:
diff changeset
710 }
kono
parents:
diff changeset
711 }
kono
parents:
diff changeset
712 CLEAR_HARD_REG_SET (regno_set);
kono
parents:
diff changeset
713 return find_hard_regno_for_1 (regno, cost, try_only_hard_regno, first_p,
kono
parents:
diff changeset
714 regno_set);
kono
parents:
diff changeset
715 }
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 /* Current value used for checking elements in
kono
parents:
diff changeset
718 update_hard_regno_preference_check. */
kono
parents:
diff changeset
719 static int curr_update_hard_regno_preference_check;
kono
parents:
diff changeset
720 /* If an element value is equal to the above variable value, then the
kono
parents:
diff changeset
721 corresponding regno has been processed for preference
kono
parents:
diff changeset
722 propagation. */
kono
parents:
diff changeset
723 static int *update_hard_regno_preference_check;
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 /* Update the preference for using HARD_REGNO for pseudos that are
kono
parents:
diff changeset
726 connected directly or indirectly with REGNO. Apply divisor DIV
kono
parents:
diff changeset
727 to any preference adjustments.
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 The more indirectly a pseudo is connected, the smaller its effect
kono
parents:
diff changeset
730 should be. We therefore increase DIV on each "hop". */
kono
parents:
diff changeset
731 static void
kono
parents:
diff changeset
732 update_hard_regno_preference (int regno, int hard_regno, int div)
kono
parents:
diff changeset
733 {
kono
parents:
diff changeset
734 int another_regno, cost;
kono
parents:
diff changeset
735 lra_copy_t cp, next_cp;
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 /* Search depth 5 seems to be enough. */
kono
parents:
diff changeset
738 if (div > (1 << 5))
kono
parents:
diff changeset
739 return;
kono
parents:
diff changeset
740 for (cp = lra_reg_info[regno].copies; cp != NULL; cp = next_cp)
kono
parents:
diff changeset
741 {
kono
parents:
diff changeset
742 if (cp->regno1 == regno)
kono
parents:
diff changeset
743 {
kono
parents:
diff changeset
744 next_cp = cp->regno1_next;
kono
parents:
diff changeset
745 another_regno = cp->regno2;
kono
parents:
diff changeset
746 }
kono
parents:
diff changeset
747 else if (cp->regno2 == regno)
kono
parents:
diff changeset
748 {
kono
parents:
diff changeset
749 next_cp = cp->regno2_next;
kono
parents:
diff changeset
750 another_regno = cp->regno1;
kono
parents:
diff changeset
751 }
kono
parents:
diff changeset
752 else
kono
parents:
diff changeset
753 gcc_unreachable ();
kono
parents:
diff changeset
754 if (reg_renumber[another_regno] < 0
kono
parents:
diff changeset
755 && (update_hard_regno_preference_check[another_regno]
kono
parents:
diff changeset
756 != curr_update_hard_regno_preference_check))
kono
parents:
diff changeset
757 {
kono
parents:
diff changeset
758 update_hard_regno_preference_check[another_regno]
kono
parents:
diff changeset
759 = curr_update_hard_regno_preference_check;
kono
parents:
diff changeset
760 cost = cp->freq < div ? 1 : cp->freq / div;
kono
parents:
diff changeset
761 lra_setup_reload_pseudo_preferenced_hard_reg
kono
parents:
diff changeset
762 (another_regno, hard_regno, cost);
kono
parents:
diff changeset
763 update_hard_regno_preference (another_regno, hard_regno, div * 2);
kono
parents:
diff changeset
764 }
kono
parents:
diff changeset
765 }
kono
parents:
diff changeset
766 }
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 /* Return prefix title for pseudo REGNO. */
kono
parents:
diff changeset
769 static const char *
kono
parents:
diff changeset
770 pseudo_prefix_title (int regno)
kono
parents:
diff changeset
771 {
kono
parents:
diff changeset
772 return
kono
parents:
diff changeset
773 (regno < lra_constraint_new_regno_start ? ""
kono
parents:
diff changeset
774 : bitmap_bit_p (&lra_inheritance_pseudos, regno) ? "inheritance "
kono
parents:
diff changeset
775 : bitmap_bit_p (&lra_split_regs, regno) ? "split "
kono
parents:
diff changeset
776 : bitmap_bit_p (&lra_optional_reload_pseudos, regno) ? "optional reload "
kono
parents:
diff changeset
777 : bitmap_bit_p (&lra_subreg_reload_pseudos, regno) ? "subreg reload "
kono
parents:
diff changeset
778 : "reload ");
kono
parents:
diff changeset
779 }
kono
parents:
diff changeset
780
kono
parents:
diff changeset
781 /* Update REG_RENUMBER and other pseudo preferences by assignment of
kono
parents:
diff changeset
782 HARD_REGNO to pseudo REGNO and print about it if PRINT_P. */
kono
parents:
diff changeset
783 void
kono
parents:
diff changeset
784 lra_setup_reg_renumber (int regno, int hard_regno, bool print_p)
kono
parents:
diff changeset
785 {
kono
parents:
diff changeset
786 int i, hr;
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 /* We can not just reassign hard register. */
kono
parents:
diff changeset
789 lra_assert (hard_regno < 0 || reg_renumber[regno] < 0);
kono
parents:
diff changeset
790 if ((hr = hard_regno) < 0)
kono
parents:
diff changeset
791 hr = reg_renumber[regno];
kono
parents:
diff changeset
792 reg_renumber[regno] = hard_regno;
kono
parents:
diff changeset
793 lra_assert (hr >= 0);
kono
parents:
diff changeset
794 for (i = 0; i < hard_regno_nregs (hr, PSEUDO_REGNO_MODE (regno)); i++)
kono
parents:
diff changeset
795 if (hard_regno < 0)
kono
parents:
diff changeset
796 lra_hard_reg_usage[hr + i] -= lra_reg_info[regno].freq;
kono
parents:
diff changeset
797 else
kono
parents:
diff changeset
798 lra_hard_reg_usage[hr + i] += lra_reg_info[regno].freq;
kono
parents:
diff changeset
799 if (print_p && lra_dump_file != NULL)
kono
parents:
diff changeset
800 fprintf (lra_dump_file, " Assign %d to %sr%d (freq=%d)\n",
kono
parents:
diff changeset
801 reg_renumber[regno], pseudo_prefix_title (regno),
kono
parents:
diff changeset
802 regno, lra_reg_info[regno].freq);
kono
parents:
diff changeset
803 if (hard_regno >= 0)
kono
parents:
diff changeset
804 {
kono
parents:
diff changeset
805 curr_update_hard_regno_preference_check++;
kono
parents:
diff changeset
806 update_hard_regno_preference (regno, hard_regno, 1);
kono
parents:
diff changeset
807 }
kono
parents:
diff changeset
808 }
kono
parents:
diff changeset
809
kono
parents:
diff changeset
810 /* Pseudos which occur in insns containing a particular pseudo. */
kono
parents:
diff changeset
811 static bitmap_head insn_conflict_pseudos;
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 /* Bitmaps used to contain spill pseudos for given pseudo hard regno
kono
parents:
diff changeset
814 and best spill pseudos for given pseudo (and best hard regno). */
kono
parents:
diff changeset
815 static bitmap_head spill_pseudos_bitmap, best_spill_pseudos_bitmap;
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817 /* Current pseudo check for validity of elements in
kono
parents:
diff changeset
818 TRY_HARD_REG_PSEUDOS. */
kono
parents:
diff changeset
819 static int curr_pseudo_check;
kono
parents:
diff changeset
820 /* Array used for validity of elements in TRY_HARD_REG_PSEUDOS. */
kono
parents:
diff changeset
821 static int try_hard_reg_pseudos_check[FIRST_PSEUDO_REGISTER];
kono
parents:
diff changeset
822 /* Pseudos who hold given hard register at the considered points. */
kono
parents:
diff changeset
823 static bitmap_head try_hard_reg_pseudos[FIRST_PSEUDO_REGISTER];
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 /* Set up try_hard_reg_pseudos for given program point P and class
kono
parents:
diff changeset
826 RCLASS. Those are pseudos living at P and assigned to a hard
kono
parents:
diff changeset
827 register of RCLASS. In other words, those are pseudos which can be
kono
parents:
diff changeset
828 spilled to assign a hard register of RCLASS to a pseudo living at
kono
parents:
diff changeset
829 P. */
kono
parents:
diff changeset
830 static void
kono
parents:
diff changeset
831 setup_try_hard_regno_pseudos (int p, enum reg_class rclass)
kono
parents:
diff changeset
832 {
kono
parents:
diff changeset
833 int i, hard_regno;
kono
parents:
diff changeset
834 machine_mode mode;
kono
parents:
diff changeset
835 unsigned int spill_regno;
kono
parents:
diff changeset
836 bitmap_iterator bi;
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 /* Find what pseudos could be spilled. */
kono
parents:
diff changeset
839 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[p], 0, spill_regno, bi)
kono
parents:
diff changeset
840 {
kono
parents:
diff changeset
841 mode = PSEUDO_REGNO_MODE (spill_regno);
kono
parents:
diff changeset
842 hard_regno = live_pseudos_reg_renumber[spill_regno];
kono
parents:
diff changeset
843 if (overlaps_hard_reg_set_p (reg_class_contents[rclass],
kono
parents:
diff changeset
844 mode, hard_regno))
kono
parents:
diff changeset
845 {
kono
parents:
diff changeset
846 for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
kono
parents:
diff changeset
847 {
kono
parents:
diff changeset
848 if (try_hard_reg_pseudos_check[hard_regno + i]
kono
parents:
diff changeset
849 != curr_pseudo_check)
kono
parents:
diff changeset
850 {
kono
parents:
diff changeset
851 try_hard_reg_pseudos_check[hard_regno + i]
kono
parents:
diff changeset
852 = curr_pseudo_check;
kono
parents:
diff changeset
853 bitmap_clear (&try_hard_reg_pseudos[hard_regno + i]);
kono
parents:
diff changeset
854 }
kono
parents:
diff changeset
855 bitmap_set_bit (&try_hard_reg_pseudos[hard_regno + i],
kono
parents:
diff changeset
856 spill_regno);
kono
parents:
diff changeset
857 }
kono
parents:
diff changeset
858 }
kono
parents:
diff changeset
859 }
kono
parents:
diff changeset
860 }
kono
parents:
diff changeset
861
kono
parents:
diff changeset
862 /* Assign temporarily HARD_REGNO to pseudo REGNO. Temporary
kono
parents:
diff changeset
863 assignment means that we might undo the data change. */
kono
parents:
diff changeset
864 static void
kono
parents:
diff changeset
865 assign_temporarily (int regno, int hard_regno)
kono
parents:
diff changeset
866 {
kono
parents:
diff changeset
867 int p;
kono
parents:
diff changeset
868 lra_live_range_t r;
kono
parents:
diff changeset
869
kono
parents:
diff changeset
870 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
871 {
kono
parents:
diff changeset
872 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
873 if (hard_regno < 0)
kono
parents:
diff changeset
874 bitmap_clear_bit (&live_hard_reg_pseudos[p], regno);
kono
parents:
diff changeset
875 else
kono
parents:
diff changeset
876 {
kono
parents:
diff changeset
877 bitmap_set_bit (&live_hard_reg_pseudos[p], regno);
kono
parents:
diff changeset
878 insert_in_live_range_start_chain (regno);
kono
parents:
diff changeset
879 }
kono
parents:
diff changeset
880 }
kono
parents:
diff changeset
881 live_pseudos_reg_renumber[regno] = hard_regno;
kono
parents:
diff changeset
882 }
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 /* Return true iff there is a reason why pseudo SPILL_REGNO should not
kono
parents:
diff changeset
885 be spilled. */
kono
parents:
diff changeset
886 static bool
kono
parents:
diff changeset
887 must_not_spill_p (unsigned spill_regno)
kono
parents:
diff changeset
888 {
kono
parents:
diff changeset
889 if ((pic_offset_table_rtx != NULL
kono
parents:
diff changeset
890 && spill_regno == REGNO (pic_offset_table_rtx))
kono
parents:
diff changeset
891 || ((int) spill_regno >= lra_constraint_new_regno_start
kono
parents:
diff changeset
892 && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
kono
parents:
diff changeset
893 && ! bitmap_bit_p (&lra_split_regs, spill_regno)
kono
parents:
diff changeset
894 && ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno)
kono
parents:
diff changeset
895 && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)))
kono
parents:
diff changeset
896 return true;
kono
parents:
diff changeset
897 /* A reload pseudo that requires a singleton register class should
kono
parents:
diff changeset
898 not be spilled.
kono
parents:
diff changeset
899 FIXME: this mitigates the issue on certain i386 patterns, but
kono
parents:
diff changeset
900 does not solve the general case where existing reloads fully
kono
parents:
diff changeset
901 cover a limited register class. */
kono
parents:
diff changeset
902 if (!bitmap_bit_p (&non_reload_pseudos, spill_regno)
kono
parents:
diff changeset
903 && reg_class_size [reg_preferred_class (spill_regno)] == 1
kono
parents:
diff changeset
904 && reg_alternate_class (spill_regno) == NO_REGS)
kono
parents:
diff changeset
905 return true;
kono
parents:
diff changeset
906 return false;
kono
parents:
diff changeset
907 }
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 /* Array used for sorting reload pseudos for subsequent allocation
kono
parents:
diff changeset
910 after spilling some pseudo. */
kono
parents:
diff changeset
911 static int *sorted_reload_pseudos;
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 /* Spill some pseudos for a reload pseudo REGNO and return hard
kono
parents:
diff changeset
914 register which should be used for pseudo after spilling. The
kono
parents:
diff changeset
915 function adds spilled pseudos to SPILLED_PSEUDO_BITMAP. When we
kono
parents:
diff changeset
916 choose hard register (and pseudos occupying the hard registers and
kono
parents:
diff changeset
917 to be spilled), we take into account not only how REGNO will
kono
parents:
diff changeset
918 benefit from the spills but also how other reload pseudos not yet
kono
parents:
diff changeset
919 assigned to hard registers benefit from the spills too. In very
kono
parents:
diff changeset
920 rare cases, the function can fail and return -1.
kono
parents:
diff changeset
921
kono
parents:
diff changeset
922 If FIRST_P, return the first available hard reg ignoring other
kono
parents:
diff changeset
923 criteria, e.g. allocation cost and cost of spilling non-reload
kono
parents:
diff changeset
924 pseudos. This approach results in less hard reg pool fragmentation
kono
parents:
diff changeset
925 and permit to allocate hard regs to reload pseudos in complicated
kono
parents:
diff changeset
926 situations where pseudo sizes are different. */
kono
parents:
diff changeset
927 static int
kono
parents:
diff changeset
928 spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
kono
parents:
diff changeset
929 {
kono
parents:
diff changeset
930 int i, j, n, p, hard_regno, best_hard_regno, cost, best_cost, rclass_size;
kono
parents:
diff changeset
931 int reload_hard_regno, reload_cost;
kono
parents:
diff changeset
932 bool static_p, best_static_p;
kono
parents:
diff changeset
933 machine_mode mode;
kono
parents:
diff changeset
934 enum reg_class rclass;
kono
parents:
diff changeset
935 unsigned int spill_regno, reload_regno, uid;
kono
parents:
diff changeset
936 int insn_pseudos_num, best_insn_pseudos_num;
kono
parents:
diff changeset
937 int bad_spills_num, smallest_bad_spills_num;
kono
parents:
diff changeset
938 lra_live_range_t r;
kono
parents:
diff changeset
939 bitmap_iterator bi;
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 rclass = regno_allocno_class_array[regno];
kono
parents:
diff changeset
942 lra_assert (reg_renumber[regno] < 0 && rclass != NO_REGS);
kono
parents:
diff changeset
943 bitmap_clear (&insn_conflict_pseudos);
kono
parents:
diff changeset
944 bitmap_clear (&best_spill_pseudos_bitmap);
kono
parents:
diff changeset
945 EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
kono
parents:
diff changeset
946 {
kono
parents:
diff changeset
947 struct lra_insn_reg *ir;
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 for (ir = lra_get_insn_regs (uid); ir != NULL; ir = ir->next)
kono
parents:
diff changeset
950 if (ir->regno >= FIRST_PSEUDO_REGISTER)
kono
parents:
diff changeset
951 bitmap_set_bit (&insn_conflict_pseudos, ir->regno);
kono
parents:
diff changeset
952 }
kono
parents:
diff changeset
953 best_hard_regno = -1;
kono
parents:
diff changeset
954 best_cost = INT_MAX;
kono
parents:
diff changeset
955 best_static_p = TRUE;
kono
parents:
diff changeset
956 best_insn_pseudos_num = INT_MAX;
kono
parents:
diff changeset
957 smallest_bad_spills_num = INT_MAX;
kono
parents:
diff changeset
958 rclass_size = ira_class_hard_regs_num[rclass];
kono
parents:
diff changeset
959 mode = PSEUDO_REGNO_MODE (regno);
kono
parents:
diff changeset
960 /* Invalidate try_hard_reg_pseudos elements. */
kono
parents:
diff changeset
961 curr_pseudo_check++;
kono
parents:
diff changeset
962 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
963 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
964 setup_try_hard_regno_pseudos (p, rclass);
kono
parents:
diff changeset
965 for (i = 0; i < rclass_size; i++)
kono
parents:
diff changeset
966 {
kono
parents:
diff changeset
967 hard_regno = ira_class_hard_regs[rclass][i];
kono
parents:
diff changeset
968 bitmap_clear (&spill_pseudos_bitmap);
kono
parents:
diff changeset
969 for (j = hard_regno_nregs (hard_regno, mode) - 1; j >= 0; j--)
kono
parents:
diff changeset
970 {
kono
parents:
diff changeset
971 if (try_hard_reg_pseudos_check[hard_regno + j] != curr_pseudo_check)
kono
parents:
diff changeset
972 continue;
kono
parents:
diff changeset
973 lra_assert (!bitmap_empty_p (&try_hard_reg_pseudos[hard_regno + j]));
kono
parents:
diff changeset
974 bitmap_ior_into (&spill_pseudos_bitmap,
kono
parents:
diff changeset
975 &try_hard_reg_pseudos[hard_regno + j]);
kono
parents:
diff changeset
976 }
kono
parents:
diff changeset
977 /* Spill pseudos. */
kono
parents:
diff changeset
978 static_p = false;
kono
parents:
diff changeset
979 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
980 if (must_not_spill_p (spill_regno))
kono
parents:
diff changeset
981 goto fail;
kono
parents:
diff changeset
982 else if (non_spilled_static_chain_regno_p (spill_regno))
kono
parents:
diff changeset
983 static_p = true;
kono
parents:
diff changeset
984 insn_pseudos_num = 0;
kono
parents:
diff changeset
985 bad_spills_num = 0;
kono
parents:
diff changeset
986 if (lra_dump_file != NULL)
kono
parents:
diff changeset
987 fprintf (lra_dump_file, " Trying %d:", hard_regno);
kono
parents:
diff changeset
988 sparseset_clear (live_range_reload_inheritance_pseudos);
kono
parents:
diff changeset
989 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
990 {
kono
parents:
diff changeset
991 if (bitmap_bit_p (&insn_conflict_pseudos, spill_regno))
kono
parents:
diff changeset
992 insn_pseudos_num++;
kono
parents:
diff changeset
993 if (spill_regno >= (unsigned int) lra_bad_spill_regno_start)
kono
parents:
diff changeset
994 bad_spills_num++;
kono
parents:
diff changeset
995 for (r = lra_reg_info[spill_regno].live_ranges;
kono
parents:
diff changeset
996 r != NULL;
kono
parents:
diff changeset
997 r = r->next)
kono
parents:
diff changeset
998 {
kono
parents:
diff changeset
999 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
1000 {
kono
parents:
diff changeset
1001 lra_live_range_t r2;
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
1004 r2 != NULL;
kono
parents:
diff changeset
1005 r2 = r2->start_next)
kono
parents:
diff changeset
1006 if (r2->regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1007 sparseset_set_bit (live_range_reload_inheritance_pseudos,
kono
parents:
diff changeset
1008 r2->regno);
kono
parents:
diff changeset
1009 }
kono
parents:
diff changeset
1010 }
kono
parents:
diff changeset
1011 }
kono
parents:
diff changeset
1012 n = 0;
kono
parents:
diff changeset
1013 if (sparseset_cardinality (live_range_reload_inheritance_pseudos)
kono
parents:
diff changeset
1014 <= (unsigned)LRA_MAX_CONSIDERED_RELOAD_PSEUDOS)
kono
parents:
diff changeset
1015 EXECUTE_IF_SET_IN_SPARSESET (live_range_reload_inheritance_pseudos,
kono
parents:
diff changeset
1016 reload_regno)
kono
parents:
diff changeset
1017 if ((int) reload_regno != regno
kono
parents:
diff changeset
1018 && (ira_reg_classes_intersect_p
kono
parents:
diff changeset
1019 [rclass][regno_allocno_class_array[reload_regno]])
kono
parents:
diff changeset
1020 && live_pseudos_reg_renumber[reload_regno] < 0
kono
parents:
diff changeset
1021 && find_hard_regno_for (reload_regno, &cost, -1, first_p) < 0)
kono
parents:
diff changeset
1022 sorted_reload_pseudos[n++] = reload_regno;
kono
parents:
diff changeset
1023 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1024 {
kono
parents:
diff changeset
1025 update_lives (spill_regno, true);
kono
parents:
diff changeset
1026 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1027 fprintf (lra_dump_file, " spill %d(freq=%d)",
kono
parents:
diff changeset
1028 spill_regno, lra_reg_info[spill_regno].freq);
kono
parents:
diff changeset
1029 }
kono
parents:
diff changeset
1030 hard_regno = find_hard_regno_for (regno, &cost, -1, first_p);
kono
parents:
diff changeset
1031 if (hard_regno >= 0)
kono
parents:
diff changeset
1032 {
kono
parents:
diff changeset
1033 assign_temporarily (regno, hard_regno);
kono
parents:
diff changeset
1034 qsort (sorted_reload_pseudos, n, sizeof (int),
kono
parents:
diff changeset
1035 reload_pseudo_compare_func);
kono
parents:
diff changeset
1036 for (j = 0; j < n; j++)
kono
parents:
diff changeset
1037 {
kono
parents:
diff changeset
1038 reload_regno = sorted_reload_pseudos[j];
kono
parents:
diff changeset
1039 lra_assert (live_pseudos_reg_renumber[reload_regno] < 0);
kono
parents:
diff changeset
1040 if ((reload_hard_regno
kono
parents:
diff changeset
1041 = find_hard_regno_for (reload_regno,
kono
parents:
diff changeset
1042 &reload_cost, -1, first_p)) >= 0)
kono
parents:
diff changeset
1043 {
kono
parents:
diff changeset
1044 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1045 fprintf (lra_dump_file, " assign %d(cost=%d)",
kono
parents:
diff changeset
1046 reload_regno, reload_cost);
kono
parents:
diff changeset
1047 assign_temporarily (reload_regno, reload_hard_regno);
kono
parents:
diff changeset
1048 cost += reload_cost;
kono
parents:
diff changeset
1049 }
kono
parents:
diff changeset
1050 }
kono
parents:
diff changeset
1051 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1052 {
kono
parents:
diff changeset
1053 rtx_insn_list *x;
kono
parents:
diff changeset
1054
kono
parents:
diff changeset
1055 cost += lra_reg_info[spill_regno].freq;
kono
parents:
diff changeset
1056 if (ira_reg_equiv[spill_regno].memory != NULL
kono
parents:
diff changeset
1057 || ira_reg_equiv[spill_regno].constant != NULL)
kono
parents:
diff changeset
1058 for (x = ira_reg_equiv[spill_regno].init_insns;
kono
parents:
diff changeset
1059 x != NULL;
kono
parents:
diff changeset
1060 x = x->next ())
kono
parents:
diff changeset
1061 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (x->insn ()));
kono
parents:
diff changeset
1062 }
kono
parents:
diff changeset
1063 /* Avoid spilling static chain pointer pseudo when non-local
kono
parents:
diff changeset
1064 goto is used. */
kono
parents:
diff changeset
1065 if ((! static_p && best_static_p)
kono
parents:
diff changeset
1066 || (static_p == best_static_p
kono
parents:
diff changeset
1067 && (best_insn_pseudos_num > insn_pseudos_num
kono
parents:
diff changeset
1068 || (best_insn_pseudos_num == insn_pseudos_num
kono
parents:
diff changeset
1069 && (bad_spills_num < smallest_bad_spills_num
kono
parents:
diff changeset
1070 || (bad_spills_num == smallest_bad_spills_num
kono
parents:
diff changeset
1071 && best_cost > cost))))))
kono
parents:
diff changeset
1072 {
kono
parents:
diff changeset
1073 best_insn_pseudos_num = insn_pseudos_num;
kono
parents:
diff changeset
1074 smallest_bad_spills_num = bad_spills_num;
kono
parents:
diff changeset
1075 best_static_p = static_p;
kono
parents:
diff changeset
1076 best_cost = cost;
kono
parents:
diff changeset
1077 best_hard_regno = hard_regno;
kono
parents:
diff changeset
1078 bitmap_copy (&best_spill_pseudos_bitmap, &spill_pseudos_bitmap);
kono
parents:
diff changeset
1079 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1080 fprintf (lra_dump_file,
kono
parents:
diff changeset
1081 " Now best %d(cost=%d, bad_spills=%d, insn_pseudos=%d)\n",
kono
parents:
diff changeset
1082 hard_regno, cost, bad_spills_num, insn_pseudos_num);
kono
parents:
diff changeset
1083 }
kono
parents:
diff changeset
1084 assign_temporarily (regno, -1);
kono
parents:
diff changeset
1085 for (j = 0; j < n; j++)
kono
parents:
diff changeset
1086 {
kono
parents:
diff changeset
1087 reload_regno = sorted_reload_pseudos[j];
kono
parents:
diff changeset
1088 if (live_pseudos_reg_renumber[reload_regno] >= 0)
kono
parents:
diff changeset
1089 assign_temporarily (reload_regno, -1);
kono
parents:
diff changeset
1090 }
kono
parents:
diff changeset
1091 }
kono
parents:
diff changeset
1092 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1093 fprintf (lra_dump_file, "\n");
kono
parents:
diff changeset
1094 /* Restore the live hard reg pseudo info for spilled pseudos. */
kono
parents:
diff changeset
1095 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1096 update_lives (spill_regno, false);
kono
parents:
diff changeset
1097 fail:
kono
parents:
diff changeset
1098 ;
kono
parents:
diff changeset
1099 }
kono
parents:
diff changeset
1100 /* Spill: */
kono
parents:
diff changeset
1101 EXECUTE_IF_SET_IN_BITMAP (&best_spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1102 {
kono
parents:
diff changeset
1103 if ((int) spill_regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1104 former_reload_pseudo_spill_p = true;
kono
parents:
diff changeset
1105 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1106 fprintf (lra_dump_file, " Spill %sr%d(hr=%d, freq=%d) for r%d\n",
kono
parents:
diff changeset
1107 pseudo_prefix_title (spill_regno),
kono
parents:
diff changeset
1108 spill_regno, reg_renumber[spill_regno],
kono
parents:
diff changeset
1109 lra_reg_info[spill_regno].freq, regno);
kono
parents:
diff changeset
1110 update_lives (spill_regno, true);
kono
parents:
diff changeset
1111 lra_setup_reg_renumber (spill_regno, -1, false);
kono
parents:
diff changeset
1112 }
kono
parents:
diff changeset
1113 bitmap_ior_into (spilled_pseudo_bitmap, &best_spill_pseudos_bitmap);
kono
parents:
diff changeset
1114 return best_hard_regno;
kono
parents:
diff changeset
1115 }
kono
parents:
diff changeset
1116
kono
parents:
diff changeset
1117 /* Assign HARD_REGNO to REGNO. */
kono
parents:
diff changeset
1118 static void
kono
parents:
diff changeset
1119 assign_hard_regno (int hard_regno, int regno)
kono
parents:
diff changeset
1120 {
kono
parents:
diff changeset
1121 int i;
kono
parents:
diff changeset
1122
kono
parents:
diff changeset
1123 lra_assert (hard_regno >= 0);
kono
parents:
diff changeset
1124 lra_setup_reg_renumber (regno, hard_regno, true);
kono
parents:
diff changeset
1125 update_lives (regno, false);
kono
parents:
diff changeset
1126 for (i = 0;
kono
parents:
diff changeset
1127 i < hard_regno_nregs (hard_regno, lra_reg_info[regno].biggest_mode);
kono
parents:
diff changeset
1128 i++)
kono
parents:
diff changeset
1129 df_set_regs_ever_live (hard_regno + i, true);
kono
parents:
diff changeset
1130 }
kono
parents:
diff changeset
1131
kono
parents:
diff changeset
1132 /* Array used for sorting different pseudos. */
kono
parents:
diff changeset
1133 static int *sorted_pseudos;
kono
parents:
diff changeset
1134
kono
parents:
diff changeset
1135 /* The constraints pass is allowed to create equivalences between
kono
parents:
diff changeset
1136 pseudos that make the current allocation "incorrect" (in the sense
kono
parents:
diff changeset
1137 that pseudos are assigned to hard registers from their own conflict
kono
parents:
diff changeset
1138 sets). The global variable lra_risky_transformations_p says
kono
parents:
diff changeset
1139 whether this might have happened.
kono
parents:
diff changeset
1140
kono
parents:
diff changeset
1141 Process pseudos assigned to hard registers (less frequently used
kono
parents:
diff changeset
1142 first), spill if a conflict is found, and mark the spilled pseudos
kono
parents:
diff changeset
1143 in SPILLED_PSEUDO_BITMAP. Set up LIVE_HARD_REG_PSEUDOS from
kono
parents:
diff changeset
1144 pseudos, assigned to hard registers. */
kono
parents:
diff changeset
1145 static void
kono
parents:
diff changeset
1146 setup_live_pseudos_and_spill_after_risky_transforms (bitmap
kono
parents:
diff changeset
1147 spilled_pseudo_bitmap)
kono
parents:
diff changeset
1148 {
kono
parents:
diff changeset
1149 int p, i, j, n, regno, hard_regno;
kono
parents:
diff changeset
1150 unsigned int k, conflict_regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1151 poly_int64 offset;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1152 int val;
111
kono
parents:
diff changeset
1153 HARD_REG_SET conflict_set;
kono
parents:
diff changeset
1154 machine_mode mode;
kono
parents:
diff changeset
1155 lra_live_range_t r;
kono
parents:
diff changeset
1156 bitmap_iterator bi;
kono
parents:
diff changeset
1157 int max_regno = max_reg_num ();
kono
parents:
diff changeset
1158
kono
parents:
diff changeset
1159 if (! lra_risky_transformations_p)
kono
parents:
diff changeset
1160 {
kono
parents:
diff changeset
1161 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1162 if (reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
kono
parents:
diff changeset
1163 update_lives (i, false);
kono
parents:
diff changeset
1164 return;
kono
parents:
diff changeset
1165 }
kono
parents:
diff changeset
1166 for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1167 if ((pic_offset_table_rtx == NULL_RTX
kono
parents:
diff changeset
1168 || i != (int) REGNO (pic_offset_table_rtx))
kono
parents:
diff changeset
1169 && reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
kono
parents:
diff changeset
1170 sorted_pseudos[n++] = i;
kono
parents:
diff changeset
1171 qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
kono
parents:
diff changeset
1172 if (pic_offset_table_rtx != NULL_RTX
kono
parents:
diff changeset
1173 && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
kono
parents:
diff changeset
1174 && reg_renumber[regno] >= 0 && lra_reg_info[regno].nrefs > 0)
kono
parents:
diff changeset
1175 sorted_pseudos[n++] = regno;
kono
parents:
diff changeset
1176 for (i = n - 1; i >= 0; i--)
kono
parents:
diff changeset
1177 {
kono
parents:
diff changeset
1178 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1179 hard_regno = reg_renumber[regno];
kono
parents:
diff changeset
1180 lra_assert (hard_regno >= 0);
kono
parents:
diff changeset
1181 mode = lra_reg_info[regno].biggest_mode;
kono
parents:
diff changeset
1182 sparseset_clear (live_range_hard_reg_pseudos);
kono
parents:
diff changeset
1183 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
1184 {
kono
parents:
diff changeset
1185 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[r->start], 0, k, bi)
kono
parents:
diff changeset
1186 sparseset_set_bit (live_range_hard_reg_pseudos, k);
kono
parents:
diff changeset
1187 for (p = r->start + 1; p <= r->finish; p++)
kono
parents:
diff changeset
1188 {
kono
parents:
diff changeset
1189 lra_live_range_t r2;
kono
parents:
diff changeset
1190
kono
parents:
diff changeset
1191 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
1192 r2 != NULL;
kono
parents:
diff changeset
1193 r2 = r2->start_next)
kono
parents:
diff changeset
1194 if (live_pseudos_reg_renumber[r2->regno] >= 0)
kono
parents:
diff changeset
1195 sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
kono
parents:
diff changeset
1196 }
kono
parents:
diff changeset
1197 }
kono
parents:
diff changeset
1198 COPY_HARD_REG_SET (conflict_set, lra_no_alloc_regs);
kono
parents:
diff changeset
1199 IOR_HARD_REG_SET (conflict_set, lra_reg_info[regno].conflict_hard_regs);
kono
parents:
diff changeset
1200 val = lra_reg_info[regno].val;
kono
parents:
diff changeset
1201 offset = lra_reg_info[regno].offset;
kono
parents:
diff changeset
1202 EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
kono
parents:
diff changeset
1203 if (!lra_reg_val_equal_p (conflict_regno, val, offset)
kono
parents:
diff changeset
1204 /* If it is multi-register pseudos they should start on
kono
parents:
diff changeset
1205 the same hard register. */
kono
parents:
diff changeset
1206 || hard_regno != reg_renumber[conflict_regno])
kono
parents:
diff changeset
1207 {
kono
parents:
diff changeset
1208 int conflict_hard_regno = reg_renumber[conflict_regno];
kono
parents:
diff changeset
1209 machine_mode biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
kono
parents:
diff changeset
1210 int biggest_nregs = hard_regno_nregs (conflict_hard_regno,
kono
parents:
diff changeset
1211 biggest_mode);
kono
parents:
diff changeset
1212 int nregs_diff
kono
parents:
diff changeset
1213 = (biggest_nregs
kono
parents:
diff changeset
1214 - hard_regno_nregs (conflict_hard_regno,
kono
parents:
diff changeset
1215 PSEUDO_REGNO_MODE (conflict_regno)));
kono
parents:
diff changeset
1216 add_to_hard_reg_set (&conflict_set,
kono
parents:
diff changeset
1217 biggest_mode,
kono
parents:
diff changeset
1218 conflict_hard_regno
kono
parents:
diff changeset
1219 - (WORDS_BIG_ENDIAN ? nregs_diff : 0));
kono
parents:
diff changeset
1220 }
kono
parents:
diff changeset
1221 if (! overlaps_hard_reg_set_p (conflict_set, mode, hard_regno))
kono
parents:
diff changeset
1222 {
kono
parents:
diff changeset
1223 update_lives (regno, false);
kono
parents:
diff changeset
1224 continue;
kono
parents:
diff changeset
1225 }
kono
parents:
diff changeset
1226 bitmap_set_bit (spilled_pseudo_bitmap, regno);
kono
parents:
diff changeset
1227 for (j = 0;
kono
parents:
diff changeset
1228 j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno));
kono
parents:
diff changeset
1229 j++)
kono
parents:
diff changeset
1230 lra_hard_reg_usage[hard_regno + j] -= lra_reg_info[regno].freq;
kono
parents:
diff changeset
1231 reg_renumber[regno] = -1;
kono
parents:
diff changeset
1232 if (regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1233 former_reload_pseudo_spill_p = true;
kono
parents:
diff changeset
1234 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1235 fprintf (lra_dump_file, " Spill r%d after risky transformations\n",
kono
parents:
diff changeset
1236 regno);
kono
parents:
diff changeset
1237 }
kono
parents:
diff changeset
1238 }
kono
parents:
diff changeset
1239
kono
parents:
diff changeset
1240 /* Improve allocation by assigning the same hard regno of inheritance
kono
parents:
diff changeset
1241 pseudos to the connected pseudos. We need this because inheritance
kono
parents:
diff changeset
1242 pseudos are allocated after reload pseudos in the thread and when
kono
parents:
diff changeset
1243 we assign a hard register to a reload pseudo we don't know yet that
kono
parents:
diff changeset
1244 the connected inheritance pseudos can get the same hard register.
kono
parents:
diff changeset
1245 Add pseudos with changed allocation to bitmap CHANGED_PSEUDOS. */
kono
parents:
diff changeset
1246 static void
kono
parents:
diff changeset
1247 improve_inheritance (bitmap changed_pseudos)
kono
parents:
diff changeset
1248 {
kono
parents:
diff changeset
1249 unsigned int k;
kono
parents:
diff changeset
1250 int regno, another_regno, hard_regno, another_hard_regno, cost, i, n;
kono
parents:
diff changeset
1251 lra_copy_t cp, next_cp;
kono
parents:
diff changeset
1252 bitmap_iterator bi;
kono
parents:
diff changeset
1253
kono
parents:
diff changeset
1254 if (lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES)
kono
parents:
diff changeset
1255 return;
kono
parents:
diff changeset
1256 n = 0;
kono
parents:
diff changeset
1257 EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, k, bi)
kono
parents:
diff changeset
1258 if (reg_renumber[k] >= 0 && lra_reg_info[k].nrefs != 0)
kono
parents:
diff changeset
1259 sorted_pseudos[n++] = k;
kono
parents:
diff changeset
1260 qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
kono
parents:
diff changeset
1261 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1262 {
kono
parents:
diff changeset
1263 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1264 hard_regno = reg_renumber[regno];
kono
parents:
diff changeset
1265 lra_assert (hard_regno >= 0);
kono
parents:
diff changeset
1266 for (cp = lra_reg_info[regno].copies; cp != NULL; cp = next_cp)
kono
parents:
diff changeset
1267 {
kono
parents:
diff changeset
1268 if (cp->regno1 == regno)
kono
parents:
diff changeset
1269 {
kono
parents:
diff changeset
1270 next_cp = cp->regno1_next;
kono
parents:
diff changeset
1271 another_regno = cp->regno2;
kono
parents:
diff changeset
1272 }
kono
parents:
diff changeset
1273 else if (cp->regno2 == regno)
kono
parents:
diff changeset
1274 {
kono
parents:
diff changeset
1275 next_cp = cp->regno2_next;
kono
parents:
diff changeset
1276 another_regno = cp->regno1;
kono
parents:
diff changeset
1277 }
kono
parents:
diff changeset
1278 else
kono
parents:
diff changeset
1279 gcc_unreachable ();
kono
parents:
diff changeset
1280 /* Don't change reload pseudo allocation. It might have
kono
parents:
diff changeset
1281 this allocation for a purpose and changing it can result
kono
parents:
diff changeset
1282 in LRA cycling. */
kono
parents:
diff changeset
1283 if ((another_regno < lra_constraint_new_regno_start
kono
parents:
diff changeset
1284 || bitmap_bit_p (&lra_inheritance_pseudos, another_regno))
kono
parents:
diff changeset
1285 && (another_hard_regno = reg_renumber[another_regno]) >= 0
kono
parents:
diff changeset
1286 && another_hard_regno != hard_regno)
kono
parents:
diff changeset
1287 {
kono
parents:
diff changeset
1288 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1289 fprintf
kono
parents:
diff changeset
1290 (lra_dump_file,
kono
parents:
diff changeset
1291 " Improving inheritance for %d(%d) and %d(%d)...\n",
kono
parents:
diff changeset
1292 regno, hard_regno, another_regno, another_hard_regno);
kono
parents:
diff changeset
1293 update_lives (another_regno, true);
kono
parents:
diff changeset
1294 lra_setup_reg_renumber (another_regno, -1, false);
kono
parents:
diff changeset
1295 if (hard_regno == find_hard_regno_for (another_regno, &cost,
kono
parents:
diff changeset
1296 hard_regno, false))
kono
parents:
diff changeset
1297 assign_hard_regno (hard_regno, another_regno);
kono
parents:
diff changeset
1298 else
kono
parents:
diff changeset
1299 assign_hard_regno (another_hard_regno, another_regno);
kono
parents:
diff changeset
1300 bitmap_set_bit (changed_pseudos, another_regno);
kono
parents:
diff changeset
1301 }
kono
parents:
diff changeset
1302 }
kono
parents:
diff changeset
1303 }
kono
parents:
diff changeset
1304 }
kono
parents:
diff changeset
1305
kono
parents:
diff changeset
1306
kono
parents:
diff changeset
1307 /* Bitmap finally containing all pseudos spilled on this assignment
kono
parents:
diff changeset
1308 pass. */
kono
parents:
diff changeset
1309 static bitmap_head all_spilled_pseudos;
kono
parents:
diff changeset
1310 /* All pseudos whose allocation was changed. */
kono
parents:
diff changeset
1311 static bitmap_head changed_pseudo_bitmap;
kono
parents:
diff changeset
1312
kono
parents:
diff changeset
1313
kono
parents:
diff changeset
1314 /* Add to LIVE_RANGE_HARD_REG_PSEUDOS all pseudos conflicting with
kono
parents:
diff changeset
1315 REGNO and whose hard regs can be assigned to REGNO. */
kono
parents:
diff changeset
1316 static void
kono
parents:
diff changeset
1317 find_all_spills_for (int regno)
kono
parents:
diff changeset
1318 {
kono
parents:
diff changeset
1319 int p;
kono
parents:
diff changeset
1320 lra_live_range_t r;
kono
parents:
diff changeset
1321 unsigned int k;
kono
parents:
diff changeset
1322 bitmap_iterator bi;
kono
parents:
diff changeset
1323 enum reg_class rclass;
kono
parents:
diff changeset
1324 bool *rclass_intersect_p;
kono
parents:
diff changeset
1325
kono
parents:
diff changeset
1326 rclass = regno_allocno_class_array[regno];
kono
parents:
diff changeset
1327 rclass_intersect_p = ira_reg_classes_intersect_p[rclass];
kono
parents:
diff changeset
1328 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
1329 {
kono
parents:
diff changeset
1330 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[r->start], 0, k, bi)
kono
parents:
diff changeset
1331 if (rclass_intersect_p[regno_allocno_class_array[k]])
kono
parents:
diff changeset
1332 sparseset_set_bit (live_range_hard_reg_pseudos, k);
kono
parents:
diff changeset
1333 for (p = r->start + 1; p <= r->finish; p++)
kono
parents:
diff changeset
1334 {
kono
parents:
diff changeset
1335 lra_live_range_t r2;
kono
parents:
diff changeset
1336
kono
parents:
diff changeset
1337 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
1338 r2 != NULL;
kono
parents:
diff changeset
1339 r2 = r2->start_next)
kono
parents:
diff changeset
1340 {
kono
parents:
diff changeset
1341 if (live_pseudos_reg_renumber[r2->regno] >= 0
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1342 && ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1343 && rclass_intersect_p[regno_allocno_class_array[r2->regno]]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1344 && ((int) r2->regno < lra_constraint_new_regno_start
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1345 || bitmap_bit_p (&lra_inheritance_pseudos, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1346 || bitmap_bit_p (&lra_split_regs, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1347 || bitmap_bit_p (&lra_optional_reload_pseudos, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1348 /* There is no sense to consider another reload
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1349 pseudo if it has the same class. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1350 || regno_allocno_class_array[r2->regno] != rclass))
111
kono
parents:
diff changeset
1351 sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
kono
parents:
diff changeset
1352 }
kono
parents:
diff changeset
1353 }
kono
parents:
diff changeset
1354 }
kono
parents:
diff changeset
1355 }
kono
parents:
diff changeset
1356
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1357 /* Assign hard registers to reload pseudos and other pseudos. Return
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1358 true if we was not able to assign hard registers to all reload
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1359 pseudos. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1360 static bool
111
kono
parents:
diff changeset
1361 assign_by_spills (void)
kono
parents:
diff changeset
1362 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1363 int i, n, nfails, iter, regno, regno2, hard_regno, cost;
111
kono
parents:
diff changeset
1364 rtx restore_rtx;
kono
parents:
diff changeset
1365 bitmap_head changed_insns, do_not_assign_nonreload_pseudos;
kono
parents:
diff changeset
1366 unsigned int u, conflict_regno;
kono
parents:
diff changeset
1367 bitmap_iterator bi;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1368 bool reload_p, fails_p = false;
111
kono
parents:
diff changeset
1369 int max_regno = max_reg_num ();
kono
parents:
diff changeset
1370
kono
parents:
diff changeset
1371 for (n = 0, i = lra_constraint_new_regno_start; i < max_regno; i++)
kono
parents:
diff changeset
1372 if (reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
kono
parents:
diff changeset
1373 && regno_allocno_class_array[i] != NO_REGS)
kono
parents:
diff changeset
1374 sorted_pseudos[n++] = i;
kono
parents:
diff changeset
1375 bitmap_initialize (&insn_conflict_pseudos, &reg_obstack);
kono
parents:
diff changeset
1376 bitmap_initialize (&spill_pseudos_bitmap, &reg_obstack);
kono
parents:
diff changeset
1377 bitmap_initialize (&best_spill_pseudos_bitmap, &reg_obstack);
kono
parents:
diff changeset
1378 update_hard_regno_preference_check = XCNEWVEC (int, max_regno);
kono
parents:
diff changeset
1379 curr_update_hard_regno_preference_check = 0;
kono
parents:
diff changeset
1380 memset (try_hard_reg_pseudos_check, 0, sizeof (try_hard_reg_pseudos_check));
kono
parents:
diff changeset
1381 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
kono
parents:
diff changeset
1382 bitmap_initialize (&try_hard_reg_pseudos[i], &reg_obstack);
kono
parents:
diff changeset
1383 curr_pseudo_check = 0;
kono
parents:
diff changeset
1384 bitmap_initialize (&changed_insns, &reg_obstack);
kono
parents:
diff changeset
1385 bitmap_initialize (&non_reload_pseudos, &reg_obstack);
kono
parents:
diff changeset
1386 bitmap_ior (&non_reload_pseudos, &lra_inheritance_pseudos, &lra_split_regs);
kono
parents:
diff changeset
1387 bitmap_ior_into (&non_reload_pseudos, &lra_subreg_reload_pseudos);
kono
parents:
diff changeset
1388 bitmap_ior_into (&non_reload_pseudos, &lra_optional_reload_pseudos);
kono
parents:
diff changeset
1389 for (iter = 0; iter <= 1; iter++)
kono
parents:
diff changeset
1390 {
kono
parents:
diff changeset
1391 qsort (sorted_pseudos, n, sizeof (int), reload_pseudo_compare_func);
kono
parents:
diff changeset
1392 nfails = 0;
kono
parents:
diff changeset
1393 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1394 {
kono
parents:
diff changeset
1395 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1396 if (reg_renumber[regno] >= 0)
kono
parents:
diff changeset
1397 continue;
kono
parents:
diff changeset
1398 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1399 fprintf (lra_dump_file, " Assigning to %d "
kono
parents:
diff changeset
1400 "(cl=%s, orig=%d, freq=%d, tfirst=%d, tfreq=%d)...\n",
kono
parents:
diff changeset
1401 regno, reg_class_names[regno_allocno_class_array[regno]],
kono
parents:
diff changeset
1402 ORIGINAL_REGNO (regno_reg_rtx[regno]),
kono
parents:
diff changeset
1403 lra_reg_info[regno].freq, regno_assign_info[regno].first,
kono
parents:
diff changeset
1404 regno_assign_info[regno_assign_info[regno].first].freq);
kono
parents:
diff changeset
1405 hard_regno = find_hard_regno_for (regno, &cost, -1, iter == 1);
kono
parents:
diff changeset
1406 reload_p = ! bitmap_bit_p (&non_reload_pseudos, regno);
kono
parents:
diff changeset
1407 if (hard_regno < 0 && reload_p)
kono
parents:
diff changeset
1408 hard_regno = spill_for (regno, &all_spilled_pseudos, iter == 1);
kono
parents:
diff changeset
1409 if (hard_regno < 0)
kono
parents:
diff changeset
1410 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1411 if (reload_p) {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1412 /* Put unassigned reload pseudo first in the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1413 array. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1414 regno2 = sorted_pseudos[nfails];
111
kono
parents:
diff changeset
1415 sorted_pseudos[nfails++] = regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1416 sorted_pseudos[i] = regno2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1417 }
111
kono
parents:
diff changeset
1418 }
kono
parents:
diff changeset
1419 else
kono
parents:
diff changeset
1420 {
kono
parents:
diff changeset
1421 /* This register might have been spilled by the previous
kono
parents:
diff changeset
1422 pass. Indicate that it is no longer spilled. */
kono
parents:
diff changeset
1423 bitmap_clear_bit (&all_spilled_pseudos, regno);
kono
parents:
diff changeset
1424 assign_hard_regno (hard_regno, regno);
kono
parents:
diff changeset
1425 if (! reload_p)
kono
parents:
diff changeset
1426 /* As non-reload pseudo assignment is changed we
kono
parents:
diff changeset
1427 should reconsider insns referring for the
kono
parents:
diff changeset
1428 pseudo. */
kono
parents:
diff changeset
1429 bitmap_set_bit (&changed_pseudo_bitmap, regno);
kono
parents:
diff changeset
1430 }
kono
parents:
diff changeset
1431 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1432 if (nfails == 0 || iter > 0)
111
kono
parents:
diff changeset
1433 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1434 fails_p = nfails != 0;
111
kono
parents:
diff changeset
1435 break;
kono
parents:
diff changeset
1436 }
kono
parents:
diff changeset
1437 /* This is a very rare event. We can not assign a hard register
kono
parents:
diff changeset
1438 to reload pseudo because the hard register was assigned to
kono
parents:
diff changeset
1439 another reload pseudo on a previous assignment pass. For x86
kono
parents:
diff changeset
1440 example, on the 1st pass we assigned CX (although another
kono
parents:
diff changeset
1441 hard register could be used for this) to reload pseudo in an
kono
parents:
diff changeset
1442 insn, on the 2nd pass we need CX (and only this) hard
kono
parents:
diff changeset
1443 register for a new reload pseudo in the same insn. Another
kono
parents:
diff changeset
1444 possible situation may occur in assigning to multi-regs
kono
parents:
diff changeset
1445 reload pseudos when hard regs pool is too fragmented even
kono
parents:
diff changeset
1446 after spilling non-reload pseudos.
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 We should do something radical here to succeed. Here we
kono
parents:
diff changeset
1449 spill *all* conflicting pseudos and reassign them. */
kono
parents:
diff changeset
1450 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1451 fprintf (lra_dump_file, " 2nd iter for reload pseudo assignments:\n");
kono
parents:
diff changeset
1452 sparseset_clear (live_range_hard_reg_pseudos);
kono
parents:
diff changeset
1453 for (i = 0; i < nfails; i++)
kono
parents:
diff changeset
1454 {
kono
parents:
diff changeset
1455 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1456 fprintf (lra_dump_file, " Reload r%d assignment failure\n",
kono
parents:
diff changeset
1457 sorted_pseudos[i]);
kono
parents:
diff changeset
1458 find_all_spills_for (sorted_pseudos[i]);
kono
parents:
diff changeset
1459 }
kono
parents:
diff changeset
1460 EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
kono
parents:
diff changeset
1461 {
kono
parents:
diff changeset
1462 if ((int) conflict_regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1463 {
kono
parents:
diff changeset
1464 sorted_pseudos[nfails++] = conflict_regno;
kono
parents:
diff changeset
1465 former_reload_pseudo_spill_p = true;
kono
parents:
diff changeset
1466 }
kono
parents:
diff changeset
1467 else
kono
parents:
diff changeset
1468 /* It is better to do reloads before spilling as after the
kono
parents:
diff changeset
1469 spill-subpass we will reload memory instead of pseudos
kono
parents:
diff changeset
1470 and this will make reusing reload pseudos more
kono
parents:
diff changeset
1471 complicated. Going directly to the spill pass in such
kono
parents:
diff changeset
1472 case might result in worse code performance or even LRA
kono
parents:
diff changeset
1473 cycling if we have few registers. */
kono
parents:
diff changeset
1474 bitmap_set_bit (&all_spilled_pseudos, conflict_regno);
kono
parents:
diff changeset
1475 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1476 fprintf (lra_dump_file, " Spill %s r%d(hr=%d, freq=%d)\n",
kono
parents:
diff changeset
1477 pseudo_prefix_title (conflict_regno), conflict_regno,
kono
parents:
diff changeset
1478 reg_renumber[conflict_regno],
kono
parents:
diff changeset
1479 lra_reg_info[conflict_regno].freq);
kono
parents:
diff changeset
1480 update_lives (conflict_regno, true);
kono
parents:
diff changeset
1481 lra_setup_reg_renumber (conflict_regno, -1, false);
kono
parents:
diff changeset
1482 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1483 if (n < nfails)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1484 n = nfails;
111
kono
parents:
diff changeset
1485 }
kono
parents:
diff changeset
1486 improve_inheritance (&changed_pseudo_bitmap);
kono
parents:
diff changeset
1487 bitmap_clear (&non_reload_pseudos);
kono
parents:
diff changeset
1488 bitmap_clear (&changed_insns);
kono
parents:
diff changeset
1489 if (! lra_simple_p)
kono
parents:
diff changeset
1490 {
kono
parents:
diff changeset
1491 /* We should not assign to original pseudos of inheritance
kono
parents:
diff changeset
1492 pseudos or split pseudos if any its inheritance pseudo did
kono
parents:
diff changeset
1493 not get hard register or any its split pseudo was not split
kono
parents:
diff changeset
1494 because undo inheritance/split pass will extend live range of
kono
parents:
diff changeset
1495 such inheritance or split pseudos. */
kono
parents:
diff changeset
1496 bitmap_initialize (&do_not_assign_nonreload_pseudos, &reg_obstack);
kono
parents:
diff changeset
1497 EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, u, bi)
kono
parents:
diff changeset
1498 if ((restore_rtx = lra_reg_info[u].restore_rtx) != NULL_RTX
kono
parents:
diff changeset
1499 && REG_P (restore_rtx)
kono
parents:
diff changeset
1500 && reg_renumber[u] < 0
kono
parents:
diff changeset
1501 && bitmap_bit_p (&lra_inheritance_pseudos, u))
kono
parents:
diff changeset
1502 bitmap_set_bit (&do_not_assign_nonreload_pseudos, REGNO (restore_rtx));
kono
parents:
diff changeset
1503 EXECUTE_IF_SET_IN_BITMAP (&lra_split_regs, 0, u, bi)
kono
parents:
diff changeset
1504 if ((restore_rtx = lra_reg_info[u].restore_rtx) != NULL_RTX
kono
parents:
diff changeset
1505 && reg_renumber[u] >= 0)
kono
parents:
diff changeset
1506 {
kono
parents:
diff changeset
1507 lra_assert (REG_P (restore_rtx));
kono
parents:
diff changeset
1508 bitmap_set_bit (&do_not_assign_nonreload_pseudos, REGNO (restore_rtx));
kono
parents:
diff changeset
1509 }
kono
parents:
diff changeset
1510 for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1511 if (((i < lra_constraint_new_regno_start
kono
parents:
diff changeset
1512 && ! bitmap_bit_p (&do_not_assign_nonreload_pseudos, i))
kono
parents:
diff changeset
1513 || (bitmap_bit_p (&lra_inheritance_pseudos, i)
kono
parents:
diff changeset
1514 && lra_reg_info[i].restore_rtx != NULL_RTX)
kono
parents:
diff changeset
1515 || (bitmap_bit_p (&lra_split_regs, i)
kono
parents:
diff changeset
1516 && lra_reg_info[i].restore_rtx != NULL_RTX)
kono
parents:
diff changeset
1517 || bitmap_bit_p (&lra_subreg_reload_pseudos, i)
kono
parents:
diff changeset
1518 || bitmap_bit_p (&lra_optional_reload_pseudos, i))
kono
parents:
diff changeset
1519 && reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
kono
parents:
diff changeset
1520 && regno_allocno_class_array[i] != NO_REGS)
kono
parents:
diff changeset
1521 sorted_pseudos[n++] = i;
kono
parents:
diff changeset
1522 bitmap_clear (&do_not_assign_nonreload_pseudos);
kono
parents:
diff changeset
1523 if (n != 0 && lra_dump_file != NULL)
kono
parents:
diff changeset
1524 fprintf (lra_dump_file, " Reassigning non-reload pseudos\n");
kono
parents:
diff changeset
1525 qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
kono
parents:
diff changeset
1526 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1527 {
kono
parents:
diff changeset
1528 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1529 hard_regno = find_hard_regno_for (regno, &cost, -1, false);
kono
parents:
diff changeset
1530 if (hard_regno >= 0)
kono
parents:
diff changeset
1531 {
kono
parents:
diff changeset
1532 assign_hard_regno (hard_regno, regno);
kono
parents:
diff changeset
1533 /* We change allocation for non-reload pseudo on this
kono
parents:
diff changeset
1534 iteration -- mark the pseudo for invalidation of used
kono
parents:
diff changeset
1535 alternatives of insns containing the pseudo. */
kono
parents:
diff changeset
1536 bitmap_set_bit (&changed_pseudo_bitmap, regno);
kono
parents:
diff changeset
1537 }
kono
parents:
diff changeset
1538 else
kono
parents:
diff changeset
1539 {
kono
parents:
diff changeset
1540 enum reg_class rclass = lra_get_allocno_class (regno);
kono
parents:
diff changeset
1541 enum reg_class spill_class;
kono
parents:
diff changeset
1542
kono
parents:
diff changeset
1543 if (targetm.spill_class == NULL
kono
parents:
diff changeset
1544 || lra_reg_info[regno].restore_rtx == NULL_RTX
kono
parents:
diff changeset
1545 || ! bitmap_bit_p (&lra_inheritance_pseudos, regno)
kono
parents:
diff changeset
1546 || (spill_class
kono
parents:
diff changeset
1547 = ((enum reg_class)
kono
parents:
diff changeset
1548 targetm.spill_class
kono
parents:
diff changeset
1549 ((reg_class_t) rclass,
kono
parents:
diff changeset
1550 PSEUDO_REGNO_MODE (regno)))) == NO_REGS)
kono
parents:
diff changeset
1551 continue;
kono
parents:
diff changeset
1552 regno_allocno_class_array[regno] = spill_class;
kono
parents:
diff changeset
1553 hard_regno = find_hard_regno_for (regno, &cost, -1, false);
kono
parents:
diff changeset
1554 if (hard_regno < 0)
kono
parents:
diff changeset
1555 regno_allocno_class_array[regno] = rclass;
kono
parents:
diff changeset
1556 else
kono
parents:
diff changeset
1557 {
kono
parents:
diff changeset
1558 setup_reg_classes
kono
parents:
diff changeset
1559 (regno, spill_class, spill_class, spill_class);
kono
parents:
diff changeset
1560 assign_hard_regno (hard_regno, regno);
kono
parents:
diff changeset
1561 bitmap_set_bit (&changed_pseudo_bitmap, regno);
kono
parents:
diff changeset
1562 }
kono
parents:
diff changeset
1563 }
kono
parents:
diff changeset
1564 }
kono
parents:
diff changeset
1565 }
kono
parents:
diff changeset
1566 free (update_hard_regno_preference_check);
kono
parents:
diff changeset
1567 bitmap_clear (&best_spill_pseudos_bitmap);
kono
parents:
diff changeset
1568 bitmap_clear (&spill_pseudos_bitmap);
kono
parents:
diff changeset
1569 bitmap_clear (&insn_conflict_pseudos);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1570 return fails_p;
111
kono
parents:
diff changeset
1571 }
kono
parents:
diff changeset
1572
kono
parents:
diff changeset
1573 /* Entry function to assign hard registers to new reload pseudos
kono
parents:
diff changeset
1574 starting with LRA_CONSTRAINT_NEW_REGNO_START (by possible spilling
kono
parents:
diff changeset
1575 of old pseudos) and possibly to the old pseudos. The function adds
kono
parents:
diff changeset
1576 what insns to process for the next constraint pass. Those are all
kono
parents:
diff changeset
1577 insns who contains non-reload and non-inheritance pseudos with
kono
parents:
diff changeset
1578 changed allocation.
kono
parents:
diff changeset
1579
kono
parents:
diff changeset
1580 Return true if we did not spill any non-reload and non-inheritance
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1581 pseudos. Set up FAILS_P if we failed to assign hard registers to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1582 all reload pseudos. */
111
kono
parents:
diff changeset
1583 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1584 lra_assign (bool &fails_p)
111
kono
parents:
diff changeset
1585 {
kono
parents:
diff changeset
1586 int i;
kono
parents:
diff changeset
1587 unsigned int u;
kono
parents:
diff changeset
1588 bitmap_iterator bi;
kono
parents:
diff changeset
1589 bitmap_head insns_to_process;
kono
parents:
diff changeset
1590 bool no_spills_p;
kono
parents:
diff changeset
1591 int max_regno = max_reg_num ();
kono
parents:
diff changeset
1592
kono
parents:
diff changeset
1593 timevar_push (TV_LRA_ASSIGN);
kono
parents:
diff changeset
1594 lra_assignment_iter++;
kono
parents:
diff changeset
1595 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1596 fprintf (lra_dump_file, "\n********** Assignment #%d: **********\n\n",
kono
parents:
diff changeset
1597 lra_assignment_iter);
kono
parents:
diff changeset
1598 init_lives ();
kono
parents:
diff changeset
1599 sorted_pseudos = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
1600 sorted_reload_pseudos = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
1601 regno_allocno_class_array = XNEWVEC (enum reg_class, max_regno);
kono
parents:
diff changeset
1602 regno_live_length = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
1603 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1604 {
kono
parents:
diff changeset
1605 int l;
kono
parents:
diff changeset
1606 lra_live_range_t r;
kono
parents:
diff changeset
1607
kono
parents:
diff changeset
1608 regno_allocno_class_array[i] = lra_get_allocno_class (i);
kono
parents:
diff changeset
1609 for (l = 0, r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
1610 l += r->finish - r->start + 1;
kono
parents:
diff changeset
1611 regno_live_length[i] = l;
kono
parents:
diff changeset
1612 }
kono
parents:
diff changeset
1613 former_reload_pseudo_spill_p = false;
kono
parents:
diff changeset
1614 init_regno_assign_info ();
kono
parents:
diff changeset
1615 bitmap_initialize (&all_spilled_pseudos, &reg_obstack);
kono
parents:
diff changeset
1616 create_live_range_start_chains ();
kono
parents:
diff changeset
1617 setup_live_pseudos_and_spill_after_risky_transforms (&all_spilled_pseudos);
kono
parents:
diff changeset
1618 if (flag_checking && !flag_ipa_ra)
kono
parents:
diff changeset
1619 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1620 if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
kono
parents:
diff changeset
1621 && lra_reg_info[i].call_p
kono
parents:
diff changeset
1622 && overlaps_hard_reg_set_p (call_used_reg_set,
kono
parents:
diff changeset
1623 PSEUDO_REGNO_MODE (i), reg_renumber[i]))
kono
parents:
diff changeset
1624 gcc_unreachable ();
kono
parents:
diff changeset
1625 /* Setup insns to process on the next constraint pass. */
kono
parents:
diff changeset
1626 bitmap_initialize (&changed_pseudo_bitmap, &reg_obstack);
kono
parents:
diff changeset
1627 init_live_reload_and_inheritance_pseudos ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1628 fails_p = assign_by_spills ();
111
kono
parents:
diff changeset
1629 finish_live_reload_and_inheritance_pseudos ();
kono
parents:
diff changeset
1630 bitmap_ior_into (&changed_pseudo_bitmap, &all_spilled_pseudos);
kono
parents:
diff changeset
1631 no_spills_p = true;
kono
parents:
diff changeset
1632 EXECUTE_IF_SET_IN_BITMAP (&all_spilled_pseudos, 0, u, bi)
kono
parents:
diff changeset
1633 /* We ignore spilled pseudos created on last inheritance pass
kono
parents:
diff changeset
1634 because they will be removed. */
kono
parents:
diff changeset
1635 if (lra_reg_info[u].restore_rtx == NULL_RTX)
kono
parents:
diff changeset
1636 {
kono
parents:
diff changeset
1637 no_spills_p = false;
kono
parents:
diff changeset
1638 break;
kono
parents:
diff changeset
1639 }
kono
parents:
diff changeset
1640 finish_live_range_start_chains ();
kono
parents:
diff changeset
1641 bitmap_clear (&all_spilled_pseudos);
kono
parents:
diff changeset
1642 bitmap_initialize (&insns_to_process, &reg_obstack);
kono
parents:
diff changeset
1643 EXECUTE_IF_SET_IN_BITMAP (&changed_pseudo_bitmap, 0, u, bi)
kono
parents:
diff changeset
1644 bitmap_ior_into (&insns_to_process, &lra_reg_info[u].insn_bitmap);
kono
parents:
diff changeset
1645 bitmap_clear (&changed_pseudo_bitmap);
kono
parents:
diff changeset
1646 EXECUTE_IF_SET_IN_BITMAP (&insns_to_process, 0, u, bi)
kono
parents:
diff changeset
1647 {
kono
parents:
diff changeset
1648 lra_push_insn_by_uid (u);
kono
parents:
diff changeset
1649 /* Invalidate alternatives for insn should be processed. */
kono
parents:
diff changeset
1650 lra_set_used_insn_alternative_by_uid (u, -1);
kono
parents:
diff changeset
1651 }
kono
parents:
diff changeset
1652 bitmap_clear (&insns_to_process);
kono
parents:
diff changeset
1653 finish_regno_assign_info ();
kono
parents:
diff changeset
1654 free (regno_live_length);
kono
parents:
diff changeset
1655 free (regno_allocno_class_array);
kono
parents:
diff changeset
1656 free (sorted_pseudos);
kono
parents:
diff changeset
1657 free (sorted_reload_pseudos);
kono
parents:
diff changeset
1658 finish_lives ();
kono
parents:
diff changeset
1659 timevar_pop (TV_LRA_ASSIGN);
kono
parents:
diff changeset
1660 if (former_reload_pseudo_spill_p)
kono
parents:
diff changeset
1661 lra_assignment_iter_after_spill++;
kono
parents:
diff changeset
1662 /* This is conditional on flag_checking because valid code can take
kono
parents:
diff changeset
1663 more than this maximum number of iteration, but at the same time
kono
parents:
diff changeset
1664 the test can uncover errors in machine descriptions. */
kono
parents:
diff changeset
1665 if (flag_checking
kono
parents:
diff changeset
1666 && (lra_assignment_iter_after_spill
kono
parents:
diff changeset
1667 > LRA_MAX_ASSIGNMENT_ITERATION_NUMBER))
kono
parents:
diff changeset
1668 internal_error
kono
parents:
diff changeset
1669 ("Maximum number of LRA assignment passes is achieved (%d)\n",
kono
parents:
diff changeset
1670 LRA_MAX_ASSIGNMENT_ITERATION_NUMBER);
kono
parents:
diff changeset
1671 return no_spills_p;
kono
parents:
diff changeset
1672 }
kono
parents:
diff changeset
1673
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1674 /* Find start and finish insns for reload pseudo REGNO. Return true
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1675 if we managed to find the expected insns. Return false,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1676 otherwise. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1677 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1678 find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1679 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1680 unsigned int uid;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1681 bitmap_iterator bi;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1682 int n = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1683 rtx_insn *prev_insn, *next_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1684 rtx_insn *start_insn = NULL, *first_insn = NULL, *second_insn = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1685
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1686 EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1687 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1688 if (start_insn == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1689 start_insn = lra_insn_recog_data[uid]->insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1690 n++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1691 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1692 /* For reload pseudo we should have at most 3 insns referring for it:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1693 input/output reload insns and the original insn. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1694 if (n > 3)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1695 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1696 if (n > 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1697 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1698 for (prev_insn = PREV_INSN (start_insn),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1699 next_insn = NEXT_INSN (start_insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1700 n != 1 && (prev_insn != NULL || next_insn != NULL); )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1701 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1702 if (prev_insn != NULL && first_insn == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1703 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1704 if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1705 INSN_UID (prev_insn)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1706 prev_insn = PREV_INSN (prev_insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1707 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1708 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1709 first_insn = prev_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1710 n--;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1711 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1712 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1713 if (next_insn != NULL && second_insn == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1714 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1715 if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1716 INSN_UID (next_insn)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1717 next_insn = NEXT_INSN (next_insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1718 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1719 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1720 second_insn = next_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1721 n--;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1722 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1723 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1724 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1725 if (n > 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1726 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1727 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1728 start = first_insn != NULL ? first_insn : start_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1729 finish = second_insn != NULL ? second_insn : start_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1730 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1731 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1732
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1733 /* Process reload pseudos which did not get a hard reg, split a hard
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1734 reg live range in live range of a reload pseudo, and then return
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1735 TRUE. If we did not split a hard reg live range, report an error,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1736 and return FALSE. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1737 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1738 lra_split_hard_reg_for (void)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1739 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1740 int i, regno;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1741 rtx_insn *insn, *first, *last;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1742 unsigned int u;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1743 bitmap_iterator bi;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1744 enum reg_class rclass;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1745 int max_regno = max_reg_num ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1746 /* We did not assign hard regs to reload pseudos after two
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1747 iterations. Either it's an asm and something is wrong with the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1748 constraints, or we have run out of spill registers; error out in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1749 either case. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1750 bool asm_p = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1751 bitmap_head failed_reload_insns, failed_reload_pseudos;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1752
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1753 if (lra_dump_file != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1754 fprintf (lra_dump_file,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1755 "\n****** Splitting a hard reg after assignment #%d: ******\n\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1756 lra_assignment_iter);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1757 bitmap_initialize (&failed_reload_pseudos, &reg_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1758 for (i = lra_constraint_new_regno_start; i < max_regno; i++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1759 if (reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1760 && (rclass = lra_get_allocno_class (i)) != NO_REGS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1761 && ! bitmap_bit_p (&non_reload_pseudos, i))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1762 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1763 if (! find_reload_regno_insns (i, first, last))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1764 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1765 if (spill_hard_reg_in_range (i, rclass, first, last))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1766 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1767 bitmap_clear (&failed_reload_pseudos);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1768 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1769 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1770 bitmap_set_bit (&failed_reload_pseudos, i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1771 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1772 bitmap_initialize (&failed_reload_insns, &reg_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1773 EXECUTE_IF_SET_IN_BITMAP (&failed_reload_pseudos, 0, u, bi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1774 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1775 regno = u;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1776 bitmap_ior_into (&failed_reload_insns,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1777 &lra_reg_info[regno].insn_bitmap);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1778 lra_setup_reg_renumber
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1779 (regno, ira_class_hard_regs[lra_get_allocno_class (regno)][0], false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1780 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1781 EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1782 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1783 insn = lra_insn_recog_data[u]->insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1784 if (asm_noperands (PATTERN (insn)) >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1785 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1786 asm_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1787 error_for_asm (insn,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1788 "%<asm%> operand has impossible constraints");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1789 /* Avoid further trouble with this insn.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1790 For asm goto, instead of fixing up all the edges
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1791 just clear the template and clear input operands
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1792 (asm goto doesn't have any output operands). */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1793 if (JUMP_P (insn))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1794 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1795 rtx asm_op = extract_asm_operands (PATTERN (insn));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1796 ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup ("");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1797 ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1798 ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1799 lra_update_insn_regno_info (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1800 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1801 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1802 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1803 PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1804 lra_set_insn_deleted (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1805 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1806 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1807 else if (!asm_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1808 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1809 error ("unable to find a register to spill");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1810 fatal_insn ("this is the insn:", insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1811 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1812 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1813 bitmap_clear (&failed_reload_pseudos);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1814 bitmap_clear (&failed_reload_insns);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1815 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1816 }