Branch data Line data Source code
1 : : /* IRA conflict builder.
2 : : Copyright (C) 2006-2025 Free Software Foundation, Inc.
3 : : Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "backend.h"
25 : : #include "target.h"
26 : : #include "rtl.h"
27 : : #include "predict.h"
28 : : #include "memmodel.h"
29 : : #include "tm_p.h"
30 : : #include "insn-config.h"
31 : : #include "regs.h"
32 : : #include "ira.h"
33 : : #include "ira-int.h"
34 : : #include "sparseset.h"
35 : : #include "addresses.h"
36 : :
37 : : /* This file contains code responsible for allocno conflict creation,
38 : : allocno copy creation and allocno info accumulation on upper level
39 : : regions. */
40 : :
41 : : /* ira_allocnos_num array of arrays of bits, recording whether two
42 : : allocno's conflict (can't go in the same hardware register).
43 : :
44 : : Some arrays will be used as conflict bit vector of the
45 : : corresponding allocnos see function build_object_conflicts. */
46 : : static IRA_INT_TYPE **conflicts;
47 : :
48 : : /* Macro to test a conflict of C1 and C2 in `conflicts'. */
49 : : #define OBJECTS_CONFLICT_P(C1, C2) \
50 : : (OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2) \
51 : : && OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1) \
52 : : && TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)], \
53 : : OBJECT_CONFLICT_ID (C2), \
54 : : OBJECT_MIN (C1), OBJECT_MAX (C1)))
55 : :
56 : :
57 : : /* Record a conflict between objects OBJ1 and OBJ2. If necessary,
58 : : canonicalize the conflict by recording it for lower-order subobjects
59 : : of the corresponding allocnos. */
60 : : static void
61 : 218230335 : record_object_conflict (ira_object_t obj1, ira_object_t obj2)
62 : : {
63 : 218230335 : ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
64 : 218230335 : ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
65 : 218230335 : int w1 = OBJECT_SUBWORD (obj1);
66 : 218230335 : int w2 = OBJECT_SUBWORD (obj2);
67 : 218230335 : int id1, id2;
68 : :
69 : : /* Canonicalize the conflict. If two identically-numbered words
70 : : conflict, always record this as a conflict between words 0. That
71 : : is the only information we need, and it is easier to test for if
72 : : it is collected in each allocno's lowest-order object. */
73 : 218230335 : if (w1 == w2 && w1 > 0)
74 : : {
75 : 1302597 : obj1 = ALLOCNO_OBJECT (a1, 0);
76 : 1302597 : obj2 = ALLOCNO_OBJECT (a2, 0);
77 : : }
78 : 218230335 : id1 = OBJECT_CONFLICT_ID (obj1);
79 : 218230335 : id2 = OBJECT_CONFLICT_ID (obj2);
80 : :
81 : 218230335 : SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
82 : : OBJECT_MAX (obj1));
83 : 218230335 : SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
84 : : OBJECT_MAX (obj2));
85 : 218230335 : }
86 : :
87 : : /* Build allocno conflict table by processing allocno live ranges.
88 : : Return true if the table was built. The table is not built if it
89 : : is too big. */
90 : : static bool
91 : 1044976 : build_conflict_bit_table (void)
92 : : {
93 : 1044976 : int i;
94 : 1044976 : unsigned int j;
95 : 1044976 : enum reg_class aclass;
96 : 1044976 : int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
97 : 1044976 : live_range_t r;
98 : 1044976 : ira_allocno_t allocno;
99 : 1044976 : ira_allocno_iterator ai;
100 : 1044976 : sparseset objects_live;
101 : 1044976 : ira_object_t obj;
102 : 1044976 : ira_allocno_object_iterator aoi;
103 : :
104 : 1044976 : allocated_words_num = 0;
105 : 27322038 : FOR_EACH_ALLOCNO (allocno, ai)
106 : 52006300 : FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
107 : : {
108 : 25729238 : if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
109 : 901498 : continue;
110 : 24827740 : conflict_bit_vec_words_num
111 : 24827740 : = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
112 : : / IRA_INT_BITS);
113 : 24827740 : allocated_words_num += conflict_bit_vec_words_num;
114 : 24827740 : if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
115 : 24827740 : > (uint64_t) param_ira_max_conflict_table_size * 1024 * 1024)
116 : : {
117 : 0 : if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
118 : 0 : fprintf (ira_dump_file,
119 : : "+++Conflict table will be too big(>%dMB) "
120 : : "-- don't use it\n",
121 : : param_ira_max_conflict_table_size);
122 : 0 : return false;
123 : : }
124 : : }
125 : :
126 : 2089952 : conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
127 : 1044976 : * ira_objects_num);
128 : 1044976 : allocated_words_num = 0;
129 : 27322038 : FOR_EACH_ALLOCNO (allocno, ai)
130 : 52006300 : FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
131 : : {
132 : 25729238 : int id = OBJECT_CONFLICT_ID (obj);
133 : 25729238 : if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
134 : : {
135 : 901498 : conflicts[id] = NULL;
136 : 901498 : continue;
137 : : }
138 : 24827740 : conflict_bit_vec_words_num
139 : 24827740 : = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
140 : : / IRA_INT_BITS);
141 : 24827740 : allocated_words_num += conflict_bit_vec_words_num;
142 : 24827740 : conflicts[id]
143 : 49655480 : = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
144 : 24827740 : * conflict_bit_vec_words_num);
145 : 24827740 : memset (conflicts[id], 0,
146 : : sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
147 : : }
148 : :
149 : 1044976 : object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
150 : 1044976 : if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
151 : 39 : fprintf (ira_dump_file,
152 : : "+++Allocating " HOST_SIZE_T_PRINT_UNSIGNED
153 : : " bytes for conflict table (uncompressed size "
154 : : HOST_SIZE_T_PRINT_UNSIGNED ")\n",
155 : 39 : (fmt_size_t) (sizeof (IRA_INT_TYPE) * allocated_words_num),
156 : 39 : (fmt_size_t) (sizeof (IRA_INT_TYPE) * object_set_words
157 : 39 : * ira_objects_num));
158 : :
159 : 1044976 : objects_live = sparseset_alloc (ira_objects_num);
160 : 30958842 : for (i = 0; i < ira_max_point; i++)
161 : : {
162 : 57340250 : for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
163 : : {
164 : 27426384 : ira_object_t obj = r->object;
165 : 27426384 : ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
166 : 27426384 : int id = OBJECT_CONFLICT_ID (obj);
167 : :
168 : 27426384 : gcc_assert (id < ira_objects_num);
169 : :
170 : 27426384 : aclass = ALLOCNO_CLASS (allocno);
171 : 531742761 : EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
172 : : {
173 : 285535097 : ira_object_t live_obj = ira_object_id_map[j];
174 : 285535097 : ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
175 : 285535097 : enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
176 : :
177 : 285535097 : if (ira_reg_classes_intersect_p[aclass][live_aclass]
178 : : /* Don't set up conflict for the allocno with itself. */
179 : 218781280 : && live_a != allocno)
180 : : {
181 : 218230335 : record_object_conflict (obj, live_obj);
182 : : }
183 : : }
184 : 27426384 : sparseset_set_bit (objects_live, id);
185 : : }
186 : :
187 : 57340250 : for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
188 : 27426384 : sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
189 : : }
190 : 1044976 : sparseset_free (objects_live);
191 : 1044976 : return true;
192 : : }
193 : :
194 : : /* Return true iff allocnos A1 and A2 cannot be allocated to the same
195 : : register due to conflicts. */
196 : :
197 : : static bool
198 : 7943039 : allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
199 : : {
200 : : /* Due to the fact that we canonicalize conflicts (see
201 : : record_object_conflict), we only need to test for conflicts of
202 : : the lowest order words. */
203 : 7943039 : ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
204 : 7943039 : ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
205 : :
206 : 7943039 : return OBJECTS_CONFLICT_P (obj1, obj2);
207 : : }
208 : :
209 : : /* Check that X is REG or SUBREG of REG. */
210 : : #define REG_SUBREG_P(x) \
211 : : (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
212 : :
213 : : /* Return X if X is a REG, otherwise it should be SUBREG of REG and
214 : : the function returns the reg in this case. *OFFSET will be set to
215 : : 0 in the first case or the regno offset in the first case. */
216 : : static rtx
217 : 25084344 : go_through_subreg (rtx x, int *offset)
218 : : {
219 : 25084344 : rtx reg;
220 : :
221 : 25084344 : *offset = 0;
222 : 25084344 : if (REG_P (x))
223 : : return x;
224 : 1012159 : ira_assert (GET_CODE (x) == SUBREG);
225 : 1012159 : reg = SUBREG_REG (x);
226 : 1012159 : ira_assert (REG_P (reg));
227 : 1012159 : if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
228 : 0 : *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
229 : 0 : SUBREG_BYTE (x), GET_MODE (x));
230 : : /* The offset is always 0 for paradoxical subregs. */
231 : 1012159 : else if (!can_div_trunc_p (SUBREG_BYTE (x),
232 : 1012159 : REGMODE_NATURAL_SIZE (GET_MODE (reg)), offset))
233 : : /* Checked by validate_subreg. We must know at compile time which
234 : : inner hard registers are being accessed. */
235 : : gcc_unreachable ();
236 : : return reg;
237 : : }
238 : :
239 : : /* Return the recomputed frequency for this shuffle copy or its similar
240 : : case, since it's not for a real move insn, make it smaller. */
241 : :
242 : : static int
243 : 11546485 : get_freq_for_shuffle_copy (int freq)
244 : : {
245 : 9765092 : return freq < 8 ? 1 : freq / 8;
246 : : }
247 : :
248 : : /* Process registers REG1 and REG2 in move INSN with execution
249 : : frequency FREQ. The function also processes the registers in a
250 : : potential move insn (INSN == NULL in this case) with frequency
251 : : FREQ. The function can modify hard register costs of the
252 : : corresponding allocnos or create a copy involving the corresponding
253 : : allocnos. The function does nothing if the both registers are hard
254 : : registers. When nothing is changed, the function returns FALSE.
255 : : SINGLE_INPUT_OP_HAS_CSTR_P is only meaningful when constraint_p
256 : : is true, see function ira_get_dup_out_num for its meaning. */
257 : : static bool
258 : 12542172 : process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, rtx_insn *insn,
259 : : int freq, bool single_input_op_has_cstr_p = true)
260 : : {
261 : 12542172 : int allocno_preferenced_hard_regno, index, offset1, offset2;
262 : 12542172 : int cost, conflict_cost, move_cost;
263 : 12542172 : bool only_regs_p;
264 : 12542172 : ira_allocno_t a;
265 : 12542172 : reg_class_t rclass, aclass;
266 : 12542172 : machine_mode mode;
267 : 12542172 : ira_copy_t cp;
268 : :
269 : 12542172 : gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
270 : 12542172 : only_regs_p = REG_P (reg1) && REG_P (reg2);
271 : 12542172 : reg1 = go_through_subreg (reg1, &offset1);
272 : 12542172 : reg2 = go_through_subreg (reg2, &offset2);
273 : : /* Set up hard regno preferenced by allocno. If allocno gets the
274 : : hard regno the copy (or potential move) insn will be removed. */
275 : 12542172 : if (HARD_REGISTER_P (reg1))
276 : : {
277 : 3030409 : if (HARD_REGISTER_P (reg2))
278 : : return false;
279 : 3030409 : allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
280 : 3030409 : a = ira_curr_regno_allocno_map[REGNO (reg2)];
281 : : }
282 : 9511763 : else if (HARD_REGISTER_P (reg2))
283 : : {
284 : 3299862 : allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
285 : 3299862 : a = ira_curr_regno_allocno_map[REGNO (reg1)];
286 : : }
287 : : else
288 : : {
289 : 6211901 : ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
290 : 6211901 : ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
291 : :
292 : 6211901 : if (!allocnos_conflict_for_copy_p (a1, a2)
293 : 5698105 : && offset1 == offset2
294 : 6211901 : && ordered_p (GET_MODE_PRECISION (ALLOCNO_MODE (a1)),
295 : 5616846 : GET_MODE_PRECISION (ALLOCNO_MODE (a2))))
296 : : {
297 : 5616846 : cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
298 : : ira_curr_loop_tree_node);
299 : 5616846 : bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
300 : 5616846 : return true;
301 : : }
302 : : else
303 : : return false;
304 : : }
305 : :
306 : 6330271 : if (! IN_RANGE (allocno_preferenced_hard_regno,
307 : : 0, FIRST_PSEUDO_REGISTER - 1))
308 : : /* Cannot be tied. */
309 : : return false;
310 : 6330271 : rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
311 : 6330271 : mode = ALLOCNO_MODE (a);
312 : 6330271 : aclass = ALLOCNO_CLASS (a);
313 : 6330271 : if (only_regs_p && insn != NULL_RTX
314 : 6270420 : && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
315 : : /* It is already taken into account in ira-costs.cc. */
316 : : return false;
317 : 377004 : index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
318 : 377004 : if (index < 0)
319 : : /* Cannot be tied. It is not in the allocno class. */
320 : : return false;
321 : 365372 : ira_init_register_move_cost_if_necessary (mode);
322 : 365372 : if (HARD_REGISTER_P (reg1))
323 : 166725 : move_cost = ira_register_move_cost[mode][aclass][rclass];
324 : : else
325 : 198647 : move_cost = ira_register_move_cost[mode][rclass][aclass];
326 : :
327 : 365372 : if (!single_input_op_has_cstr_p)
328 : : {
329 : : /* When this is a constraint copy and the matching constraint
330 : : doesn't only exist for this given operand but also for some
331 : : other operand(s), it means saving the possible move cost does
332 : : NOT need to require reg1 and reg2 to use the same hardware
333 : : register, so this hardware preference isn't required to be
334 : : fixed. To avoid it to over prefer this hardware register,
335 : : and over disparage this hardware register on conflicted
336 : : objects, we need some cost tweaking here, similar to what
337 : : we do for shuffle copy. */
338 : 0 : gcc_assert (constraint_p);
339 : 0 : int reduced_freq = get_freq_for_shuffle_copy (freq);
340 : 0 : if (HARD_REGISTER_P (reg1))
341 : : /* For reg2 = opcode(reg1, reg3 ...), assume that reg3 is a
342 : : pseudo register which has matching constraint on reg2,
343 : : even if reg2 isn't assigned by reg1, it's still possible
344 : : not to have register moves if reg2 and reg3 use the same
345 : : hardware register. So to avoid the allocation to over
346 : : prefer reg1, we can just take it as a shuffle copy. */
347 : 0 : cost = conflict_cost = move_cost * reduced_freq;
348 : : else
349 : : {
350 : : /* For reg1 = opcode(reg2, reg3 ...), assume that reg3 is a
351 : : pseudo register which has matching constraint on reg2,
352 : : to save the register move, it's better to assign reg1
353 : : to either of reg2 and reg3 (or one of other pseudos like
354 : : reg3), it's reasonable to use freq for the cost. But
355 : : for conflict_cost, since reg2 and reg3 conflicts with
356 : : each other, both of them has the chance to be assigned
357 : : by reg1, assume reg3 has one copy which also conflicts
358 : : with reg2, we shouldn't make it less preferred on reg1
359 : : since reg3 has the same chance to be assigned by reg1.
360 : : So it adjusts the conflic_cost to make it same as what
361 : : we use for shuffle copy. */
362 : 0 : cost = move_cost * freq;
363 : 0 : conflict_cost = move_cost * reduced_freq;
364 : : }
365 : : }
366 : : else
367 : 365372 : cost = conflict_cost = move_cost * freq;
368 : :
369 : 408144 : do
370 : : {
371 : 408144 : ira_allocate_and_set_costs
372 : 408144 : (&ALLOCNO_HARD_REG_COSTS (a), aclass,
373 : : ALLOCNO_CLASS_COST (a));
374 : 408144 : ira_allocate_and_set_costs
375 : 408144 : (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
376 : 408144 : ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
377 : 408144 : ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= conflict_cost;
378 : 408144 : if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
379 : 363975 : ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
380 : 408144 : ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
381 : 408144 : a = ira_parent_or_cap_allocno (a);
382 : : }
383 : 408144 : while (a != NULL);
384 : : return true;
385 : : }
386 : :
387 : : /* Return true if output operand OUTPUT and input operand INPUT of
388 : : INSN can use the same register class for at least one alternative.
389 : : INSN is already described in recog_data and recog_op_alt. */
390 : : static bool
391 : 2645441 : can_use_same_reg_p (rtx_insn *insn, int output, int input)
392 : : {
393 : 2645441 : alternative_mask preferred = get_preferred_alternatives (insn);
394 : 3824069 : for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
395 : : {
396 : 3604018 : if (!TEST_BIT (preferred, nalt))
397 : 798656 : continue;
398 : :
399 : 2805362 : const operand_alternative *op_alt
400 : 2805362 : = &recog_op_alt[nalt * recog_data.n_operands];
401 : 2805362 : if (op_alt[input].matches == output)
402 : : return true;
403 : :
404 : 1749287 : if (op_alt[output].earlyclobber)
405 : 64440 : continue;
406 : :
407 : 1684847 : if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
408 : : != NO_REGS)
409 : : return true;
410 : : }
411 : : return false;
412 : : }
413 : :
414 : : /* Process all of the output registers of the current insn (INSN) which
415 : : are not bound (BOUND_P) and the input register REG (its operand number
416 : : OP_NUM) which dies in the insn as if there were a move insn between
417 : : them with frequency FREQ. */
418 : : static void
419 : 11546485 : process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
420 : : bool *bound_p)
421 : : {
422 : 11546485 : int i;
423 : 11546485 : rtx another_reg;
424 : :
425 : 11546485 : gcc_assert (REG_SUBREG_P (reg));
426 : 41495302 : for (i = 0; i < recog_data.n_operands; i++)
427 : : {
428 : 29948817 : another_reg = recog_data.operand[i];
429 : :
430 : 29948817 : if (!REG_SUBREG_P (another_reg) || op_num == i
431 : 10177403 : || recog_data.operand_type[i] != OP_OUT
432 : 5659870 : || bound_p[i]
433 : 32568751 : || (!can_use_same_reg_p (insn, i, op_num)
434 : 203742 : && (recog_data.constraints[op_num][0] != '%'
435 : 14719 : || !can_use_same_reg_p (insn, i, op_num + 1))
436 : 194544 : && (op_num == 0
437 : 194544 : || recog_data.constraints[op_num - 1][0] != '%'
438 : 10788 : || !can_use_same_reg_p (insn, i, op_num - 1))))
439 : 27523427 : continue;
440 : :
441 : 2425390 : process_regs_for_copy (reg, another_reg, false, NULL, freq);
442 : : }
443 : 11546485 : }
444 : :
445 : : /* Process INSN and create allocno copies if necessary. For example,
446 : : it might be because INSN is a pseudo-register move or INSN is two
447 : : operand insn. */
448 : : static void
449 : 59278560 : add_insn_allocno_copies (rtx_insn *insn)
450 : : {
451 : 59278560 : rtx set = single_set (insn), operand, dup;
452 : 59278560 : bool bound_p[MAX_RECOG_OPERANDS];
453 : 59278560 : int i, n, freq;
454 : 59278560 : alternative_mask alts;
455 : :
456 : 59278560 : freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
457 : 49231924 : if (freq == 0)
458 : 7948648 : freq = 1;
459 : :
460 : : /* Tie output register operands of two consecutive single_sets
461 : : marked as a fused pair. */
462 : 59278560 : if (single_output_fused_pair_p (insn))
463 : 0 : process_regs_for_copy (SET_DEST (set),
464 : 0 : SET_DEST (single_set (prev_nonnote_nondebug_insn (insn))),
465 : : true, NULL, freq);
466 : :
467 : 0 : if (set != NULL_RTX
468 : 55379390 : && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
469 : 9900833 : && ! side_effects_p (set)
470 : 69179393 : && find_reg_note (insn, REG_DEAD,
471 : 9900833 : REG_P (SET_SRC (set))
472 : : ? SET_SRC (set)
473 : : : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
474 : : {
475 : 7596325 : process_regs_for_copy (SET_SRC (set), SET_DEST (set),
476 : : false, insn, freq);
477 : 46780607 : return;
478 : : }
479 : : /* Fast check of possibility of constraint or shuffle copies. If
480 : : there are no dead registers, there will be no such copies. */
481 : 51682235 : if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
482 : : return;
483 : 20094278 : alts = ira_setup_alts (insn);
484 : 87136219 : for (i = 0; i < recog_data.n_operands; i++)
485 : 46947663 : bound_p[i] = false;
486 : 67041941 : for (i = 0; i < recog_data.n_operands; i++)
487 : : {
488 : 46947663 : operand = recog_data.operand[i];
489 : 46947663 : if (! REG_SUBREG_P (operand))
490 : 26328607 : continue;
491 : 20619056 : bool single_input_op_has_cstr_p;
492 : 20619056 : if ((n = ira_get_dup_out_num (i, alts, single_input_op_has_cstr_p)) >= 0)
493 : : {
494 : 3069686 : bound_p[n] = true;
495 : 3069686 : dup = recog_data.operand[n];
496 : 137713 : if (REG_SUBREG_P (dup)
497 : 6124471 : && find_reg_note (insn, REG_DEAD,
498 : 3054785 : REG_P (operand)
499 : : ? operand
500 : : : SUBREG_REG (operand)) != NULL_RTX)
501 : 2520457 : process_regs_for_copy (operand, dup, true, NULL, freq,
502 : : single_input_op_has_cstr_p);
503 : : }
504 : : }
505 : 67041941 : for (i = 0; i < recog_data.n_operands; i++)
506 : : {
507 : 46947663 : operand = recog_data.operand[i];
508 : 27140550 : if (REG_SUBREG_P (operand)
509 : 47759606 : && find_reg_note (insn, REG_DEAD,
510 : : REG_P (operand)
511 : : ? operand : SUBREG_REG (operand)) != NULL_RTX)
512 : : {
513 : : /* If an operand dies, prefer its hard register for the output
514 : : operands by decreasing the hard register cost or creating
515 : : the corresponding allocno copies. The cost will not
516 : : correspond to a real move insn cost, so make the frequency
517 : : smaller. */
518 : 11546485 : int new_freq = get_freq_for_shuffle_copy (freq);
519 : 11546485 : process_reg_shuffles (insn, operand, i, new_freq, bound_p);
520 : : }
521 : : }
522 : : }
523 : :
524 : : /* Add copies originated from BB given by LOOP_TREE_NODE. */
525 : : static void
526 : 12377549 : add_copies (ira_loop_tree_node_t loop_tree_node)
527 : : {
528 : 12377549 : basic_block bb;
529 : 12377549 : rtx_insn *insn;
530 : :
531 : 12377549 : bb = loop_tree_node->bb;
532 : 12377549 : if (bb == NULL)
533 : : return;
534 : 141449500 : FOR_BB_INSNS (bb, insn)
535 : 130282714 : if (NONDEBUG_INSN_P (insn))
536 : 59278560 : add_insn_allocno_copies (insn);
537 : : }
538 : :
539 : : /* Propagate copies the corresponding allocnos on upper loop tree
540 : : level. */
541 : : static void
542 : 999616 : propagate_copies (void)
543 : : {
544 : 999616 : ira_copy_t cp;
545 : 999616 : ira_copy_iterator ci;
546 : 999616 : ira_allocno_t a1, a2, parent_a1, parent_a2;
547 : :
548 : 8147929 : FOR_EACH_COPY (cp, ci)
549 : : {
550 : 7148313 : a1 = cp->first;
551 : 7148313 : a2 = cp->second;
552 : 7148313 : if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
553 : 5417175 : continue;
554 : 1731138 : ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
555 : 1731138 : parent_a1 = ira_parent_or_cap_allocno (a1);
556 : 1731138 : parent_a2 = ira_parent_or_cap_allocno (a2);
557 : 1731138 : ira_assert (parent_a1 != NULL && parent_a2 != NULL);
558 : 1731138 : if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
559 : 1730820 : ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
560 : 1730820 : cp->constraint_p, cp->insn, cp->loop_tree_node);
561 : : }
562 : 999616 : }
563 : :
564 : : /* Array used to collect all conflict allocnos for given allocno. */
565 : : static ira_object_t *collected_conflict_objects;
566 : :
567 : : /* Build conflict vectors or bit conflict vectors (whatever is more
568 : : profitable) for object OBJ from the conflict table. */
569 : : static void
570 : 25729238 : build_object_conflicts (ira_object_t obj)
571 : : {
572 : 25729238 : int i, px, parent_num;
573 : 25729238 : ira_allocno_t parent_a, another_parent_a;
574 : 25729238 : ira_object_t parent_obj;
575 : 25729238 : ira_allocno_t a = OBJECT_ALLOCNO (obj);
576 : 25729238 : IRA_INT_TYPE *object_conflicts;
577 : 25729238 : minmax_set_iterator asi;
578 : 25729238 : int parent_min, parent_max ATTRIBUTE_UNUSED;
579 : :
580 : 25729238 : object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
581 : 25729238 : px = 0;
582 : 631117872 : FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
583 : : OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
584 : : {
585 : 579659396 : ira_object_t another_obj = ira_object_id_map[i];
586 : 579659396 : ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
587 : :
588 : 579659396 : ira_assert (ira_reg_classes_intersect_p
589 : : [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
590 : 579659396 : collected_conflict_objects[px++] = another_obj;
591 : : }
592 : 25729238 : if (ira_conflict_vector_profitable_p (obj, px))
593 : : {
594 : 5185149 : ira_object_t *vec;
595 : 5185149 : ira_allocate_conflict_vec (obj, px);
596 : 5185149 : vec = OBJECT_CONFLICT_VEC (obj);
597 : 5185149 : memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
598 : 5185149 : vec[px] = NULL;
599 : 5185149 : OBJECT_NUM_CONFLICTS (obj) = px;
600 : : }
601 : : else
602 : : {
603 : 20544089 : int conflict_bit_vec_words_num;
604 : :
605 : 20544089 : OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
606 : 20544089 : if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
607 : : conflict_bit_vec_words_num = 0;
608 : : else
609 : 19642591 : conflict_bit_vec_words_num
610 : 19642591 : = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
611 : : / IRA_INT_BITS);
612 : 20544089 : OBJECT_CONFLICT_ARRAY_SIZE (obj)
613 : 20544089 : = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
614 : : }
615 : :
616 : 25729238 : parent_a = ira_parent_or_cap_allocno (a);
617 : 25729238 : if (parent_a == NULL)
618 : 18906475 : return;
619 : 6822763 : ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
620 : 6822763 : ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
621 : 6822763 : parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
622 : 6822763 : parent_num = OBJECT_CONFLICT_ID (parent_obj);
623 : 6822763 : parent_min = OBJECT_MIN (parent_obj);
624 : 6822763 : parent_max = OBJECT_MAX (parent_obj);
625 : 338531852 : FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
626 : : OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
627 : : {
628 : 324886326 : ira_object_t another_obj = ira_object_id_map[i];
629 : 324886326 : ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
630 : 324886326 : int another_word = OBJECT_SUBWORD (another_obj);
631 : :
632 : 324886326 : ira_assert (ira_reg_classes_intersect_p
633 : : [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
634 : :
635 : 324886326 : another_parent_a = ira_parent_or_cap_allocno (another_a);
636 : 324886326 : if (another_parent_a == NULL)
637 : 0 : continue;
638 : 324886326 : ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
639 : 324886326 : ira_assert (ALLOCNO_CLASS (another_a)
640 : : == ALLOCNO_CLASS (another_parent_a));
641 : 324886326 : ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
642 : : == ALLOCNO_NUM_OBJECTS (another_parent_a));
643 : 324886326 : SET_MINMAX_SET_BIT (conflicts[parent_num],
644 : : OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
645 : : another_word)),
646 : : parent_min, parent_max);
647 : : }
648 : : }
649 : :
650 : : /* Build conflict vectors or bit conflict vectors (whatever is more
651 : : profitable) of all allocnos from the conflict table. */
652 : : static void
653 : 1044976 : build_conflicts (void)
654 : : {
655 : 1044976 : int i;
656 : 1044976 : ira_allocno_t a, cap;
657 : :
658 : 1044976 : collected_conflict_objects
659 : 2089952 : = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
660 : 1044976 : * ira_objects_num);
661 : 52009684 : for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
662 : 50964708 : for (a = ira_regno_allocno_map[i];
663 : 72572869 : a != NULL;
664 : 21608161 : a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
665 : : {
666 : 21608161 : int j, nregs = ALLOCNO_NUM_OBJECTS (a);
667 : 43668496 : for (j = 0; j < nregs; j++)
668 : : {
669 : 22060335 : ira_object_t obj = ALLOCNO_OBJECT (a, j);
670 : 22060335 : build_object_conflicts (obj);
671 : 25729238 : for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
672 : : {
673 : 3668903 : ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
674 : 3668903 : gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
675 : 3668903 : build_object_conflicts (cap_obj);
676 : : }
677 : : }
678 : : }
679 : 1044976 : ira_free (collected_conflict_objects);
680 : 1044976 : }
681 : :
682 : :
683 : :
684 : : /* Print hard reg set SET with TITLE to FILE. */
685 : : static void
686 : 844 : print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
687 : : {
688 : 844 : int i, start, end;
689 : :
690 : 844 : fputs (title, file);
691 : 78492 : for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
692 : : {
693 : 77648 : bool reg_included = TEST_HARD_REG_BIT (set, i);
694 : :
695 : 77648 : if (reg_included)
696 : : {
697 : 782 : if (start == -1)
698 : 450 : start = i;
699 : : end = i;
700 : : }
701 : 77648 : if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
702 : : {
703 : 450 : if (start == end)
704 : 142 : fprintf (file, " %d", start);
705 : 308 : else if (start == end + 1)
706 : 0 : fprintf (file, " %d %d", start, end);
707 : : else
708 : 308 : fprintf (file, " %d-%d", start, end);
709 : : start = -1;
710 : : }
711 : : }
712 : 844 : putc ('\n', file);
713 : 844 : }
714 : :
715 : : static void
716 : 449 : print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
717 : : {
718 : 449 : HARD_REG_SET conflicting_hard_regs;
719 : 449 : basic_block bb;
720 : 449 : int n, i;
721 : :
722 : 449 : if (reg_p)
723 : 0 : fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
724 : : else
725 : : {
726 : 449 : fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
727 : 449 : if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
728 : 0 : fprintf (file, "b%d", bb->index);
729 : : else
730 : 449 : fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
731 : 449 : putc (')', file);
732 : : }
733 : :
734 : 449 : fputs (" conflicts:", file);
735 : 449 : n = ALLOCNO_NUM_OBJECTS (a);
736 : 898 : for (i = 0; i < n; i++)
737 : : {
738 : 449 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
739 : 449 : ira_object_t conflict_obj;
740 : 449 : ira_object_conflict_iterator oci;
741 : :
742 : 449 : if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
743 : : {
744 : 27 : fprintf (file, "\n;; total conflict hard regs:\n");
745 : 27 : fprintf (file, ";; conflict hard regs:\n\n");
746 : 27 : continue;
747 : : }
748 : :
749 : 422 : if (n > 1)
750 : 0 : fprintf (file, "\n;; subobject %d:", i);
751 : 3582 : FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
752 : : {
753 : 3160 : ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
754 : 3160 : if (reg_p)
755 : 0 : fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
756 : : else
757 : : {
758 : 3160 : fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
759 : : ALLOCNO_REGNO (conflict_a));
760 : 3160 : if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
761 : 0 : fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
762 : 3160 : if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
763 : 0 : fprintf (file, ",b%d", bb->index);
764 : : else
765 : 3160 : fprintf (file, ",l%d",
766 : : ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
767 : 3160 : putc (')', file);
768 : : }
769 : : }
770 : 422 : conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
771 : 422 : & ~ira_no_alloc_regs
772 : 422 : & reg_class_contents[ALLOCNO_CLASS (a)]);
773 : 422 : print_hard_reg_set (file, "\n;; total conflict hard regs:",
774 : : conflicting_hard_regs);
775 : :
776 : 422 : conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj)
777 : 422 : & ~ira_no_alloc_regs
778 : 422 : & reg_class_contents[ALLOCNO_CLASS (a)]);
779 : 422 : print_hard_reg_set (file, ";; conflict hard regs:",
780 : : conflicting_hard_regs);
781 : 422 : putc ('\n', file);
782 : : }
783 : :
784 : 449 : }
785 : :
786 : : /* Print information about allocno or only regno (if REG_P) conflicts
787 : : to FILE. */
788 : : static void
789 : 39 : print_conflicts (FILE *file, bool reg_p)
790 : : {
791 : 39 : ira_allocno_t a;
792 : 39 : ira_allocno_iterator ai;
793 : :
794 : 488 : FOR_EACH_ALLOCNO (a, ai)
795 : 449 : print_allocno_conflicts (file, reg_p, a);
796 : 39 : putc ('\n', file);
797 : 39 : }
798 : :
799 : : /* Print information about allocno or only regno (if REG_P) conflicts
800 : : to stderr. */
801 : : void
802 : 0 : ira_debug_conflicts (bool reg_p)
803 : : {
804 : 0 : print_conflicts (stderr, reg_p);
805 : 0 : }
806 : :
807 : :
808 : :
809 : : /* Entry function which builds allocno conflicts and allocno copies
810 : : and accumulate some allocno info on upper level regions. */
811 : : void
812 : 1481332 : ira_build_conflicts (void)
813 : : {
814 : 1481332 : enum reg_class base;
815 : 1481332 : ira_allocno_t a;
816 : 1481332 : ira_allocno_iterator ai;
817 : 1481332 : HARD_REG_SET temp_hard_reg_set;
818 : :
819 : 1481332 : if (ira_conflicts_p)
820 : : {
821 : 1044976 : ira_conflicts_p = build_conflict_bit_table ();
822 : 1044976 : if (ira_conflicts_p)
823 : : {
824 : 1044976 : ira_object_t obj;
825 : 1044976 : ira_object_iterator oi;
826 : :
827 : 1044976 : build_conflicts ();
828 : 1044976 : ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
829 : : /* We need finished conflict table for the subsequent call. */
830 : 1044976 : if (flag_ira_region == IRA_REGION_ALL
831 : 1044976 : || flag_ira_region == IRA_REGION_MIXED)
832 : 999616 : propagate_copies ();
833 : :
834 : : /* Now we can free memory for the conflict table (see function
835 : : build_object_conflicts for details). */
836 : 27819190 : FOR_EACH_OBJECT (obj, oi)
837 : : {
838 : 25729238 : if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
839 : 5185149 : ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
840 : : }
841 : 1044976 : ira_free (conflicts);
842 : : }
843 : : }
844 : 1481332 : base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
845 : 1481332 : if (! targetm.class_likely_spilled_p (base))
846 : 1481332 : CLEAR_HARD_REG_SET (temp_hard_reg_set);
847 : : else
848 : 0 : temp_hard_reg_set = reg_class_contents[base] & ~ira_no_alloc_regs;
849 : 38116748 : FOR_EACH_ALLOCNO (a, ai)
850 : : {
851 : 36635416 : int i, n = ALLOCNO_NUM_OBJECTS (a);
852 : :
853 : 74589094 : for (i = 0; i < n; i++)
854 : : {
855 : 37953678 : ira_object_t obj = ALLOCNO_OBJECT (a, i);
856 : 37953678 : rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
857 : :
858 : : /* For debugging purposes don't put user defined variables in
859 : : callee-clobbered registers. However, do allow parameters
860 : : in callee-clobbered registers to improve debugging. This
861 : : is a bit of a fragile hack. */
862 : 37953678 : if (optimize == 0
863 : 12224440 : && REG_USERVAR_P (allocno_reg)
864 : 37964586 : && ! reg_is_parm_p (allocno_reg))
865 : : {
866 : 10783 : HARD_REG_SET new_conflict_regs = crtl->abi->full_reg_clobbers ();
867 : 43132 : OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
868 : 10783 : OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
869 : : }
870 : :
871 : 37953678 : if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
872 : : {
873 : 4028217 : HARD_REG_SET new_conflict_regs = ira_need_caller_save_regs (a);
874 : 4028217 : if (flag_caller_saves)
875 : 7243646 : new_conflict_regs &= (~savable_regs | temp_hard_reg_set);
876 : 16112868 : OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
877 : 4028217 : OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
878 : : }
879 : :
880 : : /* Now we deal with paradoxical subreg cases where certain registers
881 : : cannot be accessed in the widest mode. */
882 : 37953678 : machine_mode outer_mode = ALLOCNO_WMODE (a);
883 : 37953678 : machine_mode inner_mode = ALLOCNO_MODE (a);
884 : 37953678 : if (paradoxical_subreg_p (outer_mode, inner_mode))
885 : : {
886 : 639958 : enum reg_class aclass = ALLOCNO_CLASS (a);
887 : 7099405 : for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
888 : : {
889 : 6459447 : int inner_regno = ira_class_hard_regs[aclass][j];
890 : 6459447 : int outer_regno = simplify_subreg_regno (inner_regno,
891 : : inner_mode, 0,
892 : : outer_mode);
893 : 6459447 : if (outer_regno < 0
894 : 6459447 : || !in_hard_reg_set_p (reg_class_contents[aclass],
895 : : outer_mode, outer_regno))
896 : : {
897 : 3191 : SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
898 : : inner_regno);
899 : 3191 : SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
900 : : inner_regno);
901 : : }
902 : : }
903 : : }
904 : : }
905 : : }
906 : 1481332 : if (optimize && ira_conflicts_p
907 : 1044976 : && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
908 : 39 : print_conflicts (ira_dump_file, false);
909 : 1481332 : }
|