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