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