annotate gcc/lra-assigns.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Assign reload pseudos.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2010-2020 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 "lra.h"
kono
parents:
diff changeset
95 #include "lra-int.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
96 #include "function-abi.h"
111
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))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
496 conflict_set = lra_no_alloc_regs;
111
kono
parents:
diff changeset
497 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
498 conflict_set = ~regno_set | lra_no_alloc_regs;
111
kono
parents:
diff changeset
499 rclass = regno_allocno_class_array[regno];
kono
parents:
diff changeset
500 rclass_intersect_p = ira_reg_classes_intersect_p[rclass];
kono
parents:
diff changeset
501 curr_hard_regno_costs_check++;
kono
parents:
diff changeset
502 sparseset_clear (conflict_reload_and_inheritance_pseudos);
kono
parents:
diff changeset
503 sparseset_clear (live_range_hard_reg_pseudos);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
504 conflict_set |= lra_reg_info[regno].conflict_hard_regs;
111
kono
parents:
diff changeset
505 biggest_mode = lra_reg_info[regno].biggest_mode;
kono
parents:
diff changeset
506 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
507 {
kono
parents:
diff changeset
508 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[r->start], 0, k, bi)
kono
parents:
diff changeset
509 if (rclass_intersect_p[regno_allocno_class_array[k]])
kono
parents:
diff changeset
510 sparseset_set_bit (live_range_hard_reg_pseudos, k);
kono
parents:
diff changeset
511 EXECUTE_IF_SET_IN_BITMAP (&live_reload_and_inheritance_pseudos[r->start],
kono
parents:
diff changeset
512 0, k, bi)
kono
parents:
diff changeset
513 if (lra_reg_info[k].preferred_hard_regno1 >= 0
kono
parents:
diff changeset
514 && live_pseudos_reg_renumber[k] < 0
kono
parents:
diff changeset
515 && rclass_intersect_p[regno_allocno_class_array[k]])
kono
parents:
diff changeset
516 sparseset_set_bit (conflict_reload_and_inheritance_pseudos, k);
kono
parents:
diff changeset
517 for (p = r->start + 1; p <= r->finish; p++)
kono
parents:
diff changeset
518 {
kono
parents:
diff changeset
519 lra_live_range_t r2;
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
522 r2 != NULL;
kono
parents:
diff changeset
523 r2 = r2->start_next)
kono
parents:
diff changeset
524 {
kono
parents:
diff changeset
525 if (r2->regno >= lra_constraint_new_regno_start
kono
parents:
diff changeset
526 && lra_reg_info[r2->regno].preferred_hard_regno1 >= 0
kono
parents:
diff changeset
527 && live_pseudos_reg_renumber[r2->regno] < 0
kono
parents:
diff changeset
528 && rclass_intersect_p[regno_allocno_class_array[r2->regno]])
kono
parents:
diff changeset
529 sparseset_set_bit (conflict_reload_and_inheritance_pseudos,
kono
parents:
diff changeset
530 r2->regno);
kono
parents:
diff changeset
531 if (live_pseudos_reg_renumber[r2->regno] >= 0
kono
parents:
diff changeset
532 && rclass_intersect_p[regno_allocno_class_array[r2->regno]])
kono
parents:
diff changeset
533 sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
kono
parents:
diff changeset
534 }
kono
parents:
diff changeset
535 }
kono
parents:
diff changeset
536 }
kono
parents:
diff changeset
537 if ((hard_regno = lra_reg_info[regno].preferred_hard_regno1) >= 0)
kono
parents:
diff changeset
538 {
kono
parents:
diff changeset
539 adjust_hard_regno_cost
kono
parents:
diff changeset
540 (hard_regno, -lra_reg_info[regno].preferred_hard_regno_profit1);
kono
parents:
diff changeset
541 if ((hard_regno = lra_reg_info[regno].preferred_hard_regno2) >= 0)
kono
parents:
diff changeset
542 adjust_hard_regno_cost
kono
parents:
diff changeset
543 (hard_regno, -lra_reg_info[regno].preferred_hard_regno_profit2);
kono
parents:
diff changeset
544 }
kono
parents:
diff changeset
545 #ifdef STACK_REGS
kono
parents:
diff changeset
546 if (lra_reg_info[regno].no_stack_p)
kono
parents:
diff changeset
547 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
kono
parents:
diff changeset
548 SET_HARD_REG_BIT (conflict_set, i);
kono
parents:
diff changeset
549 #endif
kono
parents:
diff changeset
550 sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno);
kono
parents:
diff changeset
551 val = lra_reg_info[regno].val;
kono
parents:
diff changeset
552 offset = lra_reg_info[regno].offset;
kono
parents:
diff changeset
553 CLEAR_HARD_REG_SET (impossible_start_hard_regs);
kono
parents:
diff changeset
554 EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
kono
parents:
diff changeset
555 {
kono
parents:
diff changeset
556 conflict_hr = live_pseudos_reg_renumber[conflict_regno];
kono
parents:
diff changeset
557 if (lra_reg_val_equal_p (conflict_regno, val, offset))
kono
parents:
diff changeset
558 {
kono
parents:
diff changeset
559 conflict_hr = live_pseudos_reg_renumber[conflict_regno];
kono
parents:
diff changeset
560 nregs = hard_regno_nregs (conflict_hr,
kono
parents:
diff changeset
561 lra_reg_info[conflict_regno].biggest_mode);
kono
parents:
diff changeset
562 /* Remember about multi-register pseudos. For example, 2
kono
parents:
diff changeset
563 hard register pseudos can start on the same hard register
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
564 but cannot start on HR and HR+1/HR-1. */
111
kono
parents:
diff changeset
565 for (hr = conflict_hr + 1;
kono
parents:
diff changeset
566 hr < FIRST_PSEUDO_REGISTER && hr < conflict_hr + nregs;
kono
parents:
diff changeset
567 hr++)
kono
parents:
diff changeset
568 SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
kono
parents:
diff changeset
569 for (hr = conflict_hr - 1;
kono
parents:
diff changeset
570 hr >= 0 && (int) end_hard_regno (biggest_mode, hr) > conflict_hr;
kono
parents:
diff changeset
571 hr--)
kono
parents:
diff changeset
572 SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
kono
parents:
diff changeset
573 }
kono
parents:
diff changeset
574 else
kono
parents:
diff changeset
575 {
kono
parents:
diff changeset
576 machine_mode biggest_conflict_mode
kono
parents:
diff changeset
577 = lra_reg_info[conflict_regno].biggest_mode;
kono
parents:
diff changeset
578 int biggest_conflict_nregs
kono
parents:
diff changeset
579 = hard_regno_nregs (conflict_hr, biggest_conflict_mode);
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 nregs_diff
kono
parents:
diff changeset
582 = (biggest_conflict_nregs
kono
parents:
diff changeset
583 - hard_regno_nregs (conflict_hr,
kono
parents:
diff changeset
584 PSEUDO_REGNO_MODE (conflict_regno)));
kono
parents:
diff changeset
585 add_to_hard_reg_set (&conflict_set,
kono
parents:
diff changeset
586 biggest_conflict_mode,
kono
parents:
diff changeset
587 conflict_hr
kono
parents:
diff changeset
588 - (WORDS_BIG_ENDIAN ? nregs_diff : 0));
kono
parents:
diff changeset
589 if (hard_reg_set_subset_p (reg_class_contents[rclass],
kono
parents:
diff changeset
590 conflict_set))
kono
parents:
diff changeset
591 return -1;
kono
parents:
diff changeset
592 }
kono
parents:
diff changeset
593 }
kono
parents:
diff changeset
594 EXECUTE_IF_SET_IN_SPARSESET (conflict_reload_and_inheritance_pseudos,
kono
parents:
diff changeset
595 conflict_regno)
kono
parents:
diff changeset
596 if (!lra_reg_val_equal_p (conflict_regno, val, offset))
kono
parents:
diff changeset
597 {
kono
parents:
diff changeset
598 lra_assert (live_pseudos_reg_renumber[conflict_regno] < 0);
kono
parents:
diff changeset
599 if ((hard_regno
kono
parents:
diff changeset
600 = lra_reg_info[conflict_regno].preferred_hard_regno1) >= 0)
kono
parents:
diff changeset
601 {
kono
parents:
diff changeset
602 adjust_hard_regno_cost
kono
parents:
diff changeset
603 (hard_regno,
kono
parents:
diff changeset
604 lra_reg_info[conflict_regno].preferred_hard_regno_profit1);
kono
parents:
diff changeset
605 if ((hard_regno
kono
parents:
diff changeset
606 = lra_reg_info[conflict_regno].preferred_hard_regno2) >= 0)
kono
parents:
diff changeset
607 adjust_hard_regno_cost
kono
parents:
diff changeset
608 (hard_regno,
kono
parents:
diff changeset
609 lra_reg_info[conflict_regno].preferred_hard_regno_profit2);
kono
parents:
diff changeset
610 }
kono
parents:
diff changeset
611 }
kono
parents:
diff changeset
612 /* Make sure that all registers in a multi-word pseudo belong to the
kono
parents:
diff changeset
613 required class. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
614 conflict_set |= ~reg_class_contents[rclass];
111
kono
parents:
diff changeset
615 lra_assert (rclass != NO_REGS);
kono
parents:
diff changeset
616 rclass_size = ira_class_hard_regs_num[rclass];
kono
parents:
diff changeset
617 best_hard_regno = -1;
kono
parents:
diff changeset
618 hard_regno = ira_class_hard_regs[rclass][0];
kono
parents:
diff changeset
619 biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode);
kono
parents:
diff changeset
620 nregs_diff = (biggest_nregs
kono
parents:
diff changeset
621 - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
622 available_regs = reg_class_contents[rclass] & ~lra_no_alloc_regs;
111
kono
parents:
diff changeset
623 for (i = 0; i < rclass_size; i++)
kono
parents:
diff changeset
624 {
kono
parents:
diff changeset
625 if (try_only_hard_regno >= 0)
kono
parents:
diff changeset
626 hard_regno = try_only_hard_regno;
kono
parents:
diff changeset
627 else
kono
parents:
diff changeset
628 hard_regno = ira_class_hard_regs[rclass][i];
kono
parents:
diff changeset
629 if (! overlaps_hard_reg_set_p (conflict_set,
kono
parents:
diff changeset
630 PSEUDO_REGNO_MODE (regno), hard_regno)
kono
parents:
diff changeset
631 && targetm.hard_regno_mode_ok (hard_regno,
kono
parents:
diff changeset
632 PSEUDO_REGNO_MODE (regno))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
633 /* We cannot use prohibited_class_mode_regs for all classes
111
kono
parents:
diff changeset
634 because it is not defined for all classes. */
kono
parents:
diff changeset
635 && (ira_allocno_class_translate[rclass] != rclass
kono
parents:
diff changeset
636 || ! TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
kono
parents:
diff changeset
637 [rclass][PSEUDO_REGNO_MODE (regno)],
kono
parents:
diff changeset
638 hard_regno))
kono
parents:
diff changeset
639 && ! TEST_HARD_REG_BIT (impossible_start_hard_regs, hard_regno)
kono
parents:
diff changeset
640 && (nregs_diff == 0
kono
parents:
diff changeset
641 || (WORDS_BIG_ENDIAN
kono
parents:
diff changeset
642 ? (hard_regno - nregs_diff >= 0
kono
parents:
diff changeset
643 && TEST_HARD_REG_BIT (available_regs,
kono
parents:
diff changeset
644 hard_regno - nregs_diff))
kono
parents:
diff changeset
645 : TEST_HARD_REG_BIT (available_regs,
kono
parents:
diff changeset
646 hard_regno + nregs_diff))))
kono
parents:
diff changeset
647 {
kono
parents:
diff changeset
648 if (hard_regno_costs_check[hard_regno]
kono
parents:
diff changeset
649 != curr_hard_regno_costs_check)
kono
parents:
diff changeset
650 {
kono
parents:
diff changeset
651 hard_regno_costs_check[hard_regno] = curr_hard_regno_costs_check;
kono
parents:
diff changeset
652 hard_regno_costs[hard_regno] = 0;
kono
parents:
diff changeset
653 }
kono
parents:
diff changeset
654 for (j = 0;
kono
parents:
diff changeset
655 j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno));
kono
parents:
diff changeset
656 j++)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
657 if (! crtl->abi->clobbers_full_reg_p (hard_regno + j)
111
kono
parents:
diff changeset
658 && ! df_regs_ever_live_p (hard_regno + j))
kono
parents:
diff changeset
659 /* It needs save restore. */
kono
parents:
diff changeset
660 hard_regno_costs[hard_regno]
kono
parents:
diff changeset
661 += (2
kono
parents:
diff changeset
662 * REG_FREQ_FROM_BB (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
kono
parents:
diff changeset
663 + 1);
kono
parents:
diff changeset
664 priority = targetm.register_priority (hard_regno);
kono
parents:
diff changeset
665 if (best_hard_regno < 0 || hard_regno_costs[hard_regno] < best_cost
kono
parents:
diff changeset
666 || (hard_regno_costs[hard_regno] == best_cost
kono
parents:
diff changeset
667 && (priority > best_priority
kono
parents:
diff changeset
668 || (targetm.register_usage_leveling_p ()
kono
parents:
diff changeset
669 && priority == best_priority
kono
parents:
diff changeset
670 && best_usage > lra_hard_reg_usage[hard_regno]))))
kono
parents:
diff changeset
671 {
kono
parents:
diff changeset
672 best_hard_regno = hard_regno;
kono
parents:
diff changeset
673 best_cost = hard_regno_costs[hard_regno];
kono
parents:
diff changeset
674 best_priority = priority;
kono
parents:
diff changeset
675 best_usage = lra_hard_reg_usage[hard_regno];
kono
parents:
diff changeset
676 }
kono
parents:
diff changeset
677 }
kono
parents:
diff changeset
678 if (try_only_hard_regno >= 0 || (first_p && best_hard_regno >= 0))
kono
parents:
diff changeset
679 break;
kono
parents:
diff changeset
680 }
kono
parents:
diff changeset
681 if (best_hard_regno >= 0)
kono
parents:
diff changeset
682 *cost = best_cost - lra_reg_info[regno].freq;
kono
parents:
diff changeset
683 return best_hard_regno;
kono
parents:
diff changeset
684 }
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 /* A wrapper for find_hard_regno_for_1 (see comments for that function
kono
parents:
diff changeset
687 description). This function tries to find a hard register for
kono
parents:
diff changeset
688 preferred class first if it is worth. */
kono
parents:
diff changeset
689 static int
kono
parents:
diff changeset
690 find_hard_regno_for (int regno, int *cost, int try_only_hard_regno, bool first_p)
kono
parents:
diff changeset
691 {
kono
parents:
diff changeset
692 int hard_regno;
kono
parents:
diff changeset
693 HARD_REG_SET regno_set;
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695 /* Only original pseudos can have a different preferred class. */
kono
parents:
diff changeset
696 if (try_only_hard_regno < 0 && regno < lra_new_regno_start)
kono
parents:
diff changeset
697 {
kono
parents:
diff changeset
698 enum reg_class pref_class = reg_preferred_class (regno);
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 if (regno_allocno_class_array[regno] != pref_class)
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 hard_regno = find_hard_regno_for_1 (regno, cost, -1, first_p,
kono
parents:
diff changeset
703 reg_class_contents[pref_class]);
kono
parents:
diff changeset
704 if (hard_regno >= 0)
kono
parents:
diff changeset
705 return hard_regno;
kono
parents:
diff changeset
706 }
kono
parents:
diff changeset
707 }
kono
parents:
diff changeset
708 CLEAR_HARD_REG_SET (regno_set);
kono
parents:
diff changeset
709 return find_hard_regno_for_1 (regno, cost, try_only_hard_regno, first_p,
kono
parents:
diff changeset
710 regno_set);
kono
parents:
diff changeset
711 }
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 /* Current value used for checking elements in
kono
parents:
diff changeset
714 update_hard_regno_preference_check. */
kono
parents:
diff changeset
715 static int curr_update_hard_regno_preference_check;
kono
parents:
diff changeset
716 /* If an element value is equal to the above variable value, then the
kono
parents:
diff changeset
717 corresponding regno has been processed for preference
kono
parents:
diff changeset
718 propagation. */
kono
parents:
diff changeset
719 static int *update_hard_regno_preference_check;
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 /* Update the preference for using HARD_REGNO for pseudos that are
kono
parents:
diff changeset
722 connected directly or indirectly with REGNO. Apply divisor DIV
kono
parents:
diff changeset
723 to any preference adjustments.
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 The more indirectly a pseudo is connected, the smaller its effect
kono
parents:
diff changeset
726 should be. We therefore increase DIV on each "hop". */
kono
parents:
diff changeset
727 static void
kono
parents:
diff changeset
728 update_hard_regno_preference (int regno, int hard_regno, int div)
kono
parents:
diff changeset
729 {
kono
parents:
diff changeset
730 int another_regno, cost;
kono
parents:
diff changeset
731 lra_copy_t cp, next_cp;
kono
parents:
diff changeset
732
kono
parents:
diff changeset
733 /* Search depth 5 seems to be enough. */
kono
parents:
diff changeset
734 if (div > (1 << 5))
kono
parents:
diff changeset
735 return;
kono
parents:
diff changeset
736 for (cp = lra_reg_info[regno].copies; cp != NULL; cp = next_cp)
kono
parents:
diff changeset
737 {
kono
parents:
diff changeset
738 if (cp->regno1 == regno)
kono
parents:
diff changeset
739 {
kono
parents:
diff changeset
740 next_cp = cp->regno1_next;
kono
parents:
diff changeset
741 another_regno = cp->regno2;
kono
parents:
diff changeset
742 }
kono
parents:
diff changeset
743 else if (cp->regno2 == regno)
kono
parents:
diff changeset
744 {
kono
parents:
diff changeset
745 next_cp = cp->regno2_next;
kono
parents:
diff changeset
746 another_regno = cp->regno1;
kono
parents:
diff changeset
747 }
kono
parents:
diff changeset
748 else
kono
parents:
diff changeset
749 gcc_unreachable ();
kono
parents:
diff changeset
750 if (reg_renumber[another_regno] < 0
kono
parents:
diff changeset
751 && (update_hard_regno_preference_check[another_regno]
kono
parents:
diff changeset
752 != curr_update_hard_regno_preference_check))
kono
parents:
diff changeset
753 {
kono
parents:
diff changeset
754 update_hard_regno_preference_check[another_regno]
kono
parents:
diff changeset
755 = curr_update_hard_regno_preference_check;
kono
parents:
diff changeset
756 cost = cp->freq < div ? 1 : cp->freq / div;
kono
parents:
diff changeset
757 lra_setup_reload_pseudo_preferenced_hard_reg
kono
parents:
diff changeset
758 (another_regno, hard_regno, cost);
kono
parents:
diff changeset
759 update_hard_regno_preference (another_regno, hard_regno, div * 2);
kono
parents:
diff changeset
760 }
kono
parents:
diff changeset
761 }
kono
parents:
diff changeset
762 }
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 /* Return prefix title for pseudo REGNO. */
kono
parents:
diff changeset
765 static const char *
kono
parents:
diff changeset
766 pseudo_prefix_title (int regno)
kono
parents:
diff changeset
767 {
kono
parents:
diff changeset
768 return
kono
parents:
diff changeset
769 (regno < lra_constraint_new_regno_start ? ""
kono
parents:
diff changeset
770 : bitmap_bit_p (&lra_inheritance_pseudos, regno) ? "inheritance "
kono
parents:
diff changeset
771 : bitmap_bit_p (&lra_split_regs, regno) ? "split "
kono
parents:
diff changeset
772 : bitmap_bit_p (&lra_optional_reload_pseudos, regno) ? "optional reload "
kono
parents:
diff changeset
773 : bitmap_bit_p (&lra_subreg_reload_pseudos, regno) ? "subreg reload "
kono
parents:
diff changeset
774 : "reload ");
kono
parents:
diff changeset
775 }
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 /* Update REG_RENUMBER and other pseudo preferences by assignment of
kono
parents:
diff changeset
778 HARD_REGNO to pseudo REGNO and print about it if PRINT_P. */
kono
parents:
diff changeset
779 void
kono
parents:
diff changeset
780 lra_setup_reg_renumber (int regno, int hard_regno, bool print_p)
kono
parents:
diff changeset
781 {
kono
parents:
diff changeset
782 int i, hr;
kono
parents:
diff changeset
783
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
784 /* We cannot just reassign hard register. */
111
kono
parents:
diff changeset
785 lra_assert (hard_regno < 0 || reg_renumber[regno] < 0);
kono
parents:
diff changeset
786 if ((hr = hard_regno) < 0)
kono
parents:
diff changeset
787 hr = reg_renumber[regno];
kono
parents:
diff changeset
788 reg_renumber[regno] = hard_regno;
kono
parents:
diff changeset
789 lra_assert (hr >= 0);
kono
parents:
diff changeset
790 for (i = 0; i < hard_regno_nregs (hr, PSEUDO_REGNO_MODE (regno)); i++)
kono
parents:
diff changeset
791 if (hard_regno < 0)
kono
parents:
diff changeset
792 lra_hard_reg_usage[hr + i] -= lra_reg_info[regno].freq;
kono
parents:
diff changeset
793 else
kono
parents:
diff changeset
794 lra_hard_reg_usage[hr + i] += lra_reg_info[regno].freq;
kono
parents:
diff changeset
795 if (print_p && lra_dump_file != NULL)
kono
parents:
diff changeset
796 fprintf (lra_dump_file, " Assign %d to %sr%d (freq=%d)\n",
kono
parents:
diff changeset
797 reg_renumber[regno], pseudo_prefix_title (regno),
kono
parents:
diff changeset
798 regno, lra_reg_info[regno].freq);
kono
parents:
diff changeset
799 if (hard_regno >= 0)
kono
parents:
diff changeset
800 {
kono
parents:
diff changeset
801 curr_update_hard_regno_preference_check++;
kono
parents:
diff changeset
802 update_hard_regno_preference (regno, hard_regno, 1);
kono
parents:
diff changeset
803 }
kono
parents:
diff changeset
804 }
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 /* Pseudos which occur in insns containing a particular pseudo. */
kono
parents:
diff changeset
807 static bitmap_head insn_conflict_pseudos;
kono
parents:
diff changeset
808
kono
parents:
diff changeset
809 /* Bitmaps used to contain spill pseudos for given pseudo hard regno
kono
parents:
diff changeset
810 and best spill pseudos for given pseudo (and best hard regno). */
kono
parents:
diff changeset
811 static bitmap_head spill_pseudos_bitmap, best_spill_pseudos_bitmap;
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 /* Current pseudo check for validity of elements in
kono
parents:
diff changeset
814 TRY_HARD_REG_PSEUDOS. */
kono
parents:
diff changeset
815 static int curr_pseudo_check;
kono
parents:
diff changeset
816 /* Array used for validity of elements in TRY_HARD_REG_PSEUDOS. */
kono
parents:
diff changeset
817 static int try_hard_reg_pseudos_check[FIRST_PSEUDO_REGISTER];
kono
parents:
diff changeset
818 /* Pseudos who hold given hard register at the considered points. */
kono
parents:
diff changeset
819 static bitmap_head try_hard_reg_pseudos[FIRST_PSEUDO_REGISTER];
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 /* Set up try_hard_reg_pseudos for given program point P and class
kono
parents:
diff changeset
822 RCLASS. Those are pseudos living at P and assigned to a hard
kono
parents:
diff changeset
823 register of RCLASS. In other words, those are pseudos which can be
kono
parents:
diff changeset
824 spilled to assign a hard register of RCLASS to a pseudo living at
kono
parents:
diff changeset
825 P. */
kono
parents:
diff changeset
826 static void
kono
parents:
diff changeset
827 setup_try_hard_regno_pseudos (int p, enum reg_class rclass)
kono
parents:
diff changeset
828 {
kono
parents:
diff changeset
829 int i, hard_regno;
kono
parents:
diff changeset
830 machine_mode mode;
kono
parents:
diff changeset
831 unsigned int spill_regno;
kono
parents:
diff changeset
832 bitmap_iterator bi;
kono
parents:
diff changeset
833
kono
parents:
diff changeset
834 /* Find what pseudos could be spilled. */
kono
parents:
diff changeset
835 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[p], 0, spill_regno, bi)
kono
parents:
diff changeset
836 {
kono
parents:
diff changeset
837 mode = PSEUDO_REGNO_MODE (spill_regno);
kono
parents:
diff changeset
838 hard_regno = live_pseudos_reg_renumber[spill_regno];
kono
parents:
diff changeset
839 if (overlaps_hard_reg_set_p (reg_class_contents[rclass],
kono
parents:
diff changeset
840 mode, hard_regno))
kono
parents:
diff changeset
841 {
kono
parents:
diff changeset
842 for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
kono
parents:
diff changeset
843 {
kono
parents:
diff changeset
844 if (try_hard_reg_pseudos_check[hard_regno + i]
kono
parents:
diff changeset
845 != curr_pseudo_check)
kono
parents:
diff changeset
846 {
kono
parents:
diff changeset
847 try_hard_reg_pseudos_check[hard_regno + i]
kono
parents:
diff changeset
848 = curr_pseudo_check;
kono
parents:
diff changeset
849 bitmap_clear (&try_hard_reg_pseudos[hard_regno + i]);
kono
parents:
diff changeset
850 }
kono
parents:
diff changeset
851 bitmap_set_bit (&try_hard_reg_pseudos[hard_regno + i],
kono
parents:
diff changeset
852 spill_regno);
kono
parents:
diff changeset
853 }
kono
parents:
diff changeset
854 }
kono
parents:
diff changeset
855 }
kono
parents:
diff changeset
856 }
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 /* Assign temporarily HARD_REGNO to pseudo REGNO. Temporary
kono
parents:
diff changeset
859 assignment means that we might undo the data change. */
kono
parents:
diff changeset
860 static void
kono
parents:
diff changeset
861 assign_temporarily (int regno, int hard_regno)
kono
parents:
diff changeset
862 {
kono
parents:
diff changeset
863 int p;
kono
parents:
diff changeset
864 lra_live_range_t r;
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
867 {
kono
parents:
diff changeset
868 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
869 if (hard_regno < 0)
kono
parents:
diff changeset
870 bitmap_clear_bit (&live_hard_reg_pseudos[p], regno);
kono
parents:
diff changeset
871 else
kono
parents:
diff changeset
872 {
kono
parents:
diff changeset
873 bitmap_set_bit (&live_hard_reg_pseudos[p], regno);
kono
parents:
diff changeset
874 insert_in_live_range_start_chain (regno);
kono
parents:
diff changeset
875 }
kono
parents:
diff changeset
876 }
kono
parents:
diff changeset
877 live_pseudos_reg_renumber[regno] = hard_regno;
kono
parents:
diff changeset
878 }
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 /* Return true iff there is a reason why pseudo SPILL_REGNO should not
kono
parents:
diff changeset
881 be spilled. */
kono
parents:
diff changeset
882 static bool
kono
parents:
diff changeset
883 must_not_spill_p (unsigned spill_regno)
kono
parents:
diff changeset
884 {
kono
parents:
diff changeset
885 if ((pic_offset_table_rtx != NULL
kono
parents:
diff changeset
886 && spill_regno == REGNO (pic_offset_table_rtx))
kono
parents:
diff changeset
887 || ((int) spill_regno >= lra_constraint_new_regno_start
kono
parents:
diff changeset
888 && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
kono
parents:
diff changeset
889 && ! bitmap_bit_p (&lra_split_regs, spill_regno)
kono
parents:
diff changeset
890 && ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno)
kono
parents:
diff changeset
891 && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)))
kono
parents:
diff changeset
892 return true;
kono
parents:
diff changeset
893 /* A reload pseudo that requires a singleton register class should
kono
parents:
diff changeset
894 not be spilled.
kono
parents:
diff changeset
895 FIXME: this mitigates the issue on certain i386 patterns, but
kono
parents:
diff changeset
896 does not solve the general case where existing reloads fully
kono
parents:
diff changeset
897 cover a limited register class. */
kono
parents:
diff changeset
898 if (!bitmap_bit_p (&non_reload_pseudos, spill_regno)
kono
parents:
diff changeset
899 && reg_class_size [reg_preferred_class (spill_regno)] == 1
kono
parents:
diff changeset
900 && reg_alternate_class (spill_regno) == NO_REGS)
kono
parents:
diff changeset
901 return true;
kono
parents:
diff changeset
902 return false;
kono
parents:
diff changeset
903 }
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 /* Array used for sorting reload pseudos for subsequent allocation
kono
parents:
diff changeset
906 after spilling some pseudo. */
kono
parents:
diff changeset
907 static int *sorted_reload_pseudos;
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 /* Spill some pseudos for a reload pseudo REGNO and return hard
kono
parents:
diff changeset
910 register which should be used for pseudo after spilling. The
kono
parents:
diff changeset
911 function adds spilled pseudos to SPILLED_PSEUDO_BITMAP. When we
kono
parents:
diff changeset
912 choose hard register (and pseudos occupying the hard registers and
kono
parents:
diff changeset
913 to be spilled), we take into account not only how REGNO will
kono
parents:
diff changeset
914 benefit from the spills but also how other reload pseudos not yet
kono
parents:
diff changeset
915 assigned to hard registers benefit from the spills too. In very
kono
parents:
diff changeset
916 rare cases, the function can fail and return -1.
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 If FIRST_P, return the first available hard reg ignoring other
kono
parents:
diff changeset
919 criteria, e.g. allocation cost and cost of spilling non-reload
kono
parents:
diff changeset
920 pseudos. This approach results in less hard reg pool fragmentation
kono
parents:
diff changeset
921 and permit to allocate hard regs to reload pseudos in complicated
kono
parents:
diff changeset
922 situations where pseudo sizes are different. */
kono
parents:
diff changeset
923 static int
kono
parents:
diff changeset
924 spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
kono
parents:
diff changeset
925 {
kono
parents:
diff changeset
926 int i, j, n, p, hard_regno, best_hard_regno, cost, best_cost, rclass_size;
kono
parents:
diff changeset
927 int reload_hard_regno, reload_cost;
kono
parents:
diff changeset
928 bool static_p, best_static_p;
kono
parents:
diff changeset
929 machine_mode mode;
kono
parents:
diff changeset
930 enum reg_class rclass;
kono
parents:
diff changeset
931 unsigned int spill_regno, reload_regno, uid;
kono
parents:
diff changeset
932 int insn_pseudos_num, best_insn_pseudos_num;
kono
parents:
diff changeset
933 int bad_spills_num, smallest_bad_spills_num;
kono
parents:
diff changeset
934 lra_live_range_t r;
kono
parents:
diff changeset
935 bitmap_iterator bi;
kono
parents:
diff changeset
936
kono
parents:
diff changeset
937 rclass = regno_allocno_class_array[regno];
kono
parents:
diff changeset
938 lra_assert (reg_renumber[regno] < 0 && rclass != NO_REGS);
kono
parents:
diff changeset
939 bitmap_clear (&insn_conflict_pseudos);
kono
parents:
diff changeset
940 bitmap_clear (&best_spill_pseudos_bitmap);
kono
parents:
diff changeset
941 EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
kono
parents:
diff changeset
942 {
kono
parents:
diff changeset
943 struct lra_insn_reg *ir;
kono
parents:
diff changeset
944
kono
parents:
diff changeset
945 for (ir = lra_get_insn_regs (uid); ir != NULL; ir = ir->next)
kono
parents:
diff changeset
946 if (ir->regno >= FIRST_PSEUDO_REGISTER)
kono
parents:
diff changeset
947 bitmap_set_bit (&insn_conflict_pseudos, ir->regno);
kono
parents:
diff changeset
948 }
kono
parents:
diff changeset
949 best_hard_regno = -1;
kono
parents:
diff changeset
950 best_cost = INT_MAX;
kono
parents:
diff changeset
951 best_static_p = TRUE;
kono
parents:
diff changeset
952 best_insn_pseudos_num = INT_MAX;
kono
parents:
diff changeset
953 smallest_bad_spills_num = INT_MAX;
kono
parents:
diff changeset
954 rclass_size = ira_class_hard_regs_num[rclass];
kono
parents:
diff changeset
955 mode = PSEUDO_REGNO_MODE (regno);
kono
parents:
diff changeset
956 /* Invalidate try_hard_reg_pseudos elements. */
kono
parents:
diff changeset
957 curr_pseudo_check++;
kono
parents:
diff changeset
958 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
959 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
960 setup_try_hard_regno_pseudos (p, rclass);
kono
parents:
diff changeset
961 for (i = 0; i < rclass_size; i++)
kono
parents:
diff changeset
962 {
kono
parents:
diff changeset
963 hard_regno = ira_class_hard_regs[rclass][i];
kono
parents:
diff changeset
964 bitmap_clear (&spill_pseudos_bitmap);
kono
parents:
diff changeset
965 for (j = hard_regno_nregs (hard_regno, mode) - 1; j >= 0; j--)
kono
parents:
diff changeset
966 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
967 if (hard_regno + j >= FIRST_PSEUDO_REGISTER)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
968 break;
111
kono
parents:
diff changeset
969 if (try_hard_reg_pseudos_check[hard_regno + j] != curr_pseudo_check)
kono
parents:
diff changeset
970 continue;
kono
parents:
diff changeset
971 lra_assert (!bitmap_empty_p (&try_hard_reg_pseudos[hard_regno + j]));
kono
parents:
diff changeset
972 bitmap_ior_into (&spill_pseudos_bitmap,
kono
parents:
diff changeset
973 &try_hard_reg_pseudos[hard_regno + j]);
kono
parents:
diff changeset
974 }
kono
parents:
diff changeset
975 /* Spill pseudos. */
kono
parents:
diff changeset
976 static_p = false;
kono
parents:
diff changeset
977 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
978 if (must_not_spill_p (spill_regno))
kono
parents:
diff changeset
979 goto fail;
kono
parents:
diff changeset
980 else if (non_spilled_static_chain_regno_p (spill_regno))
kono
parents:
diff changeset
981 static_p = true;
kono
parents:
diff changeset
982 insn_pseudos_num = 0;
kono
parents:
diff changeset
983 bad_spills_num = 0;
kono
parents:
diff changeset
984 if (lra_dump_file != NULL)
kono
parents:
diff changeset
985 fprintf (lra_dump_file, " Trying %d:", hard_regno);
kono
parents:
diff changeset
986 sparseset_clear (live_range_reload_inheritance_pseudos);
kono
parents:
diff changeset
987 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
988 {
kono
parents:
diff changeset
989 if (bitmap_bit_p (&insn_conflict_pseudos, spill_regno))
kono
parents:
diff changeset
990 insn_pseudos_num++;
kono
parents:
diff changeset
991 if (spill_regno >= (unsigned int) lra_bad_spill_regno_start)
kono
parents:
diff changeset
992 bad_spills_num++;
kono
parents:
diff changeset
993 for (r = lra_reg_info[spill_regno].live_ranges;
kono
parents:
diff changeset
994 r != NULL;
kono
parents:
diff changeset
995 r = r->next)
kono
parents:
diff changeset
996 {
kono
parents:
diff changeset
997 for (p = r->start; p <= r->finish; p++)
kono
parents:
diff changeset
998 {
kono
parents:
diff changeset
999 lra_live_range_t r2;
kono
parents:
diff changeset
1000
kono
parents:
diff changeset
1001 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
1002 r2 != NULL;
kono
parents:
diff changeset
1003 r2 = r2->start_next)
kono
parents:
diff changeset
1004 if (r2->regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1005 sparseset_set_bit (live_range_reload_inheritance_pseudos,
kono
parents:
diff changeset
1006 r2->regno);
kono
parents:
diff changeset
1007 }
kono
parents:
diff changeset
1008 }
kono
parents:
diff changeset
1009 }
kono
parents:
diff changeset
1010 n = 0;
kono
parents:
diff changeset
1011 if (sparseset_cardinality (live_range_reload_inheritance_pseudos)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1012 <= (unsigned)param_lra_max_considered_reload_pseudos)
111
kono
parents:
diff changeset
1013 EXECUTE_IF_SET_IN_SPARSESET (live_range_reload_inheritance_pseudos,
kono
parents:
diff changeset
1014 reload_regno)
kono
parents:
diff changeset
1015 if ((int) reload_regno != regno
kono
parents:
diff changeset
1016 && (ira_reg_classes_intersect_p
kono
parents:
diff changeset
1017 [rclass][regno_allocno_class_array[reload_regno]])
kono
parents:
diff changeset
1018 && live_pseudos_reg_renumber[reload_regno] < 0
kono
parents:
diff changeset
1019 && find_hard_regno_for (reload_regno, &cost, -1, first_p) < 0)
kono
parents:
diff changeset
1020 sorted_reload_pseudos[n++] = reload_regno;
kono
parents:
diff changeset
1021 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1022 {
kono
parents:
diff changeset
1023 update_lives (spill_regno, true);
kono
parents:
diff changeset
1024 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1025 fprintf (lra_dump_file, " spill %d(freq=%d)",
kono
parents:
diff changeset
1026 spill_regno, lra_reg_info[spill_regno].freq);
kono
parents:
diff changeset
1027 }
kono
parents:
diff changeset
1028 hard_regno = find_hard_regno_for (regno, &cost, -1, first_p);
kono
parents:
diff changeset
1029 if (hard_regno >= 0)
kono
parents:
diff changeset
1030 {
kono
parents:
diff changeset
1031 assign_temporarily (regno, hard_regno);
kono
parents:
diff changeset
1032 qsort (sorted_reload_pseudos, n, sizeof (int),
kono
parents:
diff changeset
1033 reload_pseudo_compare_func);
kono
parents:
diff changeset
1034 for (j = 0; j < n; j++)
kono
parents:
diff changeset
1035 {
kono
parents:
diff changeset
1036 reload_regno = sorted_reload_pseudos[j];
kono
parents:
diff changeset
1037 lra_assert (live_pseudos_reg_renumber[reload_regno] < 0);
kono
parents:
diff changeset
1038 if ((reload_hard_regno
kono
parents:
diff changeset
1039 = find_hard_regno_for (reload_regno,
kono
parents:
diff changeset
1040 &reload_cost, -1, first_p)) >= 0)
kono
parents:
diff changeset
1041 {
kono
parents:
diff changeset
1042 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1043 fprintf (lra_dump_file, " assign %d(cost=%d)",
kono
parents:
diff changeset
1044 reload_regno, reload_cost);
kono
parents:
diff changeset
1045 assign_temporarily (reload_regno, reload_hard_regno);
kono
parents:
diff changeset
1046 cost += reload_cost;
kono
parents:
diff changeset
1047 }
kono
parents:
diff changeset
1048 }
kono
parents:
diff changeset
1049 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1050 {
kono
parents:
diff changeset
1051 rtx_insn_list *x;
kono
parents:
diff changeset
1052
kono
parents:
diff changeset
1053 cost += lra_reg_info[spill_regno].freq;
kono
parents:
diff changeset
1054 if (ira_reg_equiv[spill_regno].memory != NULL
kono
parents:
diff changeset
1055 || ira_reg_equiv[spill_regno].constant != NULL)
kono
parents:
diff changeset
1056 for (x = ira_reg_equiv[spill_regno].init_insns;
kono
parents:
diff changeset
1057 x != NULL;
kono
parents:
diff changeset
1058 x = x->next ())
kono
parents:
diff changeset
1059 cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (x->insn ()));
kono
parents:
diff changeset
1060 }
kono
parents:
diff changeset
1061 /* Avoid spilling static chain pointer pseudo when non-local
kono
parents:
diff changeset
1062 goto is used. */
kono
parents:
diff changeset
1063 if ((! static_p && best_static_p)
kono
parents:
diff changeset
1064 || (static_p == best_static_p
kono
parents:
diff changeset
1065 && (best_insn_pseudos_num > insn_pseudos_num
kono
parents:
diff changeset
1066 || (best_insn_pseudos_num == insn_pseudos_num
kono
parents:
diff changeset
1067 && (bad_spills_num < smallest_bad_spills_num
kono
parents:
diff changeset
1068 || (bad_spills_num == smallest_bad_spills_num
kono
parents:
diff changeset
1069 && best_cost > cost))))))
kono
parents:
diff changeset
1070 {
kono
parents:
diff changeset
1071 best_insn_pseudos_num = insn_pseudos_num;
kono
parents:
diff changeset
1072 smallest_bad_spills_num = bad_spills_num;
kono
parents:
diff changeset
1073 best_static_p = static_p;
kono
parents:
diff changeset
1074 best_cost = cost;
kono
parents:
diff changeset
1075 best_hard_regno = hard_regno;
kono
parents:
diff changeset
1076 bitmap_copy (&best_spill_pseudos_bitmap, &spill_pseudos_bitmap);
kono
parents:
diff changeset
1077 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1078 fprintf (lra_dump_file,
kono
parents:
diff changeset
1079 " Now best %d(cost=%d, bad_spills=%d, insn_pseudos=%d)\n",
kono
parents:
diff changeset
1080 hard_regno, cost, bad_spills_num, insn_pseudos_num);
kono
parents:
diff changeset
1081 }
kono
parents:
diff changeset
1082 assign_temporarily (regno, -1);
kono
parents:
diff changeset
1083 for (j = 0; j < n; j++)
kono
parents:
diff changeset
1084 {
kono
parents:
diff changeset
1085 reload_regno = sorted_reload_pseudos[j];
kono
parents:
diff changeset
1086 if (live_pseudos_reg_renumber[reload_regno] >= 0)
kono
parents:
diff changeset
1087 assign_temporarily (reload_regno, -1);
kono
parents:
diff changeset
1088 }
kono
parents:
diff changeset
1089 }
kono
parents:
diff changeset
1090 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1091 fprintf (lra_dump_file, "\n");
kono
parents:
diff changeset
1092 /* Restore the live hard reg pseudo info for spilled pseudos. */
kono
parents:
diff changeset
1093 EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1094 update_lives (spill_regno, false);
kono
parents:
diff changeset
1095 fail:
kono
parents:
diff changeset
1096 ;
kono
parents:
diff changeset
1097 }
kono
parents:
diff changeset
1098 /* Spill: */
kono
parents:
diff changeset
1099 EXECUTE_IF_SET_IN_BITMAP (&best_spill_pseudos_bitmap, 0, spill_regno, bi)
kono
parents:
diff changeset
1100 {
kono
parents:
diff changeset
1101 if ((int) spill_regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1102 former_reload_pseudo_spill_p = true;
kono
parents:
diff changeset
1103 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1104 fprintf (lra_dump_file, " Spill %sr%d(hr=%d, freq=%d) for r%d\n",
kono
parents:
diff changeset
1105 pseudo_prefix_title (spill_regno),
kono
parents:
diff changeset
1106 spill_regno, reg_renumber[spill_regno],
kono
parents:
diff changeset
1107 lra_reg_info[spill_regno].freq, regno);
kono
parents:
diff changeset
1108 update_lives (spill_regno, true);
kono
parents:
diff changeset
1109 lra_setup_reg_renumber (spill_regno, -1, false);
kono
parents:
diff changeset
1110 }
kono
parents:
diff changeset
1111 bitmap_ior_into (spilled_pseudo_bitmap, &best_spill_pseudos_bitmap);
kono
parents:
diff changeset
1112 return best_hard_regno;
kono
parents:
diff changeset
1113 }
kono
parents:
diff changeset
1114
kono
parents:
diff changeset
1115 /* Assign HARD_REGNO to REGNO. */
kono
parents:
diff changeset
1116 static void
kono
parents:
diff changeset
1117 assign_hard_regno (int hard_regno, int regno)
kono
parents:
diff changeset
1118 {
kono
parents:
diff changeset
1119 int i;
kono
parents:
diff changeset
1120
kono
parents:
diff changeset
1121 lra_assert (hard_regno >= 0);
kono
parents:
diff changeset
1122 lra_setup_reg_renumber (regno, hard_regno, true);
kono
parents:
diff changeset
1123 update_lives (regno, false);
kono
parents:
diff changeset
1124 for (i = 0;
kono
parents:
diff changeset
1125 i < hard_regno_nregs (hard_regno, lra_reg_info[regno].biggest_mode);
kono
parents:
diff changeset
1126 i++)
kono
parents:
diff changeset
1127 df_set_regs_ever_live (hard_regno + i, true);
kono
parents:
diff changeset
1128 }
kono
parents:
diff changeset
1129
kono
parents:
diff changeset
1130 /* Array used for sorting different pseudos. */
kono
parents:
diff changeset
1131 static int *sorted_pseudos;
kono
parents:
diff changeset
1132
kono
parents:
diff changeset
1133 /* The constraints pass is allowed to create equivalences between
kono
parents:
diff changeset
1134 pseudos that make the current allocation "incorrect" (in the sense
kono
parents:
diff changeset
1135 that pseudos are assigned to hard registers from their own conflict
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1136 sets). The global variable check_and_force_assignment_correctness_p says
111
kono
parents:
diff changeset
1137 whether this might have happened.
kono
parents:
diff changeset
1138
kono
parents:
diff changeset
1139 Process pseudos assigned to hard registers (less frequently used
kono
parents:
diff changeset
1140 first), spill if a conflict is found, and mark the spilled pseudos
kono
parents:
diff changeset
1141 in SPILLED_PSEUDO_BITMAP. Set up LIVE_HARD_REG_PSEUDOS from
kono
parents:
diff changeset
1142 pseudos, assigned to hard registers. */
kono
parents:
diff changeset
1143 static void
kono
parents:
diff changeset
1144 setup_live_pseudos_and_spill_after_risky_transforms (bitmap
kono
parents:
diff changeset
1145 spilled_pseudo_bitmap)
kono
parents:
diff changeset
1146 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1147 int p, i, j, n, regno, hard_regno, biggest_nregs, nregs_diff;
111
kono
parents:
diff changeset
1148 unsigned int k, conflict_regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1149 poly_int64 offset;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1150 int val;
111
kono
parents:
diff changeset
1151 HARD_REG_SET conflict_set;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1152 machine_mode mode, biggest_mode;
111
kono
parents:
diff changeset
1153 lra_live_range_t r;
kono
parents:
diff changeset
1154 bitmap_iterator bi;
kono
parents:
diff changeset
1155 int max_regno = max_reg_num ();
kono
parents:
diff changeset
1156
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1157 if (! check_and_force_assignment_correctness_p)
111
kono
parents:
diff changeset
1158 {
kono
parents:
diff changeset
1159 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1160 if (reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
kono
parents:
diff changeset
1161 update_lives (i, false);
kono
parents:
diff changeset
1162 return;
kono
parents:
diff changeset
1163 }
kono
parents:
diff changeset
1164 for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1165 if ((pic_offset_table_rtx == NULL_RTX
kono
parents:
diff changeset
1166 || i != (int) REGNO (pic_offset_table_rtx))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1167 && (hard_regno = reg_renumber[i]) >= 0 && lra_reg_info[i].nrefs > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1168 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1169 biggest_mode = lra_reg_info[i].biggest_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1170 biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1171 nregs_diff = (biggest_nregs
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1172 - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (i)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1173 enum reg_class rclass = lra_get_allocno_class (i);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1174
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1175 if ((WORDS_BIG_ENDIAN
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1176 && (hard_regno - nregs_diff < 0
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177 || !TEST_HARD_REG_BIT (reg_class_contents[rclass],
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1178 hard_regno - nregs_diff)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 || (!WORDS_BIG_ENDIAN
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 && (hard_regno + nregs_diff >= FIRST_PSEUDO_REGISTER
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 || !TEST_HARD_REG_BIT (reg_class_contents[rclass],
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1182 hard_regno + nregs_diff))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1183 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 /* Hard registers of paradoxical sub-registers are out of
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1185 range of pseudo register class. Spill the pseudo. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1186 reg_renumber[i] = -1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1187 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 sorted_pseudos[n++] = i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1190 }
111
kono
parents:
diff changeset
1191 qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
kono
parents:
diff changeset
1192 if (pic_offset_table_rtx != NULL_RTX
kono
parents:
diff changeset
1193 && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
kono
parents:
diff changeset
1194 && reg_renumber[regno] >= 0 && lra_reg_info[regno].nrefs > 0)
kono
parents:
diff changeset
1195 sorted_pseudos[n++] = regno;
kono
parents:
diff changeset
1196 for (i = n - 1; i >= 0; i--)
kono
parents:
diff changeset
1197 {
kono
parents:
diff changeset
1198 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1199 hard_regno = reg_renumber[regno];
kono
parents:
diff changeset
1200 lra_assert (hard_regno >= 0);
kono
parents:
diff changeset
1201 mode = lra_reg_info[regno].biggest_mode;
kono
parents:
diff changeset
1202 sparseset_clear (live_range_hard_reg_pseudos);
kono
parents:
diff changeset
1203 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
1204 {
kono
parents:
diff changeset
1205 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[r->start], 0, k, bi)
kono
parents:
diff changeset
1206 sparseset_set_bit (live_range_hard_reg_pseudos, k);
kono
parents:
diff changeset
1207 for (p = r->start + 1; p <= r->finish; p++)
kono
parents:
diff changeset
1208 {
kono
parents:
diff changeset
1209 lra_live_range_t r2;
kono
parents:
diff changeset
1210
kono
parents:
diff changeset
1211 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
1212 r2 != NULL;
kono
parents:
diff changeset
1213 r2 = r2->start_next)
kono
parents:
diff changeset
1214 if (live_pseudos_reg_renumber[r2->regno] >= 0)
kono
parents:
diff changeset
1215 sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
kono
parents:
diff changeset
1216 }
kono
parents:
diff changeset
1217 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1218 conflict_set = lra_no_alloc_regs;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1219 conflict_set |= lra_reg_info[regno].conflict_hard_regs;
111
kono
parents:
diff changeset
1220 val = lra_reg_info[regno].val;
kono
parents:
diff changeset
1221 offset = lra_reg_info[regno].offset;
kono
parents:
diff changeset
1222 EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
kono
parents:
diff changeset
1223 if (!lra_reg_val_equal_p (conflict_regno, val, offset)
kono
parents:
diff changeset
1224 /* If it is multi-register pseudos they should start on
kono
parents:
diff changeset
1225 the same hard register. */
kono
parents:
diff changeset
1226 || hard_regno != reg_renumber[conflict_regno])
kono
parents:
diff changeset
1227 {
kono
parents:
diff changeset
1228 int conflict_hard_regno = reg_renumber[conflict_regno];
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1229
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1230 biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1231 biggest_nregs = hard_regno_nregs (conflict_hard_regno,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1232 biggest_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1233 nregs_diff
111
kono
parents:
diff changeset
1234 = (biggest_nregs
kono
parents:
diff changeset
1235 - hard_regno_nregs (conflict_hard_regno,
kono
parents:
diff changeset
1236 PSEUDO_REGNO_MODE (conflict_regno)));
kono
parents:
diff changeset
1237 add_to_hard_reg_set (&conflict_set,
kono
parents:
diff changeset
1238 biggest_mode,
kono
parents:
diff changeset
1239 conflict_hard_regno
kono
parents:
diff changeset
1240 - (WORDS_BIG_ENDIAN ? nregs_diff : 0));
kono
parents:
diff changeset
1241 }
kono
parents:
diff changeset
1242 if (! overlaps_hard_reg_set_p (conflict_set, mode, hard_regno))
kono
parents:
diff changeset
1243 {
kono
parents:
diff changeset
1244 update_lives (regno, false);
kono
parents:
diff changeset
1245 continue;
kono
parents:
diff changeset
1246 }
kono
parents:
diff changeset
1247 bitmap_set_bit (spilled_pseudo_bitmap, regno);
kono
parents:
diff changeset
1248 for (j = 0;
kono
parents:
diff changeset
1249 j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno));
kono
parents:
diff changeset
1250 j++)
kono
parents:
diff changeset
1251 lra_hard_reg_usage[hard_regno + j] -= lra_reg_info[regno].freq;
kono
parents:
diff changeset
1252 reg_renumber[regno] = -1;
kono
parents:
diff changeset
1253 if (regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1254 former_reload_pseudo_spill_p = true;
kono
parents:
diff changeset
1255 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1256 fprintf (lra_dump_file, " Spill r%d after risky transformations\n",
kono
parents:
diff changeset
1257 regno);
kono
parents:
diff changeset
1258 }
kono
parents:
diff changeset
1259 }
kono
parents:
diff changeset
1260
kono
parents:
diff changeset
1261 /* Improve allocation by assigning the same hard regno of inheritance
kono
parents:
diff changeset
1262 pseudos to the connected pseudos. We need this because inheritance
kono
parents:
diff changeset
1263 pseudos are allocated after reload pseudos in the thread and when
kono
parents:
diff changeset
1264 we assign a hard register to a reload pseudo we don't know yet that
kono
parents:
diff changeset
1265 the connected inheritance pseudos can get the same hard register.
kono
parents:
diff changeset
1266 Add pseudos with changed allocation to bitmap CHANGED_PSEUDOS. */
kono
parents:
diff changeset
1267 static void
kono
parents:
diff changeset
1268 improve_inheritance (bitmap changed_pseudos)
kono
parents:
diff changeset
1269 {
kono
parents:
diff changeset
1270 unsigned int k;
kono
parents:
diff changeset
1271 int regno, another_regno, hard_regno, another_hard_regno, cost, i, n;
kono
parents:
diff changeset
1272 lra_copy_t cp, next_cp;
kono
parents:
diff changeset
1273 bitmap_iterator bi;
kono
parents:
diff changeset
1274
kono
parents:
diff changeset
1275 if (lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES)
kono
parents:
diff changeset
1276 return;
kono
parents:
diff changeset
1277 n = 0;
kono
parents:
diff changeset
1278 EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, k, bi)
kono
parents:
diff changeset
1279 if (reg_renumber[k] >= 0 && lra_reg_info[k].nrefs != 0)
kono
parents:
diff changeset
1280 sorted_pseudos[n++] = k;
kono
parents:
diff changeset
1281 qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
kono
parents:
diff changeset
1282 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1283 {
kono
parents:
diff changeset
1284 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1285 hard_regno = reg_renumber[regno];
kono
parents:
diff changeset
1286 lra_assert (hard_regno >= 0);
kono
parents:
diff changeset
1287 for (cp = lra_reg_info[regno].copies; cp != NULL; cp = next_cp)
kono
parents:
diff changeset
1288 {
kono
parents:
diff changeset
1289 if (cp->regno1 == regno)
kono
parents:
diff changeset
1290 {
kono
parents:
diff changeset
1291 next_cp = cp->regno1_next;
kono
parents:
diff changeset
1292 another_regno = cp->regno2;
kono
parents:
diff changeset
1293 }
kono
parents:
diff changeset
1294 else if (cp->regno2 == regno)
kono
parents:
diff changeset
1295 {
kono
parents:
diff changeset
1296 next_cp = cp->regno2_next;
kono
parents:
diff changeset
1297 another_regno = cp->regno1;
kono
parents:
diff changeset
1298 }
kono
parents:
diff changeset
1299 else
kono
parents:
diff changeset
1300 gcc_unreachable ();
kono
parents:
diff changeset
1301 /* Don't change reload pseudo allocation. It might have
kono
parents:
diff changeset
1302 this allocation for a purpose and changing it can result
kono
parents:
diff changeset
1303 in LRA cycling. */
kono
parents:
diff changeset
1304 if ((another_regno < lra_constraint_new_regno_start
kono
parents:
diff changeset
1305 || bitmap_bit_p (&lra_inheritance_pseudos, another_regno))
kono
parents:
diff changeset
1306 && (another_hard_regno = reg_renumber[another_regno]) >= 0
kono
parents:
diff changeset
1307 && another_hard_regno != hard_regno)
kono
parents:
diff changeset
1308 {
kono
parents:
diff changeset
1309 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1310 fprintf
kono
parents:
diff changeset
1311 (lra_dump_file,
kono
parents:
diff changeset
1312 " Improving inheritance for %d(%d) and %d(%d)...\n",
kono
parents:
diff changeset
1313 regno, hard_regno, another_regno, another_hard_regno);
kono
parents:
diff changeset
1314 update_lives (another_regno, true);
kono
parents:
diff changeset
1315 lra_setup_reg_renumber (another_regno, -1, false);
kono
parents:
diff changeset
1316 if (hard_regno == find_hard_regno_for (another_regno, &cost,
kono
parents:
diff changeset
1317 hard_regno, false))
kono
parents:
diff changeset
1318 assign_hard_regno (hard_regno, another_regno);
kono
parents:
diff changeset
1319 else
kono
parents:
diff changeset
1320 assign_hard_regno (another_hard_regno, another_regno);
kono
parents:
diff changeset
1321 bitmap_set_bit (changed_pseudos, another_regno);
kono
parents:
diff changeset
1322 }
kono
parents:
diff changeset
1323 }
kono
parents:
diff changeset
1324 }
kono
parents:
diff changeset
1325 }
kono
parents:
diff changeset
1326
kono
parents:
diff changeset
1327
kono
parents:
diff changeset
1328 /* Bitmap finally containing all pseudos spilled on this assignment
kono
parents:
diff changeset
1329 pass. */
kono
parents:
diff changeset
1330 static bitmap_head all_spilled_pseudos;
kono
parents:
diff changeset
1331 /* All pseudos whose allocation was changed. */
kono
parents:
diff changeset
1332 static bitmap_head changed_pseudo_bitmap;
kono
parents:
diff changeset
1333
kono
parents:
diff changeset
1334
kono
parents:
diff changeset
1335 /* Add to LIVE_RANGE_HARD_REG_PSEUDOS all pseudos conflicting with
kono
parents:
diff changeset
1336 REGNO and whose hard regs can be assigned to REGNO. */
kono
parents:
diff changeset
1337 static void
kono
parents:
diff changeset
1338 find_all_spills_for (int regno)
kono
parents:
diff changeset
1339 {
kono
parents:
diff changeset
1340 int p;
kono
parents:
diff changeset
1341 lra_live_range_t r;
kono
parents:
diff changeset
1342 unsigned int k;
kono
parents:
diff changeset
1343 bitmap_iterator bi;
kono
parents:
diff changeset
1344 enum reg_class rclass;
kono
parents:
diff changeset
1345 bool *rclass_intersect_p;
kono
parents:
diff changeset
1346
kono
parents:
diff changeset
1347 rclass = regno_allocno_class_array[regno];
kono
parents:
diff changeset
1348 rclass_intersect_p = ira_reg_classes_intersect_p[rclass];
kono
parents:
diff changeset
1349 for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
1350 {
kono
parents:
diff changeset
1351 EXECUTE_IF_SET_IN_BITMAP (&live_hard_reg_pseudos[r->start], 0, k, bi)
kono
parents:
diff changeset
1352 if (rclass_intersect_p[regno_allocno_class_array[k]])
kono
parents:
diff changeset
1353 sparseset_set_bit (live_range_hard_reg_pseudos, k);
kono
parents:
diff changeset
1354 for (p = r->start + 1; p <= r->finish; p++)
kono
parents:
diff changeset
1355 {
kono
parents:
diff changeset
1356 lra_live_range_t r2;
kono
parents:
diff changeset
1357
kono
parents:
diff changeset
1358 for (r2 = start_point_ranges[p];
kono
parents:
diff changeset
1359 r2 != NULL;
kono
parents:
diff changeset
1360 r2 = r2->start_next)
kono
parents:
diff changeset
1361 {
kono
parents:
diff changeset
1362 if (live_pseudos_reg_renumber[r2->regno] >= 0
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1363 && ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1364 && rclass_intersect_p[regno_allocno_class_array[r2->regno]]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1365 && ((int) r2->regno < lra_constraint_new_regno_start
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1366 || bitmap_bit_p (&lra_inheritance_pseudos, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1367 || bitmap_bit_p (&lra_split_regs, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1368 || bitmap_bit_p (&lra_optional_reload_pseudos, r2->regno)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1369 /* There is no sense to consider another reload
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1370 pseudo if it has the same class. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1371 || regno_allocno_class_array[r2->regno] != rclass))
111
kono
parents:
diff changeset
1372 sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
kono
parents:
diff changeset
1373 }
kono
parents:
diff changeset
1374 }
kono
parents:
diff changeset
1375 }
kono
parents:
diff changeset
1376 }
kono
parents:
diff changeset
1377
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1378 /* Assign hard registers to reload pseudos and other pseudos. Return
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1379 true if we was not able to assign hard registers to all reload
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1380 pseudos. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1381 static bool
111
kono
parents:
diff changeset
1382 assign_by_spills (void)
kono
parents:
diff changeset
1383 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1384 int i, n, nfails, iter, regno, regno2, hard_regno, cost;
111
kono
parents:
diff changeset
1385 rtx restore_rtx;
kono
parents:
diff changeset
1386 bitmap_head changed_insns, do_not_assign_nonreload_pseudos;
kono
parents:
diff changeset
1387 unsigned int u, conflict_regno;
kono
parents:
diff changeset
1388 bitmap_iterator bi;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1389 bool reload_p, fails_p = false;
111
kono
parents:
diff changeset
1390 int max_regno = max_reg_num ();
kono
parents:
diff changeset
1391
kono
parents:
diff changeset
1392 for (n = 0, i = lra_constraint_new_regno_start; i < max_regno; i++)
kono
parents:
diff changeset
1393 if (reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
kono
parents:
diff changeset
1394 && regno_allocno_class_array[i] != NO_REGS)
kono
parents:
diff changeset
1395 sorted_pseudos[n++] = i;
kono
parents:
diff changeset
1396 bitmap_initialize (&insn_conflict_pseudos, &reg_obstack);
kono
parents:
diff changeset
1397 bitmap_initialize (&spill_pseudos_bitmap, &reg_obstack);
kono
parents:
diff changeset
1398 bitmap_initialize (&best_spill_pseudos_bitmap, &reg_obstack);
kono
parents:
diff changeset
1399 update_hard_regno_preference_check = XCNEWVEC (int, max_regno);
kono
parents:
diff changeset
1400 curr_update_hard_regno_preference_check = 0;
kono
parents:
diff changeset
1401 memset (try_hard_reg_pseudos_check, 0, sizeof (try_hard_reg_pseudos_check));
kono
parents:
diff changeset
1402 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
kono
parents:
diff changeset
1403 bitmap_initialize (&try_hard_reg_pseudos[i], &reg_obstack);
kono
parents:
diff changeset
1404 curr_pseudo_check = 0;
kono
parents:
diff changeset
1405 bitmap_initialize (&changed_insns, &reg_obstack);
kono
parents:
diff changeset
1406 bitmap_initialize (&non_reload_pseudos, &reg_obstack);
kono
parents:
diff changeset
1407 bitmap_ior (&non_reload_pseudos, &lra_inheritance_pseudos, &lra_split_regs);
kono
parents:
diff changeset
1408 bitmap_ior_into (&non_reload_pseudos, &lra_subreg_reload_pseudos);
kono
parents:
diff changeset
1409 bitmap_ior_into (&non_reload_pseudos, &lra_optional_reload_pseudos);
kono
parents:
diff changeset
1410 for (iter = 0; iter <= 1; iter++)
kono
parents:
diff changeset
1411 {
kono
parents:
diff changeset
1412 qsort (sorted_pseudos, n, sizeof (int), reload_pseudo_compare_func);
kono
parents:
diff changeset
1413 nfails = 0;
kono
parents:
diff changeset
1414 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1415 {
kono
parents:
diff changeset
1416 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1417 if (reg_renumber[regno] >= 0)
kono
parents:
diff changeset
1418 continue;
kono
parents:
diff changeset
1419 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1420 fprintf (lra_dump_file, " Assigning to %d "
kono
parents:
diff changeset
1421 "(cl=%s, orig=%d, freq=%d, tfirst=%d, tfreq=%d)...\n",
kono
parents:
diff changeset
1422 regno, reg_class_names[regno_allocno_class_array[regno]],
kono
parents:
diff changeset
1423 ORIGINAL_REGNO (regno_reg_rtx[regno]),
kono
parents:
diff changeset
1424 lra_reg_info[regno].freq, regno_assign_info[regno].first,
kono
parents:
diff changeset
1425 regno_assign_info[regno_assign_info[regno].first].freq);
kono
parents:
diff changeset
1426 hard_regno = find_hard_regno_for (regno, &cost, -1, iter == 1);
kono
parents:
diff changeset
1427 reload_p = ! bitmap_bit_p (&non_reload_pseudos, regno);
kono
parents:
diff changeset
1428 if (hard_regno < 0 && reload_p)
kono
parents:
diff changeset
1429 hard_regno = spill_for (regno, &all_spilled_pseudos, iter == 1);
kono
parents:
diff changeset
1430 if (hard_regno < 0)
kono
parents:
diff changeset
1431 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1432 if (reload_p) {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1433 /* Put unassigned reload pseudo first in the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1434 array. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1435 regno2 = sorted_pseudos[nfails];
111
kono
parents:
diff changeset
1436 sorted_pseudos[nfails++] = regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1437 sorted_pseudos[i] = regno2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1438 }
111
kono
parents:
diff changeset
1439 }
kono
parents:
diff changeset
1440 else
kono
parents:
diff changeset
1441 {
kono
parents:
diff changeset
1442 /* This register might have been spilled by the previous
kono
parents:
diff changeset
1443 pass. Indicate that it is no longer spilled. */
kono
parents:
diff changeset
1444 bitmap_clear_bit (&all_spilled_pseudos, regno);
kono
parents:
diff changeset
1445 assign_hard_regno (hard_regno, regno);
kono
parents:
diff changeset
1446 if (! reload_p)
kono
parents:
diff changeset
1447 /* As non-reload pseudo assignment is changed we
kono
parents:
diff changeset
1448 should reconsider insns referring for the
kono
parents:
diff changeset
1449 pseudo. */
kono
parents:
diff changeset
1450 bitmap_set_bit (&changed_pseudo_bitmap, regno);
kono
parents:
diff changeset
1451 }
kono
parents:
diff changeset
1452 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1453 if (nfails == 0 || iter > 0)
111
kono
parents:
diff changeset
1454 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1455 fails_p = nfails != 0;
111
kono
parents:
diff changeset
1456 break;
kono
parents:
diff changeset
1457 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1458 /* This is a very rare event. We cannot assign a hard register
111
kono
parents:
diff changeset
1459 to reload pseudo because the hard register was assigned to
kono
parents:
diff changeset
1460 another reload pseudo on a previous assignment pass. For x86
kono
parents:
diff changeset
1461 example, on the 1st pass we assigned CX (although another
kono
parents:
diff changeset
1462 hard register could be used for this) to reload pseudo in an
kono
parents:
diff changeset
1463 insn, on the 2nd pass we need CX (and only this) hard
kono
parents:
diff changeset
1464 register for a new reload pseudo in the same insn. Another
kono
parents:
diff changeset
1465 possible situation may occur in assigning to multi-regs
kono
parents:
diff changeset
1466 reload pseudos when hard regs pool is too fragmented even
kono
parents:
diff changeset
1467 after spilling non-reload pseudos.
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 We should do something radical here to succeed. Here we
kono
parents:
diff changeset
1470 spill *all* conflicting pseudos and reassign them. */
kono
parents:
diff changeset
1471 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1472 fprintf (lra_dump_file, " 2nd iter for reload pseudo assignments:\n");
kono
parents:
diff changeset
1473 sparseset_clear (live_range_hard_reg_pseudos);
kono
parents:
diff changeset
1474 for (i = 0; i < nfails; i++)
kono
parents:
diff changeset
1475 {
kono
parents:
diff changeset
1476 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1477 fprintf (lra_dump_file, " Reload r%d assignment failure\n",
kono
parents:
diff changeset
1478 sorted_pseudos[i]);
kono
parents:
diff changeset
1479 find_all_spills_for (sorted_pseudos[i]);
kono
parents:
diff changeset
1480 }
kono
parents:
diff changeset
1481 EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
kono
parents:
diff changeset
1482 {
kono
parents:
diff changeset
1483 if ((int) conflict_regno >= lra_constraint_new_regno_start)
kono
parents:
diff changeset
1484 {
kono
parents:
diff changeset
1485 sorted_pseudos[nfails++] = conflict_regno;
kono
parents:
diff changeset
1486 former_reload_pseudo_spill_p = true;
kono
parents:
diff changeset
1487 }
kono
parents:
diff changeset
1488 else
kono
parents:
diff changeset
1489 /* It is better to do reloads before spilling as after the
kono
parents:
diff changeset
1490 spill-subpass we will reload memory instead of pseudos
kono
parents:
diff changeset
1491 and this will make reusing reload pseudos more
kono
parents:
diff changeset
1492 complicated. Going directly to the spill pass in such
kono
parents:
diff changeset
1493 case might result in worse code performance or even LRA
kono
parents:
diff changeset
1494 cycling if we have few registers. */
kono
parents:
diff changeset
1495 bitmap_set_bit (&all_spilled_pseudos, conflict_regno);
kono
parents:
diff changeset
1496 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1497 fprintf (lra_dump_file, " Spill %s r%d(hr=%d, freq=%d)\n",
kono
parents:
diff changeset
1498 pseudo_prefix_title (conflict_regno), conflict_regno,
kono
parents:
diff changeset
1499 reg_renumber[conflict_regno],
kono
parents:
diff changeset
1500 lra_reg_info[conflict_regno].freq);
kono
parents:
diff changeset
1501 update_lives (conflict_regno, true);
kono
parents:
diff changeset
1502 lra_setup_reg_renumber (conflict_regno, -1, false);
kono
parents:
diff changeset
1503 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1504 if (n < nfails)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1505 n = nfails;
111
kono
parents:
diff changeset
1506 }
kono
parents:
diff changeset
1507 improve_inheritance (&changed_pseudo_bitmap);
kono
parents:
diff changeset
1508 bitmap_clear (&non_reload_pseudos);
kono
parents:
diff changeset
1509 bitmap_clear (&changed_insns);
kono
parents:
diff changeset
1510 if (! lra_simple_p)
kono
parents:
diff changeset
1511 {
kono
parents:
diff changeset
1512 /* We should not assign to original pseudos of inheritance
kono
parents:
diff changeset
1513 pseudos or split pseudos if any its inheritance pseudo did
kono
parents:
diff changeset
1514 not get hard register or any its split pseudo was not split
kono
parents:
diff changeset
1515 because undo inheritance/split pass will extend live range of
kono
parents:
diff changeset
1516 such inheritance or split pseudos. */
kono
parents:
diff changeset
1517 bitmap_initialize (&do_not_assign_nonreload_pseudos, &reg_obstack);
kono
parents:
diff changeset
1518 EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, u, bi)
kono
parents:
diff changeset
1519 if ((restore_rtx = lra_reg_info[u].restore_rtx) != NULL_RTX
kono
parents:
diff changeset
1520 && REG_P (restore_rtx)
kono
parents:
diff changeset
1521 && reg_renumber[u] < 0
kono
parents:
diff changeset
1522 && bitmap_bit_p (&lra_inheritance_pseudos, u))
kono
parents:
diff changeset
1523 bitmap_set_bit (&do_not_assign_nonreload_pseudos, REGNO (restore_rtx));
kono
parents:
diff changeset
1524 EXECUTE_IF_SET_IN_BITMAP (&lra_split_regs, 0, u, bi)
kono
parents:
diff changeset
1525 if ((restore_rtx = lra_reg_info[u].restore_rtx) != NULL_RTX
kono
parents:
diff changeset
1526 && reg_renumber[u] >= 0)
kono
parents:
diff changeset
1527 {
kono
parents:
diff changeset
1528 lra_assert (REG_P (restore_rtx));
kono
parents:
diff changeset
1529 bitmap_set_bit (&do_not_assign_nonreload_pseudos, REGNO (restore_rtx));
kono
parents:
diff changeset
1530 }
kono
parents:
diff changeset
1531 for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1532 if (((i < lra_constraint_new_regno_start
kono
parents:
diff changeset
1533 && ! bitmap_bit_p (&do_not_assign_nonreload_pseudos, i))
kono
parents:
diff changeset
1534 || (bitmap_bit_p (&lra_inheritance_pseudos, i)
kono
parents:
diff changeset
1535 && lra_reg_info[i].restore_rtx != NULL_RTX)
kono
parents:
diff changeset
1536 || (bitmap_bit_p (&lra_split_regs, i)
kono
parents:
diff changeset
1537 && lra_reg_info[i].restore_rtx != NULL_RTX)
kono
parents:
diff changeset
1538 || bitmap_bit_p (&lra_subreg_reload_pseudos, i)
kono
parents:
diff changeset
1539 || bitmap_bit_p (&lra_optional_reload_pseudos, i))
kono
parents:
diff changeset
1540 && reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
kono
parents:
diff changeset
1541 && regno_allocno_class_array[i] != NO_REGS)
kono
parents:
diff changeset
1542 sorted_pseudos[n++] = i;
kono
parents:
diff changeset
1543 bitmap_clear (&do_not_assign_nonreload_pseudos);
kono
parents:
diff changeset
1544 if (n != 0 && lra_dump_file != NULL)
kono
parents:
diff changeset
1545 fprintf (lra_dump_file, " Reassigning non-reload pseudos\n");
kono
parents:
diff changeset
1546 qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
kono
parents:
diff changeset
1547 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1548 {
kono
parents:
diff changeset
1549 regno = sorted_pseudos[i];
kono
parents:
diff changeset
1550 hard_regno = find_hard_regno_for (regno, &cost, -1, false);
kono
parents:
diff changeset
1551 if (hard_regno >= 0)
kono
parents:
diff changeset
1552 {
kono
parents:
diff changeset
1553 assign_hard_regno (hard_regno, regno);
kono
parents:
diff changeset
1554 /* We change allocation for non-reload pseudo on this
kono
parents:
diff changeset
1555 iteration -- mark the pseudo for invalidation of used
kono
parents:
diff changeset
1556 alternatives of insns containing the pseudo. */
kono
parents:
diff changeset
1557 bitmap_set_bit (&changed_pseudo_bitmap, regno);
kono
parents:
diff changeset
1558 }
kono
parents:
diff changeset
1559 else
kono
parents:
diff changeset
1560 {
kono
parents:
diff changeset
1561 enum reg_class rclass = lra_get_allocno_class (regno);
kono
parents:
diff changeset
1562 enum reg_class spill_class;
kono
parents:
diff changeset
1563
kono
parents:
diff changeset
1564 if (targetm.spill_class == NULL
kono
parents:
diff changeset
1565 || lra_reg_info[regno].restore_rtx == NULL_RTX
kono
parents:
diff changeset
1566 || ! bitmap_bit_p (&lra_inheritance_pseudos, regno)
kono
parents:
diff changeset
1567 || (spill_class
kono
parents:
diff changeset
1568 = ((enum reg_class)
kono
parents:
diff changeset
1569 targetm.spill_class
kono
parents:
diff changeset
1570 ((reg_class_t) rclass,
kono
parents:
diff changeset
1571 PSEUDO_REGNO_MODE (regno)))) == NO_REGS)
kono
parents:
diff changeset
1572 continue;
kono
parents:
diff changeset
1573 regno_allocno_class_array[regno] = spill_class;
kono
parents:
diff changeset
1574 hard_regno = find_hard_regno_for (regno, &cost, -1, false);
kono
parents:
diff changeset
1575 if (hard_regno < 0)
kono
parents:
diff changeset
1576 regno_allocno_class_array[regno] = rclass;
kono
parents:
diff changeset
1577 else
kono
parents:
diff changeset
1578 {
kono
parents:
diff changeset
1579 setup_reg_classes
kono
parents:
diff changeset
1580 (regno, spill_class, spill_class, spill_class);
kono
parents:
diff changeset
1581 assign_hard_regno (hard_regno, regno);
kono
parents:
diff changeset
1582 bitmap_set_bit (&changed_pseudo_bitmap, regno);
kono
parents:
diff changeset
1583 }
kono
parents:
diff changeset
1584 }
kono
parents:
diff changeset
1585 }
kono
parents:
diff changeset
1586 }
kono
parents:
diff changeset
1587 free (update_hard_regno_preference_check);
kono
parents:
diff changeset
1588 bitmap_clear (&best_spill_pseudos_bitmap);
kono
parents:
diff changeset
1589 bitmap_clear (&spill_pseudos_bitmap);
kono
parents:
diff changeset
1590 bitmap_clear (&insn_conflict_pseudos);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1591 return fails_p;
111
kono
parents:
diff changeset
1592 }
kono
parents:
diff changeset
1593
kono
parents:
diff changeset
1594 /* Entry function to assign hard registers to new reload pseudos
kono
parents:
diff changeset
1595 starting with LRA_CONSTRAINT_NEW_REGNO_START (by possible spilling
kono
parents:
diff changeset
1596 of old pseudos) and possibly to the old pseudos. The function adds
kono
parents:
diff changeset
1597 what insns to process for the next constraint pass. Those are all
kono
parents:
diff changeset
1598 insns who contains non-reload and non-inheritance pseudos with
kono
parents:
diff changeset
1599 changed allocation.
kono
parents:
diff changeset
1600
kono
parents:
diff changeset
1601 Return true if we did not spill any non-reload and non-inheritance
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1602 pseudos. Set up FAILS_P if we failed to assign hard registers to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1603 all reload pseudos. */
111
kono
parents:
diff changeset
1604 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1605 lra_assign (bool &fails_p)
111
kono
parents:
diff changeset
1606 {
kono
parents:
diff changeset
1607 int i;
kono
parents:
diff changeset
1608 unsigned int u;
kono
parents:
diff changeset
1609 bitmap_iterator bi;
kono
parents:
diff changeset
1610 bitmap_head insns_to_process;
kono
parents:
diff changeset
1611 bool no_spills_p;
kono
parents:
diff changeset
1612 int max_regno = max_reg_num ();
kono
parents:
diff changeset
1613
kono
parents:
diff changeset
1614 timevar_push (TV_LRA_ASSIGN);
kono
parents:
diff changeset
1615 lra_assignment_iter++;
kono
parents:
diff changeset
1616 if (lra_dump_file != NULL)
kono
parents:
diff changeset
1617 fprintf (lra_dump_file, "\n********** Assignment #%d: **********\n\n",
kono
parents:
diff changeset
1618 lra_assignment_iter);
kono
parents:
diff changeset
1619 init_lives ();
kono
parents:
diff changeset
1620 sorted_pseudos = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
1621 sorted_reload_pseudos = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
1622 regno_allocno_class_array = XNEWVEC (enum reg_class, max_regno);
kono
parents:
diff changeset
1623 regno_live_length = XNEWVEC (int, max_regno);
kono
parents:
diff changeset
1624 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
kono
parents:
diff changeset
1625 {
kono
parents:
diff changeset
1626 int l;
kono
parents:
diff changeset
1627 lra_live_range_t r;
kono
parents:
diff changeset
1628
kono
parents:
diff changeset
1629 regno_allocno_class_array[i] = lra_get_allocno_class (i);
kono
parents:
diff changeset
1630 for (l = 0, r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
kono
parents:
diff changeset
1631 l += r->finish - r->start + 1;
kono
parents:
diff changeset
1632 regno_live_length[i] = l;
kono
parents:
diff changeset
1633 }
kono
parents:
diff changeset
1634 former_reload_pseudo_spill_p = false;
kono
parents:
diff changeset
1635 init_regno_assign_info ();
kono
parents:
diff changeset
1636 bitmap_initialize (&all_spilled_pseudos, &reg_obstack);
kono
parents:
diff changeset
1637 create_live_range_start_chains ();
kono
parents:
diff changeset
1638 setup_live_pseudos_and_spill_after_risky_transforms (&all_spilled_pseudos);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1639 if (! lra_asm_error_p && flag_checking)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1640 /* Check correctness of allocation for call-crossed pseudos but
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1641 only when there are no asm errors as in the case of errors the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1642 asm is removed and it can result in incorrect allocation. */
111
kono
parents:
diff changeset
1643 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1644 if (lra_reg_info[i].nrefs != 0
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1645 && reg_renumber[i] >= 0
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1646 && overlaps_hard_reg_set_p (lra_reg_info[i].conflict_hard_regs,
111
kono
parents:
diff changeset
1647 PSEUDO_REGNO_MODE (i), reg_renumber[i]))
kono
parents:
diff changeset
1648 gcc_unreachable ();
kono
parents:
diff changeset
1649 /* Setup insns to process on the next constraint pass. */
kono
parents:
diff changeset
1650 bitmap_initialize (&changed_pseudo_bitmap, &reg_obstack);
kono
parents:
diff changeset
1651 init_live_reload_and_inheritance_pseudos ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1652 fails_p = assign_by_spills ();
111
kono
parents:
diff changeset
1653 finish_live_reload_and_inheritance_pseudos ();
kono
parents:
diff changeset
1654 bitmap_ior_into (&changed_pseudo_bitmap, &all_spilled_pseudos);
kono
parents:
diff changeset
1655 no_spills_p = true;
kono
parents:
diff changeset
1656 EXECUTE_IF_SET_IN_BITMAP (&all_spilled_pseudos, 0, u, bi)
kono
parents:
diff changeset
1657 /* We ignore spilled pseudos created on last inheritance pass
kono
parents:
diff changeset
1658 because they will be removed. */
kono
parents:
diff changeset
1659 if (lra_reg_info[u].restore_rtx == NULL_RTX)
kono
parents:
diff changeset
1660 {
kono
parents:
diff changeset
1661 no_spills_p = false;
kono
parents:
diff changeset
1662 break;
kono
parents:
diff changeset
1663 }
kono
parents:
diff changeset
1664 finish_live_range_start_chains ();
kono
parents:
diff changeset
1665 bitmap_clear (&all_spilled_pseudos);
kono
parents:
diff changeset
1666 bitmap_initialize (&insns_to_process, &reg_obstack);
kono
parents:
diff changeset
1667 EXECUTE_IF_SET_IN_BITMAP (&changed_pseudo_bitmap, 0, u, bi)
kono
parents:
diff changeset
1668 bitmap_ior_into (&insns_to_process, &lra_reg_info[u].insn_bitmap);
kono
parents:
diff changeset
1669 bitmap_clear (&changed_pseudo_bitmap);
kono
parents:
diff changeset
1670 EXECUTE_IF_SET_IN_BITMAP (&insns_to_process, 0, u, bi)
kono
parents:
diff changeset
1671 {
kono
parents:
diff changeset
1672 lra_push_insn_by_uid (u);
kono
parents:
diff changeset
1673 /* Invalidate alternatives for insn should be processed. */
kono
parents:
diff changeset
1674 lra_set_used_insn_alternative_by_uid (u, -1);
kono
parents:
diff changeset
1675 }
kono
parents:
diff changeset
1676 bitmap_clear (&insns_to_process);
kono
parents:
diff changeset
1677 finish_regno_assign_info ();
kono
parents:
diff changeset
1678 free (regno_live_length);
kono
parents:
diff changeset
1679 free (regno_allocno_class_array);
kono
parents:
diff changeset
1680 free (sorted_pseudos);
kono
parents:
diff changeset
1681 free (sorted_reload_pseudos);
kono
parents:
diff changeset
1682 finish_lives ();
kono
parents:
diff changeset
1683 timevar_pop (TV_LRA_ASSIGN);
kono
parents:
diff changeset
1684 if (former_reload_pseudo_spill_p)
kono
parents:
diff changeset
1685 lra_assignment_iter_after_spill++;
kono
parents:
diff changeset
1686 /* This is conditional on flag_checking because valid code can take
kono
parents:
diff changeset
1687 more than this maximum number of iteration, but at the same time
kono
parents:
diff changeset
1688 the test can uncover errors in machine descriptions. */
kono
parents:
diff changeset
1689 if (flag_checking
kono
parents:
diff changeset
1690 && (lra_assignment_iter_after_spill
kono
parents:
diff changeset
1691 > LRA_MAX_ASSIGNMENT_ITERATION_NUMBER))
kono
parents:
diff changeset
1692 internal_error
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1693 ("maximum number of LRA assignment passes is achieved (%d)",
111
kono
parents:
diff changeset
1694 LRA_MAX_ASSIGNMENT_ITERATION_NUMBER);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1695 /* Reset the assignment correctness flag: */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1696 check_and_force_assignment_correctness_p = false;
111
kono
parents:
diff changeset
1697 return no_spills_p;
kono
parents:
diff changeset
1698 }
kono
parents:
diff changeset
1699
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1700 /* Find start and finish insns for reload pseudo REGNO. Return true
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1701 if we managed to find the expected insns. Return false,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1702 otherwise. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1703 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1704 find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1705 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1706 unsigned int uid;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1707 bitmap_iterator bi;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1708 int n = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1709 rtx_insn *prev_insn, *next_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1710 rtx_insn *start_insn = NULL, *first_insn = NULL, *second_insn = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1711
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1712 EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1713 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1714 if (start_insn == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1715 start_insn = lra_insn_recog_data[uid]->insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1716 n++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1717 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1718 /* For reload pseudo we should have at most 3 insns referring for it:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1719 input/output reload insns and the original insn. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1720 if (n > 3)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1721 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1722 if (n > 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1723 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1724 for (prev_insn = PREV_INSN (start_insn),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1725 next_insn = NEXT_INSN (start_insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1726 n != 1 && (prev_insn != NULL || next_insn != NULL); )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1727 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1728 if (prev_insn != NULL && first_insn == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1729 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1730 if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1731 INSN_UID (prev_insn)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1732 prev_insn = PREV_INSN (prev_insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1733 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1734 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1735 first_insn = prev_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1736 n--;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1737 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1738 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1739 if (next_insn != NULL && second_insn == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1740 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1741 if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1742 INSN_UID (next_insn)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1743 next_insn = NEXT_INSN (next_insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1744 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1745 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1746 second_insn = next_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1747 n--;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1748 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1749 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1750 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1751 if (n > 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1752 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1753 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1754 start = first_insn != NULL ? first_insn : start_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1755 finish = second_insn != NULL ? second_insn : start_insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1756 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1757 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1758
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1759 /* Process reload pseudos which did not get a hard reg, split a hard
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1760 reg live range in live range of a reload pseudo, and then return
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1761 TRUE. If we did not split a hard reg live range, report an error,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1762 and return FALSE. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1763 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1764 lra_split_hard_reg_for (void)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1765 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1766 int i, regno;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1767 rtx_insn *insn, *first, *last;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1768 unsigned int u;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1769 bitmap_iterator bi;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1770 enum reg_class rclass;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1771 int max_regno = max_reg_num ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1772 /* We did not assign hard regs to reload pseudos after two
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1773 iterations. Either it's an asm and something is wrong with the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1774 constraints, or we have run out of spill registers; error out in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1775 either case. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1776 bool asm_p = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1777 bitmap_head failed_reload_insns, failed_reload_pseudos;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1778
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1779 if (lra_dump_file != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1780 fprintf (lra_dump_file,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1781 "\n****** Splitting a hard reg after assignment #%d: ******\n\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1782 lra_assignment_iter);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1783 bitmap_initialize (&failed_reload_pseudos, &reg_obstack);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1784 bitmap_initialize (&non_reload_pseudos, &reg_obstack);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1785 bitmap_ior (&non_reload_pseudos, &lra_inheritance_pseudos, &lra_split_regs);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1786 bitmap_ior_into (&non_reload_pseudos, &lra_subreg_reload_pseudos);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1787 bitmap_ior_into (&non_reload_pseudos, &lra_optional_reload_pseudos);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1788 for (i = lra_constraint_new_regno_start; i < max_regno; i++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1789 if (reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1790 && (rclass = lra_get_allocno_class (i)) != NO_REGS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1791 && ! bitmap_bit_p (&non_reload_pseudos, i))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1792 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1793 if (! find_reload_regno_insns (i, first, last))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1794 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1795 if (spill_hard_reg_in_range (i, rclass, first, last))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1796 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1797 bitmap_clear (&failed_reload_pseudos);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1798 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1799 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1800 bitmap_set_bit (&failed_reload_pseudos, i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1801 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1802 bitmap_clear (&non_reload_pseudos);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1803 bitmap_initialize (&failed_reload_insns, &reg_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1804 EXECUTE_IF_SET_IN_BITMAP (&failed_reload_pseudos, 0, u, bi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1805 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1806 regno = u;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1807 bitmap_ior_into (&failed_reload_insns,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1808 &lra_reg_info[regno].insn_bitmap);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1809 lra_setup_reg_renumber
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1810 (regno, ira_class_hard_regs[lra_get_allocno_class (regno)][0], false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1811 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1812 EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1813 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1814 insn = lra_insn_recog_data[u]->insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1815 if (asm_noperands (PATTERN (insn)) >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1816 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1817 lra_asm_error_p = asm_p = true;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1818 error_for_asm (insn,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1819 "%<asm%> operand has impossible constraints");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1820 /* Avoid further trouble with this insn.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1821 For asm goto, instead of fixing up all the edges
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1822 just clear the template and clear input operands
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1823 (asm goto doesn't have any output operands). */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1824 if (JUMP_P (insn))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1825 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1826 rtx asm_op = extract_asm_operands (PATTERN (insn));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1827 ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup ("");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1828 ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1829 ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1830 lra_update_insn_regno_info (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1831 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1832 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1833 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1834 PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1835 lra_set_insn_deleted (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1836 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1837 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1838 else if (!asm_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1839 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1840 error ("unable to find a register to spill");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1841 fatal_insn ("this is the insn:", insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1842 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1843 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1844 bitmap_clear (&failed_reload_pseudos);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1845 bitmap_clear (&failed_reload_insns);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1846 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1847 }