]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ira-emit.c
Update Copyright years for files modified in 2011 and/or 2012.
[thirdparty/gcc.git] / gcc / ira-emit.c
CommitLineData
47dd2e78 1/* Integrated Register Allocator. Changing code and generating moves.
71e45bc2 2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
47dd2e78 3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
66d9a7b9 22/* When we have more one region, we need to change the original RTL
23 code after coloring. Let us consider two allocnos representing the
24 same pseudo-register outside and inside a region respectively.
25 They can get different hard-registers. The reload pass works on
26 pseudo registers basis and there is no way to say the reload that
27 pseudo could be in different registers and it is even more
28 difficult to say in what places of the code the pseudo should have
29 particular hard-registers. So in this case IRA has to create and
30 use a new pseudo-register inside the region and adds code to move
31 allocno values on the region's borders. This is done by the code
32 in this file.
33
34 The code makes top-down traversal of the regions and generate new
35 pseudos and the move code on the region borders. In some
36 complicated cases IRA can create a new pseudo used temporarily to
37 move allocno values when a swap of values stored in two
38 hard-registers is needed (e.g. two allocnos representing different
39 pseudos outside region got respectively hard registers 1 and 2 and
40 the corresponding allocnos inside the region got respectively hard
41 registers 2 and 1). At this stage, the new pseudo is marked as
42 spilled.
43
44 IRA still creates the pseudo-register and the moves on the region
45 borders even when the both corresponding allocnos were assigned to
46 the same hard-register. It is done because, if the reload pass for
47 some reason spills a pseudo-register representing the original
48 pseudo outside or inside the region, the effect will be smaller
49 because another pseudo will still be in the hard-register. In most
50 cases, this is better then spilling the original pseudo in its
51 whole live-range. If reload does not change the allocation for the
52 two pseudo-registers, the trivial move will be removed by
53 post-reload optimizations.
54
55 IRA does not generate a new pseudo and moves for the allocno values
56 if the both allocnos representing an original pseudo inside and
57 outside region assigned to the same hard register when the register
58 pressure in the region for the corresponding pressure class is less
59 than number of available hard registers for given pressure class.
60
61 IRA also does some optimizations to remove redundant moves which is
62 transformed into stores by the reload pass on CFG edges
63 representing exits from the region.
64
65 IRA tries to reduce duplication of code generated on CFG edges
66 which are enters and exits to/from regions by moving some code to
67 the edge sources or destinations when it is possible. */
47dd2e78 68
69#include "config.h"
70#include "system.h"
71#include "coretypes.h"
72#include "tm.h"
73#include "regs.h"
74#include "rtl.h"
75#include "tm_p.h"
76#include "target.h"
77#include "flags.h"
78#include "obstack.h"
79#include "bitmap.h"
80#include "hard-reg-set.h"
81#include "basic-block.h"
82#include "expr.h"
83#include "recog.h"
84#include "params.h"
47dd2e78 85#include "reload.h"
47dd2e78 86#include "df.h"
87#include "ira-int.h"
88
89
66d9a7b9 90/* Data used to emit live range split insns and to flattening IR. */
91ira_emit_data_t ira_allocno_emit_data;
92
93/* Definitions for vectors of pointers. */
94typedef void *void_p;
66d9a7b9 95
96/* Pointers to data allocated for allocnos being created during
97 emitting. Usually there are quite few such allocnos because they
98 are created only for resolving loop in register shuffling. */
f1f41a6c 99static vec<void_p> new_allocno_emit_data_vec;
66d9a7b9 100
101/* Allocate and initiate the emit data. */
102void
103ira_initiate_emit_data (void)
104{
105 ira_allocno_t a;
106 ira_allocno_iterator ai;
107
108 ira_allocno_emit_data
109 = (ira_emit_data_t) ira_allocate (ira_allocnos_num
110 * sizeof (struct ira_emit_data));
111 memset (ira_allocno_emit_data, 0,
112 ira_allocnos_num * sizeof (struct ira_emit_data));
113 FOR_EACH_ALLOCNO (a, ai)
114 ALLOCNO_ADD_DATA (a) = ira_allocno_emit_data + ALLOCNO_NUM (a);
f1f41a6c 115 new_allocno_emit_data_vec.create (50);
66d9a7b9 116
117}
118
119/* Free the emit data. */
120void
121ira_finish_emit_data (void)
122{
123 void_p p;
124 ira_allocno_t a;
125 ira_allocno_iterator ai;
126
127 ira_free (ira_allocno_emit_data);
128 FOR_EACH_ALLOCNO (a, ai)
129 ALLOCNO_ADD_DATA (a) = NULL;
f1f41a6c 130 for (;new_allocno_emit_data_vec.length () != 0;)
66d9a7b9 131 {
f1f41a6c 132 p = new_allocno_emit_data_vec.pop ();
66d9a7b9 133 ira_free (p);
134 }
f1f41a6c 135 new_allocno_emit_data_vec.release ();
66d9a7b9 136}
137
138/* Create and return a new allocno with given REGNO and
139 LOOP_TREE_NODE. Allocate emit data for it. */
140static ira_allocno_t
141create_new_allocno (int regno, ira_loop_tree_node_t loop_tree_node)
142{
143 ira_allocno_t a;
144
145 a = ira_create_allocno (regno, false, loop_tree_node);
146 ALLOCNO_ADD_DATA (a) = ira_allocate (sizeof (struct ira_emit_data));
147 memset (ALLOCNO_ADD_DATA (a), 0, sizeof (struct ira_emit_data));
f1f41a6c 148 new_allocno_emit_data_vec.safe_push (ALLOCNO_ADD_DATA (a));
66d9a7b9 149 return a;
150}
151
152\f
153
154/* See comments below. */
47dd2e78 155typedef struct move *move_t;
156
157/* The structure represents an allocno move. Both allocnos have the
9d75589a 158 same original regno but different allocation. */
47dd2e78 159struct move
160{
161 /* The allocnos involved in the move. */
162 ira_allocno_t from, to;
163 /* The next move in the move sequence. */
164 move_t next;
165 /* Used for finding dependencies. */
166 bool visited_p;
167 /* The size of the following array. */
168 int deps_num;
169 /* Moves on which given move depends on. Dependency can be cyclic.
170 It means we need a temporary to generates the moves. Sequence
171 A1->A2, B1->B2 where A1 and B2 are assigned to reg R1 and A2 and
172 B1 are assigned to reg R2 is an example of the cyclic
173 dependencies. */
174 move_t *deps;
175 /* First insn generated for the move. */
176 rtx insn;
177};
178
179/* Array of moves (indexed by BB index) which should be put at the
180 start/end of the corresponding basic blocks. */
181static move_t *at_bb_start, *at_bb_end;
182
183/* Max regno before renaming some pseudo-registers. For example, the
184 same pseudo-register can be renamed in a loop if its allocation is
185 different outside the loop. */
186static int max_regno_before_changing;
187
188/* Return new move of allocnos TO and FROM. */
189static move_t
190create_move (ira_allocno_t to, ira_allocno_t from)
191{
192 move_t move;
193
194 move = (move_t) ira_allocate (sizeof (struct move));
195 move->deps = NULL;
196 move->deps_num = 0;
197 move->to = to;
198 move->from = from;
199 move->next = NULL;
200 move->insn = NULL_RTX;
201 move->visited_p = false;
202 return move;
203}
204
205/* Free memory for MOVE and its dependencies. */
206static void
207free_move (move_t move)
208{
209 if (move->deps != NULL)
210 ira_free (move->deps);
211 ira_free (move);
212}
213
214/* Free memory for list of the moves given by its HEAD. */
215static void
216free_move_list (move_t head)
217{
218 move_t next;
48e1416a 219
47dd2e78 220 for (; head != NULL; head = next)
221 {
222 next = head->next;
223 free_move (head);
224 }
225}
226
851d9296 227/* Return TRUE if the move list LIST1 and LIST2 are equal (two
47dd2e78 228 moves are equal if they involve the same allocnos). */
229static bool
230eq_move_lists_p (move_t list1, move_t list2)
231{
232 for (; list1 != NULL && list2 != NULL;
233 list1 = list1->next, list2 = list2->next)
234 if (list1->from != list2->from || list1->to != list2->to)
235 return false;
236 return list1 == list2;
237}
238
0c42b4f4 239/* Print move list LIST into file F. */
240static void
241print_move_list (FILE *f, move_t list)
242{
243 for (; list != NULL; list = list->next)
244 fprintf (f, " a%dr%d->a%dr%d",
245 ALLOCNO_NUM (list->from), ALLOCNO_REGNO (list->from),
246 ALLOCNO_NUM (list->to), ALLOCNO_REGNO (list->to));
247 fprintf (f, "\n");
248}
249
250extern void ira_debug_move_list (move_t list);
251
252/* Print move list LIST into stderr. */
253void
254ira_debug_move_list (move_t list)
255{
256 print_move_list (stderr, list);
257}
258
47dd2e78 259/* This recursive function changes pseudo-registers in *LOC if it is
260 necessary. The function returns TRUE if a change was done. */
261static bool
262change_regs (rtx *loc)
263{
264 int i, regno, result = false;
265 const char *fmt;
266 enum rtx_code code;
2fdae035 267 rtx reg;
47dd2e78 268
269 if (*loc == NULL_RTX)
270 return false;
271 code = GET_CODE (*loc);
272 if (code == REG)
273 {
274 regno = REGNO (*loc);
275 if (regno < FIRST_PSEUDO_REGISTER)
276 return false;
277 if (regno >= max_regno_before_changing)
278 /* It is a shared register which was changed already. */
279 return false;
280 if (ira_curr_regno_allocno_map[regno] == NULL)
281 return false;
66d9a7b9 282 reg = allocno_emit_reg (ira_curr_regno_allocno_map[regno]);
2fdae035 283 if (reg == *loc)
284 return false;
285 *loc = reg;
47dd2e78 286 return true;
287 }
288
289 fmt = GET_RTX_FORMAT (code);
290 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
291 {
292 if (fmt[i] == 'e')
293 result = change_regs (&XEXP (*loc, i)) || result;
294 else if (fmt[i] == 'E')
295 {
296 int j;
297
298 for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
299 result = change_regs (&XVECEXP (*loc, i, j)) || result;
300 }
301 }
302 return result;
303}
304
305/* Attach MOVE to the edge E. The move is attached to the head of the
306 list if HEAD_P is TRUE. */
307static void
308add_to_edge_list (edge e, move_t move, bool head_p)
309{
310 move_t last;
311
312 if (head_p || e->aux == NULL)
313 {
314 move->next = (move_t) e->aux;
315 e->aux = move;
316 }
317 else
318 {
319 for (last = (move_t) e->aux; last->next != NULL; last = last->next)
320 ;
321 last->next = move;
322 move->next = NULL;
323 }
324}
325
326/* Create and return new pseudo-register with the same attributes as
327 ORIGINAL_REG. */
fe9cf48d 328rtx
329ira_create_new_reg (rtx original_reg)
47dd2e78 330{
331 rtx new_reg;
332
333 new_reg = gen_reg_rtx (GET_MODE (original_reg));
334 ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
335 REG_USERVAR_P (new_reg) = REG_USERVAR_P (original_reg);
336 REG_POINTER (new_reg) = REG_POINTER (original_reg);
337 REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
338 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
339 fprintf (ira_dump_file, " Creating newreg=%i from oldreg=%i\n",
340 REGNO (new_reg), REGNO (original_reg));
c6a6cdaa 341 ira_expand_reg_equiv ();
47dd2e78 342 return new_reg;
343}
344
345/* Return TRUE if loop given by SUBNODE inside the loop given by
346 NODE. */
347static bool
348subloop_tree_node_p (ira_loop_tree_node_t subnode, ira_loop_tree_node_t node)
349{
350 for (; subnode != NULL; subnode = subnode->parent)
351 if (subnode == node)
352 return true;
353 return false;
354}
355
356/* Set up member `reg' to REG for allocnos which has the same regno as
357 ALLOCNO and which are inside the loop corresponding to ALLOCNO. */
358static void
359set_allocno_reg (ira_allocno_t allocno, rtx reg)
360{
361 int regno;
362 ira_allocno_t a;
363 ira_loop_tree_node_t node;
364
365 node = ALLOCNO_LOOP_TREE_NODE (allocno);
366 for (a = ira_regno_allocno_map[ALLOCNO_REGNO (allocno)];
367 a != NULL;
368 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
369 if (subloop_tree_node_p (ALLOCNO_LOOP_TREE_NODE (a), node))
66d9a7b9 370 ALLOCNO_EMIT_DATA (a)->reg = reg;
47dd2e78 371 for (a = ALLOCNO_CAP (allocno); a != NULL; a = ALLOCNO_CAP (a))
66d9a7b9 372 ALLOCNO_EMIT_DATA (a)->reg = reg;
47dd2e78 373 regno = ALLOCNO_REGNO (allocno);
374 for (a = allocno;;)
375 {
376 if (a == NULL || (a = ALLOCNO_CAP (a)) == NULL)
377 {
378 node = node->parent;
379 if (node == NULL)
380 break;
381 a = node->regno_allocno_map[regno];
382 }
383 if (a == NULL)
384 continue;
66d9a7b9 385 if (ALLOCNO_EMIT_DATA (a)->child_renamed_p)
47dd2e78 386 break;
66d9a7b9 387 ALLOCNO_EMIT_DATA (a)->child_renamed_p = true;
47dd2e78 388 }
389}
390
0b1329df 391/* Return true if there is an entry to given loop not from its parent
392 (or grandparent) block. For example, it is possible for two
393 adjacent loops inside another loop. */
47dd2e78 394static bool
0b1329df 395entered_from_non_parent_p (ira_loop_tree_node_t loop_node)
396{
397 ira_loop_tree_node_t bb_node, src_loop_node, parent;
398 edge e;
399 edge_iterator ei;
400
66d9a7b9 401 for (bb_node = loop_node->children;
402 bb_node != NULL;
403 bb_node = bb_node->next)
0b1329df 404 if (bb_node->bb != NULL)
405 {
406 FOR_EACH_EDGE (e, ei, bb_node->bb->preds)
407 if (e->src != ENTRY_BLOCK_PTR
408 && (src_loop_node = IRA_BB_NODE (e->src)->parent) != loop_node)
409 {
410 for (parent = src_loop_node->parent;
411 parent != NULL;
412 parent = parent->parent)
413 if (parent == loop_node)
414 break;
415 if (parent != NULL)
416 /* That is an exit from a nested loop -- skip it. */
417 continue;
418 for (parent = loop_node->parent;
419 parent != NULL;
420 parent = parent->parent)
421 if (src_loop_node == parent)
422 break;
423 if (parent == NULL)
424 return true;
425 }
426 }
427 return false;
428}
429
430/* Set up ENTERED_FROM_NON_PARENT_P for each loop region. */
431static void
432setup_entered_from_non_parent_p (void)
433{
434 unsigned int i;
435 loop_p loop;
436
9f8ac546 437 ira_assert (current_loops != NULL);
f1f41a6c 438 FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, i, loop)
0b1329df 439 if (ira_loop_nodes[i].regno_allocno_map != NULL)
440 ira_loop_nodes[i].entered_from_non_parent_p
441 = entered_from_non_parent_p (&ira_loop_nodes[i]);
442}
443
444/* Return TRUE if move of SRC_ALLOCNO (assigned to hard register) to
9d75589a 445 DEST_ALLOCNO (assigned to memory) can be removed because it does
0b1329df 446 not change value of the destination. One possible reason for this
447 is the situation when SRC_ALLOCNO is not modified in the
448 corresponding loop. */
449static bool
450store_can_be_removed_p (ira_allocno_t src_allocno, ira_allocno_t dest_allocno)
47dd2e78 451{
452 int regno, orig_regno;
453 ira_allocno_t a;
454 ira_loop_tree_node_t node;
455
456 ira_assert (ALLOCNO_CAP_MEMBER (src_allocno) == NULL
457 && ALLOCNO_CAP_MEMBER (dest_allocno) == NULL);
458 orig_regno = ALLOCNO_REGNO (src_allocno);
66d9a7b9 459 regno = REGNO (allocno_emit_reg (dest_allocno));
47dd2e78 460 for (node = ALLOCNO_LOOP_TREE_NODE (src_allocno);
461 node != NULL;
462 node = node->parent)
0b1329df 463 {
464 a = node->regno_allocno_map[orig_regno];
465 ira_assert (a != NULL);
66d9a7b9 466 if (REGNO (allocno_emit_reg (a)) == (unsigned) regno)
0b1329df 467 /* We achieved the destination and everything is ok. */
468 return true;
469 else if (bitmap_bit_p (node->modified_regnos, orig_regno))
470 return false;
471 else if (node->entered_from_non_parent_p)
472 /* If there is a path from a destination loop block to the
473 source loop header containing basic blocks of non-parents
474 (grandparents) of the source loop, we should have checked
475 modifications of the pseudo on this path too to decide
476 about possibility to remove the store. It could be done by
477 solving a data-flow problem. Unfortunately such global
478 solution would complicate IR flattening. Therefore we just
479 prohibit removal of the store in such complicated case. */
480 return false;
481 }
588c6733 482 /* It is actually a loop entry -- do not remove the store. */
483 return false;
47dd2e78 484}
485
486/* Generate and attach moves to the edge E. This looks at the final
487 regnos of allocnos living on the edge with the same original regno
488 to figure out when moves should be generated. */
489static void
490generate_edge_moves (edge e)
491{
492 ira_loop_tree_node_t src_loop_node, dest_loop_node;
493 unsigned int regno;
494 bitmap_iterator bi;
495 ira_allocno_t src_allocno, dest_allocno, *src_map, *dest_map;
496 move_t move;
0841d295 497 bitmap regs_live_in_dest, regs_live_out_src;
47dd2e78 498
499 src_loop_node = IRA_BB_NODE (e->src)->parent;
500 dest_loop_node = IRA_BB_NODE (e->dest)->parent;
501 e->aux = NULL;
502 if (src_loop_node == dest_loop_node)
503 return;
504 src_map = src_loop_node->regno_allocno_map;
505 dest_map = dest_loop_node->regno_allocno_map;
0841d295 506 regs_live_in_dest = df_get_live_in (e->dest);
507 regs_live_out_src = df_get_live_out (e->src);
508 EXECUTE_IF_SET_IN_REG_SET (regs_live_in_dest,
47dd2e78 509 FIRST_PSEUDO_REGISTER, regno, bi)
0841d295 510 if (bitmap_bit_p (regs_live_out_src, regno))
47dd2e78 511 {
512 src_allocno = src_map[regno];
513 dest_allocno = dest_map[regno];
66d9a7b9 514 if (REGNO (allocno_emit_reg (src_allocno))
515 == REGNO (allocno_emit_reg (dest_allocno)))
47dd2e78 516 continue;
76b340db 517 /* Remove unnecessary stores at the region exit. We should do
518 this for readonly memory for sure and this is guaranteed by
519 that we never generate moves on region borders (see
c6a6cdaa 520 checking in function change_loop). */
47dd2e78 521 if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
522 && ALLOCNO_HARD_REGNO (src_allocno) >= 0
0b1329df 523 && store_can_be_removed_p (src_allocno, dest_allocno))
47dd2e78 524 {
66d9a7b9 525 ALLOCNO_EMIT_DATA (src_allocno)->mem_optimized_dest = dest_allocno;
526 ALLOCNO_EMIT_DATA (dest_allocno)->mem_optimized_dest_p = true;
47dd2e78 527 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
528 fprintf (ira_dump_file, " Remove r%d:a%d->a%d(mem)\n",
529 regno, ALLOCNO_NUM (src_allocno),
530 ALLOCNO_NUM (dest_allocno));
531 continue;
532 }
533 move = create_move (dest_allocno, src_allocno);
534 add_to_edge_list (e, move, true);
535 }
536}
537
538/* Bitmap of allocnos local for the current loop. */
539static bitmap local_allocno_bitmap;
540
541/* This bitmap is used to find that we need to generate and to use a
542 new pseudo-register when processing allocnos with the same original
543 regno. */
544static bitmap used_regno_bitmap;
545
546/* This bitmap contains regnos of allocnos which were renamed locally
547 because the allocnos correspond to disjoint live ranges in loops
548 with a common parent. */
549static bitmap renamed_regno_bitmap;
550
551/* Change (if necessary) pseudo-registers inside loop given by loop
552 tree node NODE. */
553static void
554change_loop (ira_loop_tree_node_t node)
555{
556 bitmap_iterator bi;
557 unsigned int i;
558 int regno;
559 bool used_p;
560 ira_allocno_t allocno, parent_allocno, *map;
561 rtx insn, original_reg;
66d9a7b9 562 enum reg_class aclass, pclass;
47dd2e78 563 ira_loop_tree_node_t parent;
564
565 if (node != ira_loop_tree_root)
566 {
9f8ac546 567 ira_assert (current_loops != NULL);
568
47dd2e78 569 if (node->bb != NULL)
570 {
571 FOR_BB_INSNS (node->bb, insn)
572 if (INSN_P (insn) && change_regs (&insn))
573 {
574 df_insn_rescan (insn);
575 df_notes_rescan (insn);
576 }
577 return;
578 }
48e1416a 579
47dd2e78 580 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
581 fprintf (ira_dump_file,
582 " Changing RTL for loop %d (header bb%d)\n",
9f8ac546 583 node->loop_num, node->loop->header->index);
48e1416a 584
47dd2e78 585 parent = ira_curr_loop_tree_node->parent;
586 map = parent->regno_allocno_map;
587 EXECUTE_IF_SET_IN_REG_SET (ira_curr_loop_tree_node->border_allocnos,
588 0, i, bi)
589 {
590 allocno = ira_allocnos[i];
591 regno = ALLOCNO_REGNO (allocno);
66d9a7b9 592 aclass = ALLOCNO_CLASS (allocno);
593 pclass = ira_pressure_class_translate[aclass];
47dd2e78 594 parent_allocno = map[regno];
595 ira_assert (regno < ira_reg_equiv_len);
596 /* We generate the same hard register move because the
597 reload pass can put an allocno into memory in this case
598 we will have live range splitting. If it does not happen
599 such the same hard register moves will be removed. The
600 worst case when the both allocnos are put into memory by
601 the reload is very rare. */
602 if (parent_allocno != NULL
603 && (ALLOCNO_HARD_REGNO (allocno)
604 == ALLOCNO_HARD_REGNO (parent_allocno))
605 && (ALLOCNO_HARD_REGNO (allocno) < 0
66d9a7b9 606 || (parent->reg_pressure[pclass] + 1
1072fecf 607 <= ira_class_hard_regs_num[pclass])
47dd2e78 608 || TEST_HARD_REG_BIT (ira_prohibited_mode_move_regs
609 [ALLOCNO_MODE (allocno)],
610 ALLOCNO_HARD_REGNO (allocno))
611 /* don't create copies because reload can spill an
612 allocno set by copy although the allocno will not
613 get memory slot. */
c6a6cdaa 614 || ira_equiv_no_lvalue_p (regno)))
47dd2e78 615 continue;
66d9a7b9 616 original_reg = allocno_emit_reg (allocno);
47dd2e78 617 if (parent_allocno == NULL
66d9a7b9 618 || (REGNO (allocno_emit_reg (parent_allocno))
619 == REGNO (original_reg)))
47dd2e78 620 {
621 if (internal_flag_ira_verbose > 3 && ira_dump_file)
622 fprintf (ira_dump_file, " %i vs parent %i:",
623 ALLOCNO_HARD_REGNO (allocno),
624 ALLOCNO_HARD_REGNO (parent_allocno));
fe9cf48d 625 set_allocno_reg (allocno, ira_create_new_reg (original_reg));
47dd2e78 626 }
627 }
628 }
629 /* Rename locals: Local allocnos with same regno in different loops
630 might get the different hard register. So we need to change
631 ALLOCNO_REG. */
632 bitmap_and_compl (local_allocno_bitmap,
2bae4acc 633 ira_curr_loop_tree_node->all_allocnos,
47dd2e78 634 ira_curr_loop_tree_node->border_allocnos);
635 EXECUTE_IF_SET_IN_REG_SET (local_allocno_bitmap, 0, i, bi)
636 {
637 allocno = ira_allocnos[i];
638 regno = ALLOCNO_REGNO (allocno);
639 if (ALLOCNO_CAP_MEMBER (allocno) != NULL)
640 continue;
6ef9bbe0 641 used_p = !bitmap_set_bit (used_regno_bitmap, regno);
66d9a7b9 642 ALLOCNO_EMIT_DATA (allocno)->somewhere_renamed_p = true;
47dd2e78 643 if (! used_p)
644 continue;
645 bitmap_set_bit (renamed_regno_bitmap, regno);
fe9cf48d 646 set_allocno_reg (allocno, ira_create_new_reg (allocno_emit_reg (allocno)));
47dd2e78 647 }
648}
649
650/* Process to set up flag somewhere_renamed_p. */
651static void
652set_allocno_somewhere_renamed_p (void)
653{
654 unsigned int regno;
655 ira_allocno_t allocno;
656 ira_allocno_iterator ai;
657
658 FOR_EACH_ALLOCNO (allocno, ai)
659 {
660 regno = ALLOCNO_REGNO (allocno);
661 if (bitmap_bit_p (renamed_regno_bitmap, regno)
66d9a7b9 662 && REGNO (allocno_emit_reg (allocno)) == regno)
663 ALLOCNO_EMIT_DATA (allocno)->somewhere_renamed_p = true;
47dd2e78 664 }
665}
666
667/* Return TRUE if move lists on all edges given in vector VEC are
668 equal. */
669static bool
f1f41a6c 670eq_edge_move_lists_p (vec<edge, va_gc> *vec)
47dd2e78 671{
672 move_t list;
673 int i;
674
675 list = (move_t) EDGE_I (vec, 0)->aux;
676 for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
677 if (! eq_move_lists_p (list, (move_t) EDGE_I (vec, i)->aux))
678 return false;
679 return true;
680}
681
682/* Look at all entry edges (if START_P) or exit edges of basic block
683 BB and put move lists at the BB start or end if it is possible. In
684 other words, this decreases code duplication of allocno moves. */
685static void
686unify_moves (basic_block bb, bool start_p)
687{
688 int i;
689 edge e;
690 move_t list;
f1f41a6c 691 vec<edge, va_gc> *vec;
47dd2e78 692
693 vec = (start_p ? bb->preds : bb->succs);
694 if (EDGE_COUNT (vec) == 0 || ! eq_edge_move_lists_p (vec))
695 return;
696 e = EDGE_I (vec, 0);
697 list = (move_t) e->aux;
698 if (! start_p && control_flow_insn_p (BB_END (bb)))
699 return;
700 e->aux = NULL;
701 for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
702 {
703 e = EDGE_I (vec, i);
704 free_move_list ((move_t) e->aux);
705 e->aux = NULL;
706 }
707 if (start_p)
708 at_bb_start[bb->index] = list;
709 else
710 at_bb_end[bb->index] = list;
711}
712
713/* Last move (in move sequence being processed) setting up the
714 corresponding hard register. */
715static move_t hard_regno_last_set[FIRST_PSEUDO_REGISTER];
716
717/* If the element value is equal to CURR_TICK then the corresponding
718 element in `hard_regno_last_set' is defined and correct. */
719static int hard_regno_last_set_check[FIRST_PSEUDO_REGISTER];
720
721/* Last move (in move sequence being processed) setting up the
722 corresponding allocno. */
723static move_t *allocno_last_set;
724
725/* If the element value is equal to CURR_TICK then the corresponding
726 element in . `allocno_last_set' is defined and correct. */
727static int *allocno_last_set_check;
728
729/* Definition of vector of moves. */
47dd2e78 730
731/* This vec contains moves sorted topologically (depth-first) on their
732 dependency graph. */
f1f41a6c 733static vec<move_t> move_vec;
47dd2e78 734
735/* The variable value is used to check correctness of values of
736 elements of arrays `hard_regno_last_set' and
737 `allocno_last_set_check'. */
738static int curr_tick;
739
740/* This recursive function traverses dependencies of MOVE and produces
741 topological sorting (in depth-first order). */
742static void
743traverse_moves (move_t move)
744{
745 int i;
746
747 if (move->visited_p)
748 return;
749 move->visited_p = true;
750 for (i = move->deps_num - 1; i >= 0; i--)
751 traverse_moves (move->deps[i]);
f1f41a6c 752 move_vec.safe_push (move);
47dd2e78 753}
754
755/* Remove unnecessary moves in the LIST, makes topological sorting,
756 and removes cycles on hard reg dependencies by introducing new
757 allocnos assigned to memory and additional moves. It returns the
758 result move list. */
759static move_t
760modify_move_list (move_t list)
761{
762 int i, n, nregs, hard_regno;
ae9587ed 763 ira_allocno_t to, from;
47dd2e78 764 move_t move, new_move, set_move, first, last;
765
766 if (list == NULL)
767 return NULL;
768 /* Creat move deps. */
769 curr_tick++;
770 for (move = list; move != NULL; move = move->next)
771 {
772 to = move->to;
773 if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
774 continue;
775 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
776 for (i = 0; i < nregs; i++)
777 {
778 hard_regno_last_set[hard_regno + i] = move;
779 hard_regno_last_set_check[hard_regno + i] = curr_tick;
780 }
781 }
782 for (move = list; move != NULL; move = move->next)
783 {
784 from = move->from;
785 to = move->to;
786 if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
787 {
788 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
789 for (n = i = 0; i < nregs; i++)
790 if (hard_regno_last_set_check[hard_regno + i] == curr_tick
791 && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
792 != ALLOCNO_REGNO (from)))
793 n++;
794 move->deps = (move_t *) ira_allocate (n * sizeof (move_t));
795 for (n = i = 0; i < nregs; i++)
796 if (hard_regno_last_set_check[hard_regno + i] == curr_tick
797 && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
798 != ALLOCNO_REGNO (from)))
799 move->deps[n++] = hard_regno_last_set[hard_regno + i];
800 move->deps_num = n;
801 }
802 }
803 /* Toplogical sorting: */
f1f41a6c 804 move_vec.truncate (0);
47dd2e78 805 for (move = list; move != NULL; move = move->next)
806 traverse_moves (move);
807 last = NULL;
f1f41a6c 808 for (i = (int) move_vec.length () - 1; i >= 0; i--)
47dd2e78 809 {
f1f41a6c 810 move = move_vec[i];
47dd2e78 811 move->next = NULL;
812 if (last != NULL)
813 last->next = move;
814 last = move;
815 }
f1f41a6c 816 first = move_vec.last ();
47dd2e78 817 /* Removing cycles: */
818 curr_tick++;
f1f41a6c 819 move_vec.truncate (0);
47dd2e78 820 for (move = first; move != NULL; move = move->next)
821 {
822 from = move->from;
823 to = move->to;
824 if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
825 {
826 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
827 for (i = 0; i < nregs; i++)
828 if (hard_regno_last_set_check[hard_regno + i] == curr_tick
829 && ALLOCNO_HARD_REGNO
830 (hard_regno_last_set[hard_regno + i]->to) >= 0)
831 {
be18556f 832 int n, j;
ae9587ed 833 ira_allocno_t new_allocno;
ae9587ed 834
47dd2e78 835 set_move = hard_regno_last_set[hard_regno + i];
836 /* It does not matter what loop_tree_node (of TO or
837 FROM) to use for the new allocno because of
838 subsequent IRA internal representation
839 flattening. */
840 new_allocno
66d9a7b9 841 = create_new_allocno (ALLOCNO_REGNO (set_move->to),
47dd2e78 842 ALLOCNO_LOOP_TREE_NODE (set_move->to));
843 ALLOCNO_MODE (new_allocno) = ALLOCNO_MODE (set_move->to);
66d9a7b9 844 ira_set_allocno_class (new_allocno,
845 ALLOCNO_CLASS (set_move->to));
be18556f 846 ira_create_allocno_objects (new_allocno);
47dd2e78 847 ALLOCNO_ASSIGNED_P (new_allocno) = true;
848 ALLOCNO_HARD_REGNO (new_allocno) = -1;
66d9a7b9 849 ALLOCNO_EMIT_DATA (new_allocno)->reg
fe9cf48d 850 = ira_create_new_reg (allocno_emit_reg (set_move->to));
ae9587ed 851
47dd2e78 852 /* Make it possibly conflicting with all earlier
853 created allocnos. Cases where temporary allocnos
854 created to remove the cycles are quite rare. */
be18556f 855 n = ALLOCNO_NUM_OBJECTS (new_allocno);
856 gcc_assert (n == ALLOCNO_NUM_OBJECTS (set_move->to));
857 for (j = 0; j < n; j++)
858 {
859 ira_object_t new_obj = ALLOCNO_OBJECT (new_allocno, j);
860
861 OBJECT_MIN (new_obj) = 0;
862 OBJECT_MAX (new_obj) = ira_objects_num - 1;
863 }
864
47dd2e78 865 new_move = create_move (set_move->to, new_allocno);
866 set_move->to = new_allocno;
f1f41a6c 867 move_vec.safe_push (new_move);
47dd2e78 868 ira_move_loops_num++;
869 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
870 fprintf (ira_dump_file,
871 " Creating temporary allocno a%dr%d\n",
872 ALLOCNO_NUM (new_allocno),
66d9a7b9 873 REGNO (allocno_emit_reg (new_allocno)));
47dd2e78 874 }
875 }
876 if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
877 continue;
878 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
879 for (i = 0; i < nregs; i++)
880 {
881 hard_regno_last_set[hard_regno + i] = move;
882 hard_regno_last_set_check[hard_regno + i] = curr_tick;
883 }
884 }
f1f41a6c 885 for (i = (int) move_vec.length () - 1; i >= 0; i--)
47dd2e78 886 {
f1f41a6c 887 move = move_vec[i];
47dd2e78 888 move->next = NULL;
889 last->next = move;
890 last = move;
891 }
892 return first;
893}
894
895/* Generate RTX move insns from the move list LIST. This updates
896 allocation cost using move execution frequency FREQ. */
897static rtx
898emit_move_list (move_t list, int freq)
899{
c6a6cdaa 900 rtx to, from, dest;
901 int to_regno, from_regno, cost, regno;
902 rtx result, insn, set;
47dd2e78 903 enum machine_mode mode;
66d9a7b9 904 enum reg_class aclass;
47dd2e78 905
c6a6cdaa 906 grow_reg_equivs ();
47dd2e78 907 start_sequence ();
908 for (; list != NULL; list = list->next)
909 {
910 start_sequence ();
c6a6cdaa 911 to = allocno_emit_reg (list->to);
912 to_regno = REGNO (to);
913 from = allocno_emit_reg (list->from);
914 from_regno = REGNO (from);
915 emit_move_insn (to, from);
47dd2e78 916 list->insn = get_insns ();
917 end_sequence ();
47dd2e78 918 for (insn = list->insn; insn != NULL_RTX; insn = NEXT_INSN (insn))
212e5c4f 919 {
920 /* The reload needs to have set up insn codes. If the
921 reload sets up insn codes by itself, it may fail because
922 insns will have hard registers instead of pseudos and
923 there may be no machine insn with given hard
924 registers. */
925 recog_memoized (insn);
926 /* Add insn to equiv init insn list if it is necessary.
927 Otherwise reload will not remove this insn if it decides
928 to use the equivalence. */
929 if ((set = single_set (insn)) != NULL_RTX)
930 {
c6a6cdaa 931 dest = SET_DEST (set);
932 if (GET_CODE (dest) == SUBREG)
933 dest = SUBREG_REG (dest);
934 ira_assert (REG_P (dest));
935 regno = REGNO (dest);
212e5c4f 936 if (regno >= ira_reg_equiv_len
c6a6cdaa 937 || (ira_reg_equiv[regno].invariant == NULL_RTX
938 && ira_reg_equiv[regno].constant == NULL_RTX))
212e5c4f 939 continue; /* regno has no equivalence. */
f1f41a6c 940 ira_assert ((int) reg_equivs->length () > regno);
212e5c4f 941 reg_equiv_init (regno)
942 = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
943 }
944 }
376b4092 945 if (ira_use_lra_p)
946 ira_update_equiv_info_by_shuffle_insn (to_regno, from_regno, list->insn);
47dd2e78 947 emit_insn (list->insn);
948 mode = ALLOCNO_MODE (list->to);
66d9a7b9 949 aclass = ALLOCNO_CLASS (list->to);
47dd2e78 950 cost = 0;
951 if (ALLOCNO_HARD_REGNO (list->to) < 0)
952 {
953 if (ALLOCNO_HARD_REGNO (list->from) >= 0)
954 {
66d9a7b9 955 cost = ira_memory_move_cost[mode][aclass][0] * freq;
47dd2e78 956 ira_store_cost += cost;
957 }
958 }
959 else if (ALLOCNO_HARD_REGNO (list->from) < 0)
960 {
961 if (ALLOCNO_HARD_REGNO (list->to) >= 0)
962 {
66d9a7b9 963 cost = ira_memory_move_cost[mode][aclass][0] * freq;
47dd2e78 964 ira_load_cost += cost;
965 }
966 }
967 else
968 {
66d9a7b9 969 ira_init_register_move_cost_if_necessary (mode);
970 cost = ira_register_move_cost[mode][aclass][aclass] * freq;
47dd2e78 971 ira_shuffle_cost += cost;
972 }
973 ira_overall_cost += cost;
974 }
975 result = get_insns ();
976 end_sequence ();
977 return result;
978}
979
980/* Generate RTX move insns from move lists attached to basic blocks
981 and edges. */
982static void
983emit_moves (void)
984{
985 basic_block bb;
986 edge_iterator ei;
987 edge e;
988 rtx insns, tmp;
989
990 FOR_EACH_BB (bb)
991 {
992 if (at_bb_start[bb->index] != NULL)
993 {
994 at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
995 insns = emit_move_list (at_bb_start[bb->index],
996 REG_FREQ_FROM_BB (bb));
997 tmp = BB_HEAD (bb);
998 if (LABEL_P (tmp))
999 tmp = NEXT_INSN (tmp);
1000 if (NOTE_INSN_BASIC_BLOCK_P (tmp))
1001 tmp = NEXT_INSN (tmp);
1002 if (tmp == BB_HEAD (bb))
1003 emit_insn_before (insns, tmp);
1004 else if (tmp != NULL_RTX)
1005 emit_insn_after (insns, PREV_INSN (tmp));
1006 else
1007 emit_insn_after (insns, get_last_insn ());
1008 }
1009
1010 if (at_bb_end[bb->index] != NULL)
1011 {
1012 at_bb_end[bb->index] = modify_move_list (at_bb_end[bb->index]);
1013 insns = emit_move_list (at_bb_end[bb->index], REG_FREQ_FROM_BB (bb));
1014 ira_assert (! control_flow_insn_p (BB_END (bb)));
1015 emit_insn_after (insns, BB_END (bb));
1016 }
1017
1018 FOR_EACH_EDGE (e, ei, bb->succs)
1019 {
1020 if (e->aux == NULL)
1021 continue;
1022 ira_assert ((e->flags & EDGE_ABNORMAL) == 0
1023 || ! EDGE_CRITICAL_P (e));
1024 e->aux = modify_move_list ((move_t) e->aux);
1025 insert_insn_on_edge
1026 (emit_move_list ((move_t) e->aux,
1027 REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e))),
1028 e);
1029 if (e->src->next_bb != e->dest)
1030 ira_additional_jumps_num++;
1031 }
1032 }
1033}
1034
1035/* Update costs of A and corresponding allocnos on upper levels on the
1036 loop tree from reading (if READ_P) or writing A on an execution
1037 path with FREQ. */
1038static void
1039update_costs (ira_allocno_t a, bool read_p, int freq)
1040{
1041 ira_loop_tree_node_t parent;
1042
1043 for (;;)
1044 {
1045 ALLOCNO_NREFS (a)++;
1046 ALLOCNO_FREQ (a) += freq;
1047 ALLOCNO_MEMORY_COST (a)
66d9a7b9 1048 += (ira_memory_move_cost[ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)]
47dd2e78 1049 [read_p ? 1 : 0] * freq);
1050 if (ALLOCNO_CAP (a) != NULL)
1051 a = ALLOCNO_CAP (a);
1052 else if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL
1053 || (a = parent->regno_allocno_map[ALLOCNO_REGNO (a)]) == NULL)
1054 break;
1055 }
1056}
1057
1058/* Process moves from LIST with execution FREQ to add ranges, copies,
1059 and modify costs for allocnos involved in the moves. All regnos
1060 living through the list is in LIVE_THROUGH, and the loop tree node
1061 used to find corresponding allocnos is NODE. */
1062static void
1063add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
1064 bitmap live_through, int freq)
1065{
1066 int start, n;
1067 unsigned int regno;
1068 move_t move;
ae9587ed 1069 ira_allocno_t a;
47dd2e78 1070 ira_copy_t cp;
fbff82f4 1071 live_range_t r;
47dd2e78 1072 bitmap_iterator bi;
1073 HARD_REG_SET hard_regs_live;
1074
1075 if (list == NULL)
1076 return;
1077 n = 0;
1078 EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
1079 n++;
1080 REG_SET_TO_HARD_REG_SET (hard_regs_live, live_through);
1081 /* This is a trick to guarantee that new ranges is not merged with
1082 the old ones. */
1083 ira_max_point++;
1084 start = ira_max_point;
1085 for (move = list; move != NULL; move = move->next)
1086 {
ae9587ed 1087 ira_allocno_t from = move->from;
1088 ira_allocno_t to = move->to;
be18556f 1089 int nr, i;
1090
47dd2e78 1091 bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
1092 bitmap_clear_bit (live_through, ALLOCNO_REGNO (to));
be18556f 1093
1094 nr = ALLOCNO_NUM_OBJECTS (to);
1095 for (i = 0; i < nr; i++)
1096 {
1097 ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
1098 if (OBJECT_CONFLICT_ARRAY (to_obj) == NULL)
1099 {
1100 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1101 fprintf (ira_dump_file, " Allocate conflicts for a%dr%d\n",
66d9a7b9 1102 ALLOCNO_NUM (to), REGNO (allocno_emit_reg (to)));
be18556f 1103 ira_allocate_object_conflicts (to_obj, n);
1104 }
1105 }
1106 ior_hard_reg_conflicts (from, &hard_regs_live);
1107 ior_hard_reg_conflicts (to, &hard_regs_live);
1108
47dd2e78 1109 update_costs (from, true, freq);
1110 update_costs (to, false, freq);
b7c06809 1111 cp = ira_add_allocno_copy (from, to, freq, false, move->insn, NULL);
47dd2e78 1112 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1113 fprintf (ira_dump_file, " Adding cp%d:a%dr%d-a%dr%d\n",
1114 cp->num, ALLOCNO_NUM (cp->first),
66d9a7b9 1115 REGNO (allocno_emit_reg (cp->first)),
1116 ALLOCNO_NUM (cp->second),
1117 REGNO (allocno_emit_reg (cp->second)));
be18556f 1118
1119 nr = ALLOCNO_NUM_OBJECTS (from);
1120 for (i = 0; i < nr; i++)
47dd2e78 1121 {
be18556f 1122 ira_object_t from_obj = ALLOCNO_OBJECT (from, i);
1123 r = OBJECT_LIVE_RANGES (from_obj);
1124 if (r == NULL || r->finish >= 0)
1125 {
1126 ira_add_live_range_to_object (from_obj, start, ira_max_point);
1127 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1128 fprintf (ira_dump_file,
1129 " Adding range [%d..%d] to allocno a%dr%d\n",
1130 start, ira_max_point, ALLOCNO_NUM (from),
66d9a7b9 1131 REGNO (allocno_emit_reg (from)));
be18556f 1132 }
1133 else
1134 {
1135 r->finish = ira_max_point;
1136 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1137 fprintf (ira_dump_file,
1138 " Adding range [%d..%d] to allocno a%dr%d\n",
1139 r->start, ira_max_point, ALLOCNO_NUM (from),
66d9a7b9 1140 REGNO (allocno_emit_reg (from)));
be18556f 1141 }
47dd2e78 1142 }
be18556f 1143 ira_max_point++;
1144 nr = ALLOCNO_NUM_OBJECTS (to);
1145 for (i = 0; i < nr; i++)
0c42b4f4 1146 {
be18556f 1147 ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
1148 ira_add_live_range_to_object (to_obj, ira_max_point, -1);
0c42b4f4 1149 }
47dd2e78 1150 ira_max_point++;
47dd2e78 1151 }
1152 for (move = list; move != NULL; move = move->next)
1153 {
be18556f 1154 int nr, i;
1155 nr = ALLOCNO_NUM_OBJECTS (move->to);
1156 for (i = 0; i < nr; i++)
47dd2e78 1157 {
be18556f 1158 ira_object_t to_obj = ALLOCNO_OBJECT (move->to, i);
1159 r = OBJECT_LIVE_RANGES (to_obj);
1160 if (r->finish < 0)
1161 {
1162 r->finish = ira_max_point - 1;
1163 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1164 fprintf (ira_dump_file,
1165 " Adding range [%d..%d] to allocno a%dr%d\n",
1166 r->start, r->finish, ALLOCNO_NUM (move->to),
66d9a7b9 1167 REGNO (allocno_emit_reg (move->to)));
be18556f 1168 }
47dd2e78 1169 }
1170 }
1171 EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
1172 {
ae9587ed 1173 ira_allocno_t to;
be18556f 1174 int nr, i;
1175
47dd2e78 1176 a = node->regno_allocno_map[regno];
66d9a7b9 1177 if ((to = ALLOCNO_EMIT_DATA (a)->mem_optimized_dest) != NULL)
0c42b4f4 1178 a = to;
be18556f 1179 nr = ALLOCNO_NUM_OBJECTS (a);
1180 for (i = 0; i < nr; i++)
1181 {
1182 ira_object_t obj = ALLOCNO_OBJECT (a, i);
1183 ira_add_live_range_to_object (obj, start, ira_max_point - 1);
1184 }
0c42b4f4 1185 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1186 fprintf
1187 (ira_dump_file,
1188 " Adding range [%d..%d] to live through %s allocno a%dr%d\n",
1189 start, ira_max_point - 1,
1190 to != NULL ? "upper level" : "",
66d9a7b9 1191 ALLOCNO_NUM (a), REGNO (allocno_emit_reg (a)));
47dd2e78 1192 }
1193}
1194
1195/* Process all move list to add ranges, conflicts, copies, and modify
1196 costs for allocnos involved in the moves. */
1197static void
1198add_ranges_and_copies (void)
1199{
1200 basic_block bb;
1201 edge_iterator ei;
1202 edge e;
1203 ira_loop_tree_node_t node;
1204 bitmap live_through;
1205
1206 live_through = ira_allocate_bitmap ();
1207 FOR_EACH_BB (bb)
1208 {
1209 /* It does not matter what loop_tree_node (of source or
1210 destination block) to use for searching allocnos by their
1211 regnos because of subsequent IR flattening. */
1212 node = IRA_BB_NODE (bb)->parent;
0841d295 1213 bitmap_copy (live_through, df_get_live_in (bb));
47dd2e78 1214 add_range_and_copies_from_move_list
1215 (at_bb_start[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
0841d295 1216 bitmap_copy (live_through, df_get_live_out (bb));
47dd2e78 1217 add_range_and_copies_from_move_list
1218 (at_bb_end[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
1219 FOR_EACH_EDGE (e, ei, bb->succs)
1220 {
0841d295 1221 bitmap_and (live_through,
1222 df_get_live_in (e->dest), df_get_live_out (bb));
47dd2e78 1223 add_range_and_copies_from_move_list
1224 ((move_t) e->aux, node, live_through,
1225 REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e)));
1226 }
1227 }
1228 ira_free_bitmap (live_through);
1229}
1230
1231/* The entry function changes code and generates shuffling allocnos on
1232 region borders for the regional (LOOPS_P is TRUE in this case)
1233 register allocation. */
1234void
1235ira_emit (bool loops_p)
1236{
1237 basic_block bb;
14792f4e 1238 rtx insn;
47dd2e78 1239 edge_iterator ei;
1240 edge e;
1241 ira_allocno_t a;
1242 ira_allocno_iterator ai;
1243
1244 FOR_EACH_ALLOCNO (a, ai)
66d9a7b9 1245 ALLOCNO_EMIT_DATA (a)->reg = regno_reg_rtx[ALLOCNO_REGNO (a)];
47dd2e78 1246 if (! loops_p)
1247 return;
1248 at_bb_start = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
1249 memset (at_bb_start, 0, sizeof (move_t) * last_basic_block);
1250 at_bb_end = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
1251 memset (at_bb_end, 0, sizeof (move_t) * last_basic_block);
1252 local_allocno_bitmap = ira_allocate_bitmap ();
1253 used_regno_bitmap = ira_allocate_bitmap ();
1254 renamed_regno_bitmap = ira_allocate_bitmap ();
1255 max_regno_before_changing = max_reg_num ();
1256 ira_traverse_loop_tree (true, ira_loop_tree_root, change_loop, NULL);
1257 set_allocno_somewhere_renamed_p ();
1258 ira_free_bitmap (used_regno_bitmap);
1259 ira_free_bitmap (renamed_regno_bitmap);
1260 ira_free_bitmap (local_allocno_bitmap);
0b1329df 1261 setup_entered_from_non_parent_p ();
47dd2e78 1262 FOR_EACH_BB (bb)
1263 {
1264 at_bb_start[bb->index] = NULL;
1265 at_bb_end[bb->index] = NULL;
1266 FOR_EACH_EDGE (e, ei, bb->succs)
1267 if (e->dest != EXIT_BLOCK_PTR)
1268 generate_edge_moves (e);
1269 }
1270 allocno_last_set
1271 = (move_t *) ira_allocate (sizeof (move_t) * max_reg_num ());
1272 allocno_last_set_check
1273 = (int *) ira_allocate (sizeof (int) * max_reg_num ());
1274 memset (allocno_last_set_check, 0, sizeof (int) * max_reg_num ());
1275 memset (hard_regno_last_set_check, 0, sizeof (hard_regno_last_set_check));
1276 curr_tick = 0;
1277 FOR_EACH_BB (bb)
1278 unify_moves (bb, true);
1279 FOR_EACH_BB (bb)
1280 unify_moves (bb, false);
f1f41a6c 1281 move_vec.create (ira_allocnos_num);
47dd2e78 1282 emit_moves ();
1283 add_ranges_and_copies ();
1284 /* Clean up: */
1285 FOR_EACH_BB (bb)
1286 {
1287 free_move_list (at_bb_start[bb->index]);
1288 free_move_list (at_bb_end[bb->index]);
1289 FOR_EACH_EDGE (e, ei, bb->succs)
1290 {
1291 free_move_list ((move_t) e->aux);
1292 e->aux = NULL;
1293 }
1294 }
f1f41a6c 1295 move_vec.release ();
47dd2e78 1296 ira_free (allocno_last_set_check);
1297 ira_free (allocno_last_set);
1298 commit_edge_insertions ();
14792f4e 1299 /* Fix insn codes. It is necessary to do it before reload because
1300 reload assumes initial insn codes defined. The insn codes can be
1301 invalidated by CFG infrastructure for example in jump
1302 redirection. */
1303 FOR_EACH_BB (bb)
1304 FOR_BB_INSNS_REVERSE (bb, insn)
1305 if (INSN_P (insn))
1306 recog_memoized (insn);
47dd2e78 1307 ira_free (at_bb_end);
1308 ira_free (at_bb_start);
1309}