]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ira-conflicts.c
basic-block.h: Re-group most prototypes per file.
[thirdparty/gcc.git] / gcc / ira-conflicts.c
1 /* IRA conflict builder.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "regs.h"
27 #include "rtl.h"
28 #include "tree.h" /* For DECL_ARTIFICIAL and friends. */
29 #include "tm_p.h"
30 #include "target.h"
31 #include "flags.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "insn-config.h"
35 #include "recog.h"
36 #include "diagnostic-core.h"
37 #include "params.h"
38 #include "df.h"
39 #include "sparseset.h"
40 #include "ira-int.h"
41 #include "addresses.h"
42
43 /* This file contains code responsible for allocno conflict creation,
44 allocno copy creation and allocno info accumulation on upper level
45 regions. */
46
47 /* ira_allocnos_num array of arrays of bits, recording whether two
48 allocno's conflict (can't go in the same hardware register).
49
50 Some arrays will be used as conflict bit vector of the
51 corresponding allocnos see function build_object_conflicts. */
52 static IRA_INT_TYPE **conflicts;
53
54 /* Macro to test a conflict of C1 and C2 in `conflicts'. */
55 #define OBJECTS_CONFLICT_P(C1, C2) \
56 (OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2) \
57 && OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1) \
58 && TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)], \
59 OBJECT_CONFLICT_ID (C2), \
60 OBJECT_MIN (C1), OBJECT_MAX (C1)))
61
62 \f
63 /* Record a conflict between objects OBJ1 and OBJ2. If necessary,
64 canonicalize the conflict by recording it for lower-order subobjects
65 of the corresponding allocnos. */
66 static void
67 record_object_conflict (ira_object_t obj1, ira_object_t obj2)
68 {
69 ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
70 ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
71 int w1 = OBJECT_SUBWORD (obj1);
72 int w2 = OBJECT_SUBWORD (obj2);
73 int id1, id2;
74
75 /* Canonicalize the conflict. If two identically-numbered words
76 conflict, always record this as a conflict between words 0. That
77 is the only information we need, and it is easier to test for if
78 it is collected in each allocno's lowest-order object. */
79 if (w1 == w2 && w1 > 0)
80 {
81 obj1 = ALLOCNO_OBJECT (a1, 0);
82 obj2 = ALLOCNO_OBJECT (a2, 0);
83 }
84 id1 = OBJECT_CONFLICT_ID (obj1);
85 id2 = OBJECT_CONFLICT_ID (obj2);
86
87 SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
88 OBJECT_MAX (obj1));
89 SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
90 OBJECT_MAX (obj2));
91 }
92
93 /* Build allocno conflict table by processing allocno live ranges.
94 Return true if the table was built. The table is not built if it
95 is too big. */
96 static bool
97 build_conflict_bit_table (void)
98 {
99 int i;
100 unsigned int j;
101 enum reg_class aclass;
102 int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
103 live_range_t r;
104 ira_allocno_t allocno;
105 ira_allocno_iterator ai;
106 sparseset objects_live;
107 ira_object_t obj;
108 ira_allocno_object_iterator aoi;
109
110 allocated_words_num = 0;
111 FOR_EACH_ALLOCNO (allocno, ai)
112 FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
113 {
114 if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
115 continue;
116 conflict_bit_vec_words_num
117 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
118 / IRA_INT_BITS);
119 allocated_words_num += conflict_bit_vec_words_num;
120 if ((unsigned HOST_WIDEST_INT) allocated_words_num * sizeof (IRA_INT_TYPE)
121 > (unsigned HOST_WIDEST_INT) IRA_MAX_CONFLICT_TABLE_SIZE * 1024 * 1024)
122 {
123 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
124 fprintf
125 (ira_dump_file,
126 "+++Conflict table will be too big(>%dMB) -- don't use it\n",
127 IRA_MAX_CONFLICT_TABLE_SIZE);
128 return false;
129 }
130 }
131
132 conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
133 * ira_objects_num);
134 allocated_words_num = 0;
135 FOR_EACH_ALLOCNO (allocno, ai)
136 FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
137 {
138 int id = OBJECT_CONFLICT_ID (obj);
139 if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
140 {
141 conflicts[id] = NULL;
142 continue;
143 }
144 conflict_bit_vec_words_num
145 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
146 / IRA_INT_BITS);
147 allocated_words_num += conflict_bit_vec_words_num;
148 conflicts[id]
149 = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
150 * conflict_bit_vec_words_num);
151 memset (conflicts[id], 0,
152 sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
153 }
154
155 object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
156 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
157 fprintf
158 (ira_dump_file,
159 "+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
160 (long) allocated_words_num * sizeof (IRA_INT_TYPE),
161 (long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));
162
163 objects_live = sparseset_alloc (ira_objects_num);
164 for (i = 0; i < ira_max_point; i++)
165 {
166 for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
167 {
168 ira_object_t obj = r->object;
169 ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
170 int id = OBJECT_CONFLICT_ID (obj);
171
172 gcc_assert (id < ira_objects_num);
173
174 aclass = ALLOCNO_CLASS (allocno);
175 sparseset_set_bit (objects_live, id);
176 EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
177 {
178 ira_object_t live_obj = ira_object_id_map[j];
179 ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
180 enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
181
182 if (ira_reg_classes_intersect_p[aclass][live_aclass]
183 /* Don't set up conflict for the allocno with itself. */
184 && live_a != allocno)
185 {
186 record_object_conflict (obj, live_obj);
187 }
188 }
189 }
190
191 for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
192 sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
193 }
194 sparseset_free (objects_live);
195 return true;
196 }
197 \f
198 /* Return true iff allocnos A1 and A2 cannot be allocated to the same
199 register due to conflicts. */
200
201 static bool
202 allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
203 {
204 /* Due to the fact that we canonicalize conflicts (see
205 record_object_conflict), we only need to test for conflicts of
206 the lowest order words. */
207 ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
208 ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
209
210 return OBJECTS_CONFLICT_P (obj1, obj2);
211 }
212
213 /* Return TRUE if the operand constraint STR is commutative. */
214 static bool
215 commutative_constraint_p (const char *str)
216 {
217 int curr_alt, c;
218 bool ignore_p;
219
220 for (ignore_p = false, curr_alt = 0;;)
221 {
222 c = *str;
223 if (c == '\0')
224 break;
225 str += CONSTRAINT_LEN (c, str);
226 if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
227 ignore_p = true;
228 else if (c == ',')
229 {
230 curr_alt++;
231 ignore_p = false;
232 }
233 else if (! ignore_p)
234 {
235 /* Usually `%' is the first constraint character but the
236 documentation does not require this. */
237 if (c == '%')
238 return true;
239 }
240 }
241 return false;
242 }
243
244 /* Return the number of the operand which should be the same in any
245 case as operand with number OP_NUM (or negative value if there is
246 no such operand). If USE_COMMUT_OP_P is TRUE, the function makes
247 temporarily commutative operand exchange before this. The function
248 takes only really possible alternatives into consideration. */
249 static int
250 get_dup_num (int op_num, bool use_commut_op_p)
251 {
252 int curr_alt, c, original, dup;
253 bool ignore_p, commut_op_used_p;
254 const char *str;
255 rtx op;
256
257 if (op_num < 0 || recog_data.n_alternatives == 0)
258 return -1;
259 op = recog_data.operand[op_num];
260 commut_op_used_p = true;
261 if (use_commut_op_p)
262 {
263 if (commutative_constraint_p (recog_data.constraints[op_num]))
264 op_num++;
265 else if (op_num > 0 && commutative_constraint_p (recog_data.constraints
266 [op_num - 1]))
267 op_num--;
268 else
269 commut_op_used_p = false;
270 }
271 str = recog_data.constraints[op_num];
272 for (ignore_p = false, original = -1, curr_alt = 0;;)
273 {
274 c = *str;
275 if (c == '\0')
276 break;
277 if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
278 ignore_p = true;
279 else if (c == ',')
280 {
281 curr_alt++;
282 ignore_p = false;
283 }
284 else if (! ignore_p)
285 switch (c)
286 {
287 case 'X':
288 return -1;
289
290 case 'm':
291 case 'o':
292 /* Accept a register which might be placed in memory. */
293 return -1;
294 break;
295
296 case 'V':
297 case '<':
298 case '>':
299 break;
300
301 case 'p':
302 if (address_operand (op, VOIDmode))
303 return -1;
304 break;
305
306 case 'g':
307 return -1;
308
309 case 'r':
310 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
311 case 'h': case 'j': case 'k': case 'l':
312 case 'q': case 't': case 'u':
313 case 'v': case 'w': case 'x': case 'y': case 'z':
314 case 'A': case 'B': case 'C': case 'D':
315 case 'Q': case 'R': case 'S': case 'T': case 'U':
316 case 'W': case 'Y': case 'Z':
317 {
318 enum reg_class cl;
319
320 cl = (c == 'r'
321 ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str));
322 if (cl != NO_REGS)
323 return -1;
324 #ifdef EXTRA_CONSTRAINT_STR
325 else if (EXTRA_CONSTRAINT_STR (op, c, str))
326 return -1;
327 #endif
328 break;
329 }
330
331 case '0': case '1': case '2': case '3': case '4':
332 case '5': case '6': case '7': case '8': case '9':
333 if (original != -1 && original != c)
334 return -1;
335 original = c;
336 break;
337 }
338 str += CONSTRAINT_LEN (c, str);
339 }
340 if (original == -1)
341 return -1;
342 dup = original - '0';
343 if (use_commut_op_p)
344 {
345 if (commutative_constraint_p (recog_data.constraints[dup]))
346 dup++;
347 else if (dup > 0
348 && commutative_constraint_p (recog_data.constraints[dup -1]))
349 dup--;
350 else if (! commut_op_used_p)
351 return -1;
352 }
353 return dup;
354 }
355
356 /* Check that X is REG or SUBREG of REG. */
357 #define REG_SUBREG_P(x) \
358 (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
359
360 /* Return X if X is a REG, otherwise it should be SUBREG of REG and
361 the function returns the reg in this case. *OFFSET will be set to
362 0 in the first case or the regno offset in the first case. */
363 static rtx
364 go_through_subreg (rtx x, int *offset)
365 {
366 rtx reg;
367
368 *offset = 0;
369 if (REG_P (x))
370 return x;
371 ira_assert (GET_CODE (x) == SUBREG);
372 reg = SUBREG_REG (x);
373 ira_assert (REG_P (reg));
374 if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
375 *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
376 SUBREG_BYTE (x), GET_MODE (x));
377 else
378 *offset = (SUBREG_BYTE (x) / REGMODE_NATURAL_SIZE (GET_MODE (x)));
379 return reg;
380 }
381
382 /* Process registers REG1 and REG2 in move INSN with execution
383 frequency FREQ. The function also processes the registers in a
384 potential move insn (INSN == NULL in this case) with frequency
385 FREQ. The function can modify hard register costs of the
386 corresponding allocnos or create a copy involving the corresponding
387 allocnos. The function does nothing if the both registers are hard
388 registers. When nothing is changed, the function returns
389 FALSE. */
390 static bool
391 process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
392 rtx insn, int freq)
393 {
394 int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
395 bool only_regs_p;
396 ira_allocno_t a;
397 reg_class_t rclass, aclass;
398 enum machine_mode mode;
399 ira_copy_t cp;
400
401 gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
402 only_regs_p = REG_P (reg1) && REG_P (reg2);
403 reg1 = go_through_subreg (reg1, &offset1);
404 reg2 = go_through_subreg (reg2, &offset2);
405 /* Set up hard regno preferenced by allocno. If allocno gets the
406 hard regno the copy (or potential move) insn will be removed. */
407 if (HARD_REGISTER_P (reg1))
408 {
409 if (HARD_REGISTER_P (reg2))
410 return false;
411 allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
412 a = ira_curr_regno_allocno_map[REGNO (reg2)];
413 }
414 else if (HARD_REGISTER_P (reg2))
415 {
416 allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
417 a = ira_curr_regno_allocno_map[REGNO (reg1)];
418 }
419 else
420 {
421 ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
422 ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
423
424 if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
425 {
426 cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
427 ira_curr_loop_tree_node);
428 bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
429 return true;
430 }
431 else
432 return false;
433 }
434
435 if (! IN_RANGE (allocno_preferenced_hard_regno,
436 0, FIRST_PSEUDO_REGISTER - 1))
437 /* Can not be tied. */
438 return false;
439 rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
440 mode = ALLOCNO_MODE (a);
441 aclass = ALLOCNO_CLASS (a);
442 if (only_regs_p && insn != NULL_RTX
443 && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
444 /* It is already taken into account in ira-costs.c. */
445 return false;
446 index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
447 if (index < 0)
448 /* Can not be tied. It is not in the allocno class. */
449 return false;
450 ira_init_register_move_cost_if_necessary (mode);
451 if (HARD_REGISTER_P (reg1))
452 cost = ira_register_move_cost[mode][aclass][rclass] * freq;
453 else
454 cost = ira_register_move_cost[mode][rclass][aclass] * freq;
455 do
456 {
457 ira_allocate_and_set_costs
458 (&ALLOCNO_HARD_REG_COSTS (a), aclass,
459 ALLOCNO_CLASS_COST (a));
460 ira_allocate_and_set_costs
461 (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
462 ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
463 ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
464 if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
465 ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
466 a = ira_parent_or_cap_allocno (a);
467 }
468 while (a != NULL);
469 return true;
470 }
471
472 /* Process all of the output registers of the current insn which are
473 not bound (BOUND_P) and the input register REG (its operand number
474 OP_NUM) which dies in the insn as if there were a move insn between
475 them with frequency FREQ. */
476 static void
477 process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
478 {
479 int i;
480 rtx another_reg;
481
482 gcc_assert (REG_SUBREG_P (reg));
483 for (i = 0; i < recog_data.n_operands; i++)
484 {
485 another_reg = recog_data.operand[i];
486
487 if (!REG_SUBREG_P (another_reg) || op_num == i
488 || recog_data.operand_type[i] != OP_OUT
489 || bound_p[i])
490 continue;
491
492 process_regs_for_copy (reg, another_reg, false, NULL_RTX, freq);
493 }
494 }
495
496 /* Process INSN and create allocno copies if necessary. For example,
497 it might be because INSN is a pseudo-register move or INSN is two
498 operand insn. */
499 static void
500 add_insn_allocno_copies (rtx insn)
501 {
502 rtx set, operand, dup;
503 const char *str;
504 bool commut_p, bound_p[MAX_RECOG_OPERANDS];
505 int i, j, n, freq;
506
507 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
508 if (freq == 0)
509 freq = 1;
510 if ((set = single_set (insn)) != NULL_RTX
511 && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
512 && ! side_effects_p (set)
513 && find_reg_note (insn, REG_DEAD,
514 REG_P (SET_SRC (set))
515 ? SET_SRC (set)
516 : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
517 {
518 process_regs_for_copy (SET_DEST (set), SET_SRC (set),
519 false, insn, freq);
520 return;
521 }
522 /* Fast check of possibility of constraint or shuffle copies. If
523 there are no dead registers, there will be no such copies. */
524 if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
525 return;
526 extract_insn (insn);
527 for (i = 0; i < recog_data.n_operands; i++)
528 bound_p[i] = false;
529 for (i = 0; i < recog_data.n_operands; i++)
530 {
531 operand = recog_data.operand[i];
532 if (! REG_SUBREG_P (operand))
533 continue;
534 str = recog_data.constraints[i];
535 while (*str == ' ' || *str == '\t')
536 str++;
537 for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
538 if ((n = get_dup_num (i, commut_p)) >= 0)
539 {
540 bound_p[n] = true;
541 dup = recog_data.operand[n];
542 if (REG_SUBREG_P (dup)
543 && find_reg_note (insn, REG_DEAD,
544 REG_P (operand)
545 ? operand
546 : SUBREG_REG (operand)) != NULL_RTX)
547 process_regs_for_copy (operand, dup, true, NULL_RTX, freq);
548 }
549 }
550 for (i = 0; i < recog_data.n_operands; i++)
551 {
552 operand = recog_data.operand[i];
553 if (REG_SUBREG_P (operand)
554 && find_reg_note (insn, REG_DEAD,
555 REG_P (operand)
556 ? operand : SUBREG_REG (operand)) != NULL_RTX)
557 /* If an operand dies, prefer its hard register for the output
558 operands by decreasing the hard register cost or creating
559 the corresponding allocno copies. The cost will not
560 correspond to a real move insn cost, so make the frequency
561 smaller. */
562 process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
563 }
564 }
565
566 /* Add copies originated from BB given by LOOP_TREE_NODE. */
567 static void
568 add_copies (ira_loop_tree_node_t loop_tree_node)
569 {
570 basic_block bb;
571 rtx insn;
572
573 bb = loop_tree_node->bb;
574 if (bb == NULL)
575 return;
576 FOR_BB_INSNS (bb, insn)
577 if (NONDEBUG_INSN_P (insn))
578 add_insn_allocno_copies (insn);
579 }
580
581 /* Propagate copies the corresponding allocnos on upper loop tree
582 level. */
583 static void
584 propagate_copies (void)
585 {
586 ira_copy_t cp;
587 ira_copy_iterator ci;
588 ira_allocno_t a1, a2, parent_a1, parent_a2;
589
590 FOR_EACH_COPY (cp, ci)
591 {
592 a1 = cp->first;
593 a2 = cp->second;
594 if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
595 continue;
596 ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
597 parent_a1 = ira_parent_or_cap_allocno (a1);
598 parent_a2 = ira_parent_or_cap_allocno (a2);
599 ira_assert (parent_a1 != NULL && parent_a2 != NULL);
600 if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
601 ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
602 cp->constraint_p, cp->insn, cp->loop_tree_node);
603 }
604 }
605
606 /* Array used to collect all conflict allocnos for given allocno. */
607 static ira_object_t *collected_conflict_objects;
608
609 /* Build conflict vectors or bit conflict vectors (whatever is more
610 profitable) for object OBJ from the conflict table. */
611 static void
612 build_object_conflicts (ira_object_t obj)
613 {
614 int i, px, parent_num;
615 ira_allocno_t parent_a, another_parent_a;
616 ira_object_t parent_obj;
617 ira_allocno_t a = OBJECT_ALLOCNO (obj);
618 IRA_INT_TYPE *object_conflicts;
619 minmax_set_iterator asi;
620 int parent_min, parent_max ATTRIBUTE_UNUSED;
621
622 object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
623 px = 0;
624 FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
625 OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
626 {
627 ira_object_t another_obj = ira_object_id_map[i];
628 ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
629
630 ira_assert (ira_reg_classes_intersect_p
631 [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
632 collected_conflict_objects[px++] = another_obj;
633 }
634 if (ira_conflict_vector_profitable_p (obj, px))
635 {
636 ira_object_t *vec;
637 ira_allocate_conflict_vec (obj, px);
638 vec = OBJECT_CONFLICT_VEC (obj);
639 memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
640 vec[px] = NULL;
641 OBJECT_NUM_CONFLICTS (obj) = px;
642 }
643 else
644 {
645 int conflict_bit_vec_words_num;
646
647 OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
648 if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
649 conflict_bit_vec_words_num = 0;
650 else
651 conflict_bit_vec_words_num
652 = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
653 / IRA_INT_BITS);
654 OBJECT_CONFLICT_ARRAY_SIZE (obj)
655 = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
656 }
657
658 parent_a = ira_parent_or_cap_allocno (a);
659 if (parent_a == NULL)
660 return;
661 ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
662 ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
663 parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
664 parent_num = OBJECT_CONFLICT_ID (parent_obj);
665 parent_min = OBJECT_MIN (parent_obj);
666 parent_max = OBJECT_MAX (parent_obj);
667 FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
668 OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
669 {
670 ira_object_t another_obj = ira_object_id_map[i];
671 ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
672 int another_word = OBJECT_SUBWORD (another_obj);
673
674 ira_assert (ira_reg_classes_intersect_p
675 [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
676
677 another_parent_a = ira_parent_or_cap_allocno (another_a);
678 if (another_parent_a == NULL)
679 continue;
680 ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
681 ira_assert (ALLOCNO_CLASS (another_a)
682 == ALLOCNO_CLASS (another_parent_a));
683 ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
684 == ALLOCNO_NUM_OBJECTS (another_parent_a));
685 SET_MINMAX_SET_BIT (conflicts[parent_num],
686 OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
687 another_word)),
688 parent_min, parent_max);
689 }
690 }
691
692 /* Build conflict vectors or bit conflict vectors (whatever is more
693 profitable) of all allocnos from the conflict table. */
694 static void
695 build_conflicts (void)
696 {
697 int i;
698 ira_allocno_t a, cap;
699
700 collected_conflict_objects
701 = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
702 * ira_objects_num);
703 for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
704 for (a = ira_regno_allocno_map[i];
705 a != NULL;
706 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
707 {
708 int j, nregs = ALLOCNO_NUM_OBJECTS (a);
709 for (j = 0; j < nregs; j++)
710 {
711 ira_object_t obj = ALLOCNO_OBJECT (a, j);
712 build_object_conflicts (obj);
713 for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
714 {
715 ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
716 gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
717 build_object_conflicts (cap_obj);
718 }
719 }
720 }
721 ira_free (collected_conflict_objects);
722 }
723
724 \f
725
726 /* Print hard reg set SET with TITLE to FILE. */
727 static void
728 print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
729 {
730 int i, start;
731
732 fputs (title, file);
733 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
734 {
735 if (TEST_HARD_REG_BIT (set, i))
736 {
737 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
738 start = i;
739 }
740 if (start >= 0
741 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
742 {
743 if (start == i - 1)
744 fprintf (file, " %d", start);
745 else if (start == i - 2)
746 fprintf (file, " %d %d", start, start + 1);
747 else
748 fprintf (file, " %d-%d", start, i - 1);
749 start = -1;
750 }
751 }
752 putc ('\n', file);
753 }
754
755 static void
756 print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
757 {
758 HARD_REG_SET conflicting_hard_regs;
759 basic_block bb;
760 int n, i;
761
762 if (reg_p)
763 fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
764 else
765 {
766 fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
767 if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
768 fprintf (file, "b%d", bb->index);
769 else
770 fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
771 putc (')', file);
772 }
773
774 fputs (" conflicts:", file);
775 n = ALLOCNO_NUM_OBJECTS (a);
776 for (i = 0; i < n; i++)
777 {
778 ira_object_t obj = ALLOCNO_OBJECT (a, i);
779 ira_object_t conflict_obj;
780 ira_object_conflict_iterator oci;
781
782 if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
783 continue;
784 if (n > 1)
785 fprintf (file, "\n;; subobject %d:", i);
786 FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
787 {
788 ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
789 if (reg_p)
790 fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
791 else
792 {
793 fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
794 ALLOCNO_REGNO (conflict_a));
795 if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
796 fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
797 if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
798 fprintf (file, ",b%d", bb->index);
799 else
800 fprintf (file, ",l%d",
801 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
802 putc (')', file);
803 }
804 }
805 COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
806 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
807 AND_HARD_REG_SET (conflicting_hard_regs,
808 reg_class_contents[ALLOCNO_CLASS (a)]);
809 print_hard_reg_set (file, "\n;; total conflict hard regs:",
810 conflicting_hard_regs);
811
812 COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj));
813 AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
814 AND_HARD_REG_SET (conflicting_hard_regs,
815 reg_class_contents[ALLOCNO_CLASS (a)]);
816 print_hard_reg_set (file, ";; conflict hard regs:",
817 conflicting_hard_regs);
818 putc ('\n', file);
819 }
820
821 }
822
823 /* Print information about allocno or only regno (if REG_P) conflicts
824 to FILE. */
825 static void
826 print_conflicts (FILE *file, bool reg_p)
827 {
828 ira_allocno_t a;
829 ira_allocno_iterator ai;
830
831 FOR_EACH_ALLOCNO (a, ai)
832 print_allocno_conflicts (file, reg_p, a);
833 }
834
835 /* Print information about allocno or only regno (if REG_P) conflicts
836 to stderr. */
837 void
838 ira_debug_conflicts (bool reg_p)
839 {
840 print_conflicts (stderr, reg_p);
841 }
842
843 \f
844
845 /* Entry function which builds allocno conflicts and allocno copies
846 and accumulate some allocno info on upper level regions. */
847 void
848 ira_build_conflicts (void)
849 {
850 enum reg_class base;
851 ira_allocno_t a;
852 ira_allocno_iterator ai;
853 HARD_REG_SET temp_hard_reg_set;
854
855 if (ira_conflicts_p)
856 {
857 ira_conflicts_p = build_conflict_bit_table ();
858 if (ira_conflicts_p)
859 {
860 ira_object_t obj;
861 ira_object_iterator oi;
862
863 build_conflicts ();
864 ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, add_copies);
865 /* We need finished conflict table for the subsequent call. */
866 if (flag_ira_region == IRA_REGION_ALL
867 || flag_ira_region == IRA_REGION_MIXED)
868 propagate_copies ();
869
870 /* Now we can free memory for the conflict table (see function
871 build_object_conflicts for details). */
872 FOR_EACH_OBJECT (obj, oi)
873 {
874 if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
875 ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
876 }
877 ira_free (conflicts);
878 }
879 }
880 base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
881 if (! targetm.class_likely_spilled_p (base))
882 CLEAR_HARD_REG_SET (temp_hard_reg_set);
883 else
884 {
885 COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]);
886 AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
887 AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
888 }
889 FOR_EACH_ALLOCNO (a, ai)
890 {
891 int i, n = ALLOCNO_NUM_OBJECTS (a);
892
893 for (i = 0; i < n; i++)
894 {
895 ira_object_t obj = ALLOCNO_OBJECT (a, i);
896 reg_attrs *attrs = REG_ATTRS (regno_reg_rtx [ALLOCNO_REGNO (a)]);
897 tree decl;
898
899 if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
900 /* For debugging purposes don't put user defined variables in
901 callee-clobbered registers. */
902 || (optimize == 0
903 && attrs != NULL
904 && (decl = attrs->decl) != NULL
905 && VAR_OR_FUNCTION_DECL_P (decl)
906 && ! DECL_ARTIFICIAL (decl)))
907 {
908 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
909 call_used_reg_set);
910 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
911 call_used_reg_set);
912 }
913 else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
914 {
915 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
916 no_caller_save_reg_set);
917 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
918 temp_hard_reg_set);
919 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
920 no_caller_save_reg_set);
921 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
922 temp_hard_reg_set);
923 }
924
925 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
926 {
927 int regno;
928
929 /* Allocnos bigger than the saved part of call saved
930 regs must conflict with them. */
931 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
932 if (!TEST_HARD_REG_BIT (call_used_reg_set, regno)
933 && HARD_REGNO_CALL_PART_CLOBBERED (regno,
934 obj->allocno->mode))
935 {
936 SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
937 SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
938 regno);
939 }
940 }
941 }
942 }
943 if (optimize && ira_conflicts_p
944 && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
945 print_conflicts (ira_dump_file, false);
946 }