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