]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ira-conflicts.c
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / ira-conflicts.c
CommitLineData
058e97ec 1/* IRA conflict builder.
8d9254fc 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
058e97ec
VM
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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"
c7131fb2 24#include "backend.h"
957060b5 25#include "target.h"
058e97ec 26#include "rtl.h"
957060b5 27#include "predict.h"
4d0cdd0c 28#include "memmodel.h"
058e97ec 29#include "tm_p.h"
058e97ec 30#include "insn-config.h"
957060b5
AM
31#include "regs.h"
32#include "ira.h"
33#include "ira-int.h"
058e97ec 34#include "sparseset.h"
9c7c70ee 35#include "addresses.h"
058e97ec
VM
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
ac0ab4f7 45 corresponding allocnos see function build_object_conflicts. */
058e97ec
VM
46static IRA_INT_TYPE **conflicts;
47
a49ae217 48/* Macro to test a conflict of C1 and C2 in `conflicts'. */
ac0ab4f7 49#define OBJECTS_CONFLICT_P(C1, C2) \
a49ae217
BS
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)))
058e97ec
VM
55
56\f
ac0ab4f7
BS
57/* Record a conflict between objects OBJ1 and OBJ2. If necessary,
58 canonicalize the conflict by recording it for lower-order subobjects
2b9c63a2 59 of the corresponding allocnos. */
ac0ab4f7
BS
60static void
61record_object_conflict (ira_object_t obj1, ira_object_t obj2)
62{
63 ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
64 ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
65 int w1 = OBJECT_SUBWORD (obj1);
66 int w2 = OBJECT_SUBWORD (obj2);
67 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 if (w1 == w2 && w1 > 0)
74 {
75 obj1 = ALLOCNO_OBJECT (a1, 0);
76 obj2 = ALLOCNO_OBJECT (a2, 0);
77 }
78 id1 = OBJECT_CONFLICT_ID (obj1);
79 id2 = OBJECT_CONFLICT_ID (obj2);
80
81 SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
82 OBJECT_MAX (obj1));
83 SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
84 OBJECT_MAX (obj2));
85}
86
311aab06
VM
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. */
90static bool
058e97ec
VM
91build_conflict_bit_table (void)
92{
a49ae217 93 int i;
058e97ec 94 unsigned int j;
1756cb66 95 enum reg_class aclass;
a49ae217 96 int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
b14151b5 97 live_range_t r;
a49ae217 98 ira_allocno_t allocno;
058e97ec 99 ira_allocno_iterator ai;
a49ae217 100 sparseset objects_live;
ac0ab4f7
BS
101 ira_object_t obj;
102 ira_allocno_object_iterator aoi;
058e97ec 103
311aab06
VM
104 allocated_words_num = 0;
105 FOR_EACH_ALLOCNO (allocno, ai)
ac0ab4f7
BS
106 FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
107 {
108 if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
311aab06 109 continue;
ac0ab4f7
BS
110 conflict_bit_vec_words_num
111 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
112 / IRA_INT_BITS);
113 allocated_words_num += conflict_bit_vec_words_num;
a9243bfc 114 if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
028d4092 115 > (uint64_t) param_ira_max_conflict_table_size * 1024 * 1024)
ac0ab4f7
BS
116 {
117 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
118 fprintf
119 (ira_dump_file,
120 "+++Conflict table will be too big(>%dMB) -- don't use it\n",
028d4092 121 param_ira_max_conflict_table_size);
ac0ab4f7
BS
122 return false;
123 }
124 }
a49ae217 125
058e97ec 126 conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
a49ae217 127 * ira_objects_num);
058e97ec
VM
128 allocated_words_num = 0;
129 FOR_EACH_ALLOCNO (allocno, ai)
ac0ab4f7
BS
130 FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
131 {
132 int id = OBJECT_CONFLICT_ID (obj);
133 if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
134 {
135 conflicts[id] = NULL;
136 continue;
137 }
138 conflict_bit_vec_words_num
139 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
140 / IRA_INT_BITS);
141 allocated_words_num += conflict_bit_vec_words_num;
142 conflicts[id]
143 = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
144 * conflict_bit_vec_words_num);
145 memset (conflicts[id], 0,
146 sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
147 }
a49ae217
BS
148
149 object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
058e97ec
VM
150 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
151 fprintf
152 (ira_dump_file,
153 "+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
154 (long) allocated_words_num * sizeof (IRA_INT_TYPE),
a49ae217
BS
155 (long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));
156
157 objects_live = sparseset_alloc (ira_objects_num);
058e97ec
VM
158 for (i = 0; i < ira_max_point; i++)
159 {
160 for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
161 {
9140d27b
BS
162 ira_object_t obj = r->object;
163 ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
a49ae217
BS
164 int id = OBJECT_CONFLICT_ID (obj);
165
ac0ab4f7
BS
166 gcc_assert (id < ira_objects_num);
167
1756cb66 168 aclass = ALLOCNO_CLASS (allocno);
a49ae217 169 EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
058e97ec 170 {
ac0ab4f7
BS
171 ira_object_t live_obj = ira_object_id_map[j];
172 ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
1756cb66 173 enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
a49ae217 174
1756cb66 175 if (ira_reg_classes_intersect_p[aclass][live_aclass]
058e97ec 176 /* Don't set up conflict for the allocno with itself. */
ac0ab4f7 177 && live_a != allocno)
058e97ec 178 {
ac0ab4f7 179 record_object_conflict (obj, live_obj);
058e97ec
VM
180 }
181 }
60408d8b 182 sparseset_set_bit (objects_live, id);
058e97ec 183 }
b8698a0f 184
058e97ec 185 for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
ac0ab4f7 186 sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
058e97ec 187 }
a49ae217 188 sparseset_free (objects_live);
311aab06 189 return true;
058e97ec 190}
058e97ec 191\f
a49ae217
BS
192/* Return true iff allocnos A1 and A2 cannot be allocated to the same
193 register due to conflicts. */
194
195static bool
ac0ab4f7 196allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
a49ae217 197{
ac0ab4f7
BS
198 /* Due to the fact that we canonicalize conflicts (see
199 record_object_conflict), we only need to test for conflicts of
200 the lowest order words. */
201 ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
202 ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
1756cb66 203
a49ae217
BS
204 return OBJECTS_CONFLICT_P (obj1, obj2);
205}
058e97ec 206
a7f32992
VM
207/* Check that X is REG or SUBREG of REG. */
208#define REG_SUBREG_P(x) \
209 (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
210
211/* Return X if X is a REG, otherwise it should be SUBREG of REG and
212 the function returns the reg in this case. *OFFSET will be set to
213 0 in the first case or the regno offset in the first case. */
214static rtx
215go_through_subreg (rtx x, int *offset)
216{
217 rtx reg;
218
219 *offset = 0;
220 if (REG_P (x))
221 return x;
222 ira_assert (GET_CODE (x) == SUBREG);
223 reg = SUBREG_REG (x);
224 ira_assert (REG_P (reg));
225 if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
226 *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
227 SUBREG_BYTE (x), GET_MODE (x));
91914e56
RS
228 else if (!can_div_trunc_p (SUBREG_BYTE (x),
229 REGMODE_NATURAL_SIZE (GET_MODE (x)), offset))
230 /* Checked by validate_subreg. We must know at compile time which
231 inner hard registers are being accessed. */
232 gcc_unreachable ();
a7f32992
VM
233 return reg;
234}
235
058e97ec
VM
236/* Process registers REG1 and REG2 in move INSN with execution
237 frequency FREQ. The function also processes the registers in a
238 potential move insn (INSN == NULL in this case) with frequency
239 FREQ. The function can modify hard register costs of the
240 corresponding allocnos or create a copy involving the corresponding
241 allocnos. The function does nothing if the both registers are hard
242 registers. When nothing is changed, the function returns
243 FALSE. */
244static bool
548a6322 245process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
070a1983 246 rtx_insn *insn, int freq)
058e97ec 247{
496071ca 248 int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
a7f32992 249 bool only_regs_p;
058e97ec 250 ira_allocno_t a;
a8c44c52 251 reg_class_t rclass, aclass;
ef4bddc2 252 machine_mode mode;
058e97ec
VM
253 ira_copy_t cp;
254
a7f32992
VM
255 gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
256 only_regs_p = REG_P (reg1) && REG_P (reg2);
257 reg1 = go_through_subreg (reg1, &offset1);
258 reg2 = go_through_subreg (reg2, &offset2);
496071ca
VM
259 /* Set up hard regno preferenced by allocno. If allocno gets the
260 hard regno the copy (or potential move) insn will be removed. */
058e97ec
VM
261 if (HARD_REGISTER_P (reg1))
262 {
263 if (HARD_REGISTER_P (reg2))
264 return false;
496071ca 265 allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
058e97ec
VM
266 a = ira_curr_regno_allocno_map[REGNO (reg2)];
267 }
268 else if (HARD_REGISTER_P (reg2))
269 {
496071ca 270 allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
058e97ec
VM
271 a = ira_curr_regno_allocno_map[REGNO (reg1)];
272 }
a49ae217 273 else
058e97ec 274 {
a49ae217
BS
275 ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
276 ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
2608d841 277
ac0ab4f7 278 if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
a49ae217
BS
279 {
280 cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
281 ira_curr_loop_tree_node);
282 bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
283 return true;
284 }
285 else
286 return false;
058e97ec 287 }
a49ae217 288
1756cb66
VM
289 if (! IN_RANGE (allocno_preferenced_hard_regno,
290 0, FIRST_PSEUDO_REGISTER - 1))
67914693 291 /* Cannot be tied. */
496071ca
VM
292 return false;
293 rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
058e97ec 294 mode = ALLOCNO_MODE (a);
1756cb66 295 aclass = ALLOCNO_CLASS (a);
4cda38d5 296 if (only_regs_p && insn != NULL_RTX
a8c44c52 297 && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
058e97ec
VM
298 /* It is already taken into account in ira-costs.c. */
299 return false;
1756cb66 300 index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
058e97ec 301 if (index < 0)
67914693 302 /* Cannot be tied. It is not in the allocno class. */
058e97ec 303 return false;
1756cb66 304 ira_init_register_move_cost_if_necessary (mode);
058e97ec 305 if (HARD_REGISTER_P (reg1))
1756cb66 306 cost = ira_register_move_cost[mode][aclass][rclass] * freq;
058e97ec 307 else
1756cb66 308 cost = ira_register_move_cost[mode][rclass][aclass] * freq;
029da7d4 309 do
cb1ca6ac
VM
310 {
311 ira_allocate_and_set_costs
1756cb66
VM
312 (&ALLOCNO_HARD_REG_COSTS (a), aclass,
313 ALLOCNO_CLASS_COST (a));
cb1ca6ac 314 ira_allocate_and_set_costs
1756cb66 315 (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
cb1ca6ac
VM
316 ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
317 ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
1756cb66
VM
318 if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
319 ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
3b6d1699 320 ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
029da7d4 321 a = ira_parent_or_cap_allocno (a);
cb1ca6ac 322 }
029da7d4 323 while (a != NULL);
058e97ec
VM
324 return true;
325}
326
9f635bd1
RS
327/* Return true if output operand OUTPUT and input operand INPUT of
328 INSN can use the same register class for at least one alternative.
329 INSN is already described in recog_data and recog_op_alt. */
330static bool
331can_use_same_reg_p (rtx_insn *insn, int output, int input)
332{
333 alternative_mask preferred = get_preferred_alternatives (insn);
334 for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
335 {
336 if (!TEST_BIT (preferred, nalt))
337 continue;
338
339 const operand_alternative *op_alt
340 = &recog_op_alt[nalt * recog_data.n_operands];
341 if (op_alt[input].matches == output)
342 return true;
343
344 if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
345 != NO_REGS)
346 return true;
347 }
348 return false;
349}
350
351/* Process all of the output registers of the current insn (INSN) which
352 are not bound (BOUND_P) and the input register REG (its operand number
b09495c1
VM
353 OP_NUM) which dies in the insn as if there were a move insn between
354 them with frequency FREQ. */
058e97ec 355static void
9f635bd1
RS
356process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
357 bool *bound_p)
058e97ec
VM
358{
359 int i;
360 rtx another_reg;
361
a7f32992 362 gcc_assert (REG_SUBREG_P (reg));
058e97ec
VM
363 for (i = 0; i < recog_data.n_operands; i++)
364 {
365 another_reg = recog_data.operand[i];
b8698a0f 366
a7f32992 367 if (!REG_SUBREG_P (another_reg) || op_num == i
b09495c1 368 || recog_data.operand_type[i] != OP_OUT
9f635bd1
RS
369 || bound_p[i]
370 || (!can_use_same_reg_p (insn, i, op_num)
371 && (recog_data.constraints[op_num][0] != '%'
372 || !can_use_same_reg_p (insn, i, op_num + 1))
373 && (op_num == 0
374 || recog_data.constraints[op_num - 1][0] != '%'
375 || !can_use_same_reg_p (insn, i, op_num - 1))))
058e97ec 376 continue;
b8698a0f 377
070a1983 378 process_regs_for_copy (reg, another_reg, false, NULL, freq);
058e97ec
VM
379 }
380}
381
382/* Process INSN and create allocno copies if necessary. For example,
383 it might be because INSN is a pseudo-register move or INSN is two
384 operand insn. */
385static void
070a1983 386add_insn_allocno_copies (rtx_insn *insn)
058e97ec 387{
56592e03 388 rtx set, operand, dup;
3b6d1699
VM
389 bool bound_p[MAX_RECOG_OPERANDS];
390 int i, n, freq;
73bb8fe9 391 alternative_mask alts;
a49ae217 392
058e97ec
VM
393 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
394 if (freq == 0)
395 freq = 1;
396 if ((set = single_set (insn)) != NULL_RTX
a7f32992 397 && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
058e97ec 398 && ! side_effects_p (set)
a7f32992
VM
399 && find_reg_note (insn, REG_DEAD,
400 REG_P (SET_SRC (set))
401 ? SET_SRC (set)
402 : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
058e97ec 403 {
3b6d1699 404 process_regs_for_copy (SET_SRC (set), SET_DEST (set),
1756cb66 405 false, insn, freq);
b09495c1
VM
406 return;
407 }
56592e03
VM
408 /* Fast check of possibility of constraint or shuffle copies. If
409 there are no dead registers, there will be no such copies. */
410 if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
b09495c1 411 return;
73bb8fe9 412 alts = ira_setup_alts (insn);
b09495c1
VM
413 for (i = 0; i < recog_data.n_operands; i++)
414 bound_p[i] = false;
415 for (i = 0; i < recog_data.n_operands; i++)
416 {
417 operand = recog_data.operand[i];
418 if (! REG_SUBREG_P (operand))
419 continue;
3b6d1699
VM
420 if ((n = ira_get_dup_out_num (i, alts)) >= 0)
421 {
422 bound_p[n] = true;
423 dup = recog_data.operand[n];
424 if (REG_SUBREG_P (dup)
425 && find_reg_note (insn, REG_DEAD,
426 REG_P (operand)
427 ? operand
428 : SUBREG_REG (operand)) != NULL_RTX)
070a1983 429 process_regs_for_copy (operand, dup, true, NULL,
3b6d1699
VM
430 freq);
431 }
b09495c1
VM
432 }
433 for (i = 0; i < recog_data.n_operands; i++)
434 {
435 operand = recog_data.operand[i];
436 if (REG_SUBREG_P (operand)
437 && find_reg_note (insn, REG_DEAD,
438 REG_P (operand)
439 ? operand : SUBREG_REG (operand)) != NULL_RTX)
440 /* If an operand dies, prefer its hard register for the output
441 operands by decreasing the hard register cost or creating
442 the corresponding allocno copies. The cost will not
443 correspond to a real move insn cost, so make the frequency
444 smaller. */
9f635bd1
RS
445 process_reg_shuffles (insn, operand, i, freq < 8 ? 1 : freq / 8,
446 bound_p);
058e97ec
VM
447 }
448}
449
450/* Add copies originated from BB given by LOOP_TREE_NODE. */
451static void
452add_copies (ira_loop_tree_node_t loop_tree_node)
453{
454 basic_block bb;
070a1983 455 rtx_insn *insn;
058e97ec
VM
456
457 bb = loop_tree_node->bb;
458 if (bb == NULL)
459 return;
460 FOR_BB_INSNS (bb, insn)
b5b8b0ac 461 if (NONDEBUG_INSN_P (insn))
058e97ec
VM
462 add_insn_allocno_copies (insn);
463}
464
465/* Propagate copies the corresponding allocnos on upper loop tree
466 level. */
467static void
468propagate_copies (void)
469{
470 ira_copy_t cp;
471 ira_copy_iterator ci;
472 ira_allocno_t a1, a2, parent_a1, parent_a2;
058e97ec
VM
473
474 FOR_EACH_COPY (cp, ci)
475 {
476 a1 = cp->first;
477 a2 = cp->second;
478 if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
479 continue;
480 ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
029da7d4
BS
481 parent_a1 = ira_parent_or_cap_allocno (a1);
482 parent_a2 = ira_parent_or_cap_allocno (a2);
058e97ec 483 ira_assert (parent_a1 != NULL && parent_a2 != NULL);
ac0ab4f7 484 if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
548a6322
VM
485 ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
486 cp->constraint_p, cp->insn, cp->loop_tree_node);
058e97ec
VM
487 }
488}
489
058e97ec 490/* Array used to collect all conflict allocnos for given allocno. */
a49ae217 491static ira_object_t *collected_conflict_objects;
058e97ec
VM
492
493/* Build conflict vectors or bit conflict vectors (whatever is more
ac0ab4f7 494 profitable) for object OBJ from the conflict table. */
058e97ec 495static void
ac0ab4f7 496build_object_conflicts (ira_object_t obj)
058e97ec
VM
497{
498 int i, px, parent_num;
a49ae217 499 ira_allocno_t parent_a, another_parent_a;
ac0ab4f7
BS
500 ira_object_t parent_obj;
501 ira_allocno_t a = OBJECT_ALLOCNO (obj);
502 IRA_INT_TYPE *object_conflicts;
42ce1cc4 503 minmax_set_iterator asi;
5c82436e 504 int parent_min, parent_max ATTRIBUTE_UNUSED;
058e97ec 505
ac0ab4f7 506 object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
058e97ec 507 px = 0;
ac0ab4f7 508 FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
a49ae217 509 OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
058e97ec 510 {
a49ae217
BS
511 ira_object_t another_obj = ira_object_id_map[i];
512 ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
1756cb66 513
7db7ed3c 514 ira_assert (ira_reg_classes_intersect_p
1756cb66 515 [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
a49ae217 516 collected_conflict_objects[px++] = another_obj;
058e97ec 517 }
a49ae217 518 if (ira_conflict_vector_profitable_p (obj, px))
058e97ec 519 {
ac0ab4f7 520 ira_object_t *vec;
a49ae217
BS
521 ira_allocate_conflict_vec (obj, px);
522 vec = OBJECT_CONFLICT_VEC (obj);
523 memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
058e97ec 524 vec[px] = NULL;
a49ae217 525 OBJECT_NUM_CONFLICTS (obj) = px;
058e97ec
VM
526 }
527 else
528 {
ac0ab4f7 529 int conflict_bit_vec_words_num;
1756cb66 530
ac0ab4f7 531 OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
a49ae217 532 if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
058e97ec
VM
533 conflict_bit_vec_words_num = 0;
534 else
535 conflict_bit_vec_words_num
a49ae217 536 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
058e97ec 537 / IRA_INT_BITS);
a49ae217 538 OBJECT_CONFLICT_ARRAY_SIZE (obj)
058e97ec
VM
539 = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
540 }
ac0ab4f7 541
029da7d4
BS
542 parent_a = ira_parent_or_cap_allocno (a);
543 if (parent_a == NULL)
058e97ec 544 return;
1756cb66 545 ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
ac0ab4f7
BS
546 ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
547 parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
a49ae217 548 parent_num = OBJECT_CONFLICT_ID (parent_obj);
1756cb66
VM
549 parent_min = OBJECT_MIN (parent_obj);
550 parent_max = OBJECT_MAX (parent_obj);
ac0ab4f7 551 FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
a49ae217 552 OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
058e97ec 553 {
a49ae217
BS
554 ira_object_t another_obj = ira_object_id_map[i];
555 ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
ac0ab4f7 556 int another_word = OBJECT_SUBWORD (another_obj);
a49ae217 557
7db7ed3c 558 ira_assert (ira_reg_classes_intersect_p
1756cb66 559 [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
ac0ab4f7 560
029da7d4
BS
561 another_parent_a = ira_parent_or_cap_allocno (another_a);
562 if (another_parent_a == NULL)
058e97ec
VM
563 continue;
564 ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
1756cb66
VM
565 ira_assert (ALLOCNO_CLASS (another_a)
566 == ALLOCNO_CLASS (another_parent_a));
ac0ab4f7
BS
567 ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
568 == ALLOCNO_NUM_OBJECTS (another_parent_a));
42ce1cc4 569 SET_MINMAX_SET_BIT (conflicts[parent_num],
ac0ab4f7 570 OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
1756cb66
VM
571 another_word)),
572 parent_min, parent_max);
058e97ec
VM
573 }
574}
575
576/* Build conflict vectors or bit conflict vectors (whatever is more
577 profitable) of all allocnos from the conflict table. */
578static void
579build_conflicts (void)
580{
581 int i;
582 ira_allocno_t a, cap;
583
a49ae217
BS
584 collected_conflict_objects
585 = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
586 * ira_objects_num);
058e97ec
VM
587 for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
588 for (a = ira_regno_allocno_map[i];
589 a != NULL;
590 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
591 {
ac0ab4f7
BS
592 int j, nregs = ALLOCNO_NUM_OBJECTS (a);
593 for (j = 0; j < nregs; j++)
594 {
595 ira_object_t obj = ALLOCNO_OBJECT (a, j);
596 build_object_conflicts (obj);
597 for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
598 {
599 ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
600 gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
601 build_object_conflicts (cap_obj);
602 }
603 }
058e97ec 604 }
a49ae217 605 ira_free (collected_conflict_objects);
058e97ec
VM
606}
607
608\f
609
610/* Print hard reg set SET with TITLE to FILE. */
611static void
612print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
613{
a5e3dd5d 614 int i, start, end;
058e97ec 615
edb30094 616 fputs (title, file);
a5e3dd5d 617 for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
058e97ec 618 {
a5e3dd5d
HPN
619 bool reg_included = TEST_HARD_REG_BIT (set, i);
620
621 if (reg_included)
058e97ec 622 {
a5e3dd5d 623 if (start == -1)
058e97ec 624 start = i;
a5e3dd5d 625 end = i;
058e97ec 626 }
a5e3dd5d 627 if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
058e97ec 628 {
a5e3dd5d 629 if (start == end)
058e97ec 630 fprintf (file, " %d", start);
a5e3dd5d
HPN
631 else if (start == end + 1)
632 fprintf (file, " %d %d", start, end);
058e97ec 633 else
a5e3dd5d 634 fprintf (file, " %d-%d", start, end);
058e97ec
VM
635 start = -1;
636 }
637 }
edb30094 638 putc ('\n', file);
058e97ec
VM
639}
640
058e97ec 641static void
e4f36d31 642print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
058e97ec 643{
058e97ec 644 HARD_REG_SET conflicting_hard_regs;
e4f36d31 645 basic_block bb;
ac0ab4f7 646 int n, i;
058e97ec 647
e4f36d31
JL
648 if (reg_p)
649 fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
650 else
058e97ec 651 {
e4f36d31
JL
652 fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
653 if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
654 fprintf (file, "b%d", bb->index);
058e97ec 655 else
2608d841 656 fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
e4f36d31
JL
657 putc (')', file);
658 }
a49ae217 659
e4f36d31 660 fputs (" conflicts:", file);
ac0ab4f7
BS
661 n = ALLOCNO_NUM_OBJECTS (a);
662 for (i = 0; i < n; i++)
663 {
664 ira_object_t obj = ALLOCNO_OBJECT (a, i);
665 ira_object_t conflict_obj;
666 ira_object_conflict_iterator oci;
667
668 if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
38de8b39
PB
669 {
670 fprintf (file, "\n;; total conflict hard regs:\n");
671 fprintf (file, ";; conflict hard regs:\n\n");
672 continue;
673 }
674
ac0ab4f7
BS
675 if (n > 1)
676 fprintf (file, "\n;; subobject %d:", i);
677 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
678 {
679 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
680 if (reg_p)
681 fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
682 else
683 {
684 fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
685 ALLOCNO_REGNO (conflict_a));
686 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
687 fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
688 if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
689 fprintf (file, ",b%d", bb->index);
690 else
691 fprintf (file, ",l%d",
2608d841 692 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
ac0ab4f7
BS
693 putc (')', file);
694 }
695 }
d15e5131
RS
696 conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
697 & ~ira_no_alloc_regs
698 & reg_class_contents[ALLOCNO_CLASS (a)]);
ac0ab4f7
BS
699 print_hard_reg_set (file, "\n;; total conflict hard regs:",
700 conflicting_hard_regs);
701
d15e5131
RS
702 conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj)
703 & ~ira_no_alloc_regs
704 & reg_class_contents[ALLOCNO_CLASS (a)]);
ac0ab4f7
BS
705 print_hard_reg_set (file, ";; conflict hard regs:",
706 conflicting_hard_regs);
707 putc ('\n', file);
708 }
a49ae217 709
058e97ec
VM
710}
711
e4f36d31
JL
712/* Print information about allocno or only regno (if REG_P) conflicts
713 to FILE. */
714static void
715print_conflicts (FILE *file, bool reg_p)
716{
717 ira_allocno_t a;
718 ira_allocno_iterator ai;
719
720 FOR_EACH_ALLOCNO (a, ai)
721 print_allocno_conflicts (file, reg_p, a);
38de8b39 722 putc ('\n', file);
e4f36d31
JL
723}
724
058e97ec
VM
725/* Print information about allocno or only regno (if REG_P) conflicts
726 to stderr. */
727void
728ira_debug_conflicts (bool reg_p)
729{
730 print_conflicts (stderr, reg_p);
731}
732
733\f
734
735/* Entry function which builds allocno conflicts and allocno copies
736 and accumulate some allocno info on upper level regions. */
737void
738ira_build_conflicts (void)
739{
86fc3d06 740 enum reg_class base;
058e97ec
VM
741 ira_allocno_t a;
742 ira_allocno_iterator ai;
7db7ed3c 743 HARD_REG_SET temp_hard_reg_set;
058e97ec 744
311aab06 745 if (ira_conflicts_p)
058e97ec 746 {
311aab06
VM
747 ira_conflicts_p = build_conflict_bit_table ();
748 if (ira_conflicts_p)
058e97ec 749 {
a49ae217
BS
750 ira_object_t obj;
751 ira_object_iterator oi;
752
311aab06 753 build_conflicts ();
e6a7da82 754 ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
311aab06
VM
755 /* We need finished conflict table for the subsequent call. */
756 if (flag_ira_region == IRA_REGION_ALL
757 || flag_ira_region == IRA_REGION_MIXED)
758 propagate_copies ();
a49ae217 759
311aab06 760 /* Now we can free memory for the conflict table (see function
ac0ab4f7 761 build_object_conflicts for details). */
a49ae217 762 FOR_EACH_OBJECT (obj, oi)
311aab06 763 {
a49ae217
BS
764 if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
765 ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
311aab06
VM
766 }
767 ira_free (conflicts);
058e97ec 768 }
058e97ec 769 }
86fc3d06
UW
770 base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
771 if (! targetm.class_likely_spilled_p (base))
7db7ed3c
VM
772 CLEAR_HARD_REG_SET (temp_hard_reg_set);
773 else
6c476222 774 temp_hard_reg_set = reg_class_contents[base] & ~ira_no_alloc_regs;
058e97ec
VM
775 FOR_EACH_ALLOCNO (a, ai)
776 {
ac0ab4f7 777 int i, n = ALLOCNO_NUM_OBJECTS (a);
1756cb66 778
ac0ab4f7 779 for (i = 0; i < n; i++)
058e97ec 780 {
ac0ab4f7 781 ira_object_t obj = ALLOCNO_OBJECT (a, i);
e6d46b5a 782 rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
ac0ab4f7 783
6c476222
RS
784 /* For debugging purposes don't put user defined variables in
785 callee-clobbered registers. However, do allow parameters
786 in callee-clobbered registers to improve debugging. This
787 is a bit of a fragile hack. */
788 if (optimize == 0
789 && REG_USERVAR_P (allocno_reg)
790 && ! reg_is_parm_p (allocno_reg))
ac0ab4f7 791 {
6c476222
RS
792 HARD_REG_SET new_conflict_regs = crtl->abi->full_reg_clobbers ();
793 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
794 OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
ac0ab4f7 795 }
6c476222
RS
796
797 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
ac0ab4f7 798 {
6c476222
RS
799 HARD_REG_SET new_conflict_regs = ira_need_caller_save_regs (a);
800 if (flag_caller_saves)
801 new_conflict_regs &= (~savable_regs | temp_hard_reg_set);
802 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
803 OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
ac0ab4f7 804 }
0644953e 805
d1bb282e
DS
806 /* Now we deal with paradoxical subreg cases where certain registers
807 cannot be accessed in the widest mode. */
ef4bddc2
RS
808 machine_mode outer_mode = ALLOCNO_WMODE (a);
809 machine_mode inner_mode = ALLOCNO_MODE (a);
03a95621 810 if (paradoxical_subreg_p (outer_mode, inner_mode))
d1bb282e
DS
811 {
812 enum reg_class aclass = ALLOCNO_CLASS (a);
813 for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
814 {
815 int inner_regno = ira_class_hard_regs[aclass][j];
816 int outer_regno = simplify_subreg_regno (inner_regno,
817 inner_mode, 0,
818 outer_mode);
819 if (outer_regno < 0
820 || !in_hard_reg_set_p (reg_class_contents[aclass],
821 outer_mode, outer_regno))
31b61548
VM
822 {
823 SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
824 inner_regno);
825 SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
826 inner_regno);
827 }
d1bb282e
DS
828 }
829 }
058e97ec
VM
830 }
831 }
311aab06
VM
832 if (optimize && ira_conflicts_p
833 && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
058e97ec
VM
834 print_conflicts (ira_dump_file, false);
835}