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