2008-05-08 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / ira-emit.c
blob93c0f749c62934e00c75fd01004dbabdf960b2f8
1 /* Integrated Register Allocator. Changing code and generating moves.
2 Copyright (C) 2006, 2007, 2008
3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
6 This file is part of GCC.
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.
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.
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/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "regs.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "target.h"
31 #include "flags.h"
32 #include "obstack.h"
33 #include "bitmap.h"
34 #include "hard-reg-set.h"
35 #include "basic-block.h"
36 #include "expr.h"
37 #include "recog.h"
38 #include "params.h"
39 #include "timevar.h"
40 #include "tree-pass.h"
41 #include "output.h"
42 #include "reload.h"
43 #include "errors.h"
44 #include "df.h"
45 #include "ira-int.h"
48 /* The structure represents an allocno move. The both allocnos have
49 the same origional regno but different allocation. */
50 struct move
52 /* The allocnos involved in the move. */
53 allocno_t from, to;
54 /* The next move in the move sequence. */
55 struct move *next;
56 /* Used for finding dependencies. */
57 int visited_p;
58 /* The size of the following array. */
59 int deps_num;
60 /* Moves on which given move depends on. Dependency can be cyclic.
61 It means we need a temporary to generates the moves. Sequence
62 A1->A2, B1->B2 where A1 and B2 are assigned to reg R1 and A2 and
63 B1 are assigned to reg R2 is an example of the cyclic
64 dependencies. */
65 struct move **deps;
66 /* First insn generated for the move. */
67 rtx insn;
70 /* Array of moves (indexed by BB index) which should be put at the
71 start/end of the corresponding basic blocks. */
72 static struct move **at_bb_start, **at_bb_end;
74 /* Max regno before renaming some pseudo-registers. For example, the
75 same pseudo-register can be renamed in a loop if its allocation is
76 different outside the loop. */
77 static int max_regno_before_changing;
79 static struct move *create_move (allocno_t, allocno_t);
80 static void free_move (struct move *);
81 static void free_move_list (struct move *);
82 static int eq_move_lists_p (struct move *, struct move *);
83 static int change_regs (rtx *);
84 static void add_to_edge_list (edge, struct move *, int);
85 static rtx create_new_reg (rtx);
86 static int subloop_tree_node_p (loop_tree_node_t, loop_tree_node_t);
87 static void set_allocno_reg (allocno_t, rtx);
88 static int not_modified_p (allocno_t, allocno_t);
89 static void generate_edge_moves (edge);
90 static void change_loop (loop_tree_node_t);
91 static void set_allocno_somewhere_renamed_p (void);
92 static int eq_edge_move_lists_p (VEC(edge,gc) *);
93 static void unify_moves (basic_block, int);
94 static void traverse_moves (struct move *);
95 static struct move *modify_move_list (struct move *);
96 static rtx emit_move_list (struct move *, int);
97 static void emit_moves (void);
98 static void update_costs (allocno_t, int, int);
99 static void add_range_and_copies_from_move_list (struct move *,
100 loop_tree_node_t,
101 bitmap, int);
102 static void add_ranges_and_copies (void);
104 /* The function returns new move of allocnos TO and FROM. */
105 static struct move *
106 create_move (allocno_t to, allocno_t from)
108 struct move *move;
110 move = ira_allocate (sizeof (struct move));
111 move->deps = NULL;
112 move->deps_num = 0;
113 move->to = to;
114 move->from = from;
115 move->next = NULL;
116 move->insn = NULL_RTX;
117 move->visited_p = FALSE;
118 return move;
121 /* The function frees memory for MOVE and its dependencies. */
122 static void
123 free_move (struct move *move)
125 if (move->deps != NULL)
126 ira_free (move->deps);
127 ira_free (move);
130 /* The function frees memory for list of the moves given by its
131 HEAD. */
132 static void
133 free_move_list (struct move *head)
135 struct move *next;
137 for (; head != NULL; head = next)
139 next = head->next;
140 free_move (head);
144 /* The function returns nonzero if the the move list LIST1 and LIST2
145 are equal (two moves are equal if they involve the same
146 allocnos). */
147 static int
148 eq_move_lists_p (struct move *list1, struct move *list2)
150 for (; list1 != NULL && list2 != NULL;
151 list1 = list1->next, list2 = list2->next)
152 if (list1->from != list2->from || list1->to != list2->to)
153 return FALSE;
154 return list1 == list2;
157 /* This recursive function changes pseudo-registers in *LOC if it is
158 necessary. The function returns TRUE if a change was done. */
159 static int
160 change_regs (rtx *loc)
162 int i, regno, result = FALSE;
163 const char *fmt;
164 enum rtx_code code;
166 if (*loc == NULL_RTX)
167 return FALSE;
168 code = GET_CODE (*loc);
169 if (code == REG)
171 regno = REGNO (*loc);
172 if (regno < FIRST_PSEUDO_REGISTER)
173 return FALSE;
174 if (regno >= max_regno_before_changing)
175 /* It is a shared register which was changed already. */
176 return FALSE;
177 if (ira_curr_regno_allocno_map[regno] == NULL)
178 return FALSE;
179 *loc = ALLOCNO_REG (ira_curr_regno_allocno_map[regno]);
180 return TRUE;
183 fmt = GET_RTX_FORMAT (code);
184 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
186 if (fmt[i] == 'e')
187 result = change_regs (&XEXP (*loc, i)) || result;
188 else if (fmt[i] == 'E')
190 int j;
192 for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
193 result = change_regs (&XVECEXP (*loc, i, j)) || result;
196 return result;
199 /* The function attaches MOVE to the edge E. The move is attached to
200 the head of the list if HEAD_P is nonzero. */
201 static void
202 add_to_edge_list (edge e, struct move *move, int head_p)
204 struct move *last;
206 if (head_p || e->aux == NULL)
208 move->next = e->aux;
209 e->aux = move;
211 else
213 for (last = e->aux; last->next != NULL; last = last->next)
215 last->next = move;
216 move->next = NULL;
220 /* The function creates and returns new pseudo-register with the same
221 attributes as ORIGINAL_REG. */
222 static rtx
223 create_new_reg (rtx original_reg)
225 rtx new_reg;
227 new_reg = gen_reg_rtx (GET_MODE (original_reg));
228 ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
229 REG_USERVAR_P (new_reg) = REG_USERVAR_P (original_reg);
230 REG_POINTER (new_reg) = REG_POINTER (original_reg);
231 REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
232 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
233 fprintf (ira_dump_file, " Creating newreg=%i from oldreg=%i\n",
234 REGNO (new_reg), REGNO (original_reg));
235 return new_reg;
238 /* The function returns TRUE if loop given by SUBNODE inside the
239 loop given by NODE. */
240 static int
241 subloop_tree_node_p (loop_tree_node_t subnode, loop_tree_node_t node)
243 for (; subnode != NULL; subnode = subnode->father)
244 if (subnode == node)
245 return TRUE;
246 return FALSE;
249 /* The function sets up member `reg' to REG for allocnos which has the
250 same regno as ALLOCNO and which are inside the loop corresponding to
251 ALLOCNO. */
252 static void
253 set_allocno_reg (allocno_t allocno, rtx reg)
255 int regno;
256 allocno_t a;
257 loop_tree_node_t node;
259 node = ALLOCNO_LOOP_TREE_NODE (allocno);
260 for (a = regno_allocno_map[ALLOCNO_REGNO (allocno)];
261 a != NULL;
262 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
263 if (subloop_tree_node_p (ALLOCNO_LOOP_TREE_NODE (a), node))
264 ALLOCNO_REG (a) = reg;
265 for (a = ALLOCNO_CAP (allocno); a != NULL; a = ALLOCNO_CAP (a))
266 ALLOCNO_REG (a) = reg;
267 regno = ALLOCNO_REGNO (allocno);
268 for (a = allocno;;)
270 if (a == NULL || (a = ALLOCNO_CAP (a)) == NULL)
272 node = node->father;
273 if (node == NULL)
274 break;
275 a = node->regno_allocno_map[regno];
277 if (a == NULL)
278 continue;
279 if (ALLOCNO_CHILD_RENAMED_P (a))
280 break;
281 ALLOCNO_CHILD_RENAMED_P (a) = TRUE;
285 /* The following function returns TRUE if move of SRC_ALLOCNO to
286 DEST_ALLOCNO does not change value of the destination. One possible
287 reason for this is the situation when SRC_ALLOCNO is not modified
288 in the corresponding loop. */
289 static int
290 not_modified_p (allocno_t src_allocno, allocno_t dest_allocno)
292 int regno, orig_regno;
293 allocno_t a;
294 loop_tree_node_t node;
296 orig_regno = ALLOCNO_REGNO (src_allocno);
297 regno = REGNO (ALLOCNO_REG (dest_allocno));
298 for (node = ALLOCNO_LOOP_TREE_NODE (src_allocno);
299 node != NULL;
300 node = node->father)
301 if ((a = node->regno_allocno_map[orig_regno]) == NULL)
302 break;
303 else if (REGNO (ALLOCNO_REG (a)) == (unsigned) regno)
304 return TRUE;
305 else if (bitmap_bit_p (node->modified_regnos, orig_regno))
306 return FALSE;
307 return node != NULL;
310 /* The function generates and attaches moves to the edge E. It looks
311 at the final regnos of allocnos living on the edge with the same
312 original regno to figure out when moves should be generated. */
313 static void
314 generate_edge_moves (edge e)
316 loop_tree_node_t src_loop_node, dest_loop_node;
317 unsigned int regno;
318 bitmap_iterator bi;
319 allocno_t src_allocno, dest_allocno, *src_map, *dest_map;
320 struct move *move;
322 src_loop_node = IRA_BB_NODE (e->src)->father;
323 dest_loop_node = IRA_BB_NODE (e->dest)->father;
324 e->aux = NULL;
325 if (src_loop_node == dest_loop_node)
326 return;
327 src_map = src_loop_node->regno_allocno_map;
328 dest_map = dest_loop_node->regno_allocno_map;
329 EXECUTE_IF_SET_IN_REG_SET (DF_LR_IN (e->dest),
330 FIRST_PSEUDO_REGISTER, regno, bi)
331 if (bitmap_bit_p (DF_LR_OUT (e->src), regno))
333 src_allocno = src_map[regno];
334 dest_allocno = dest_map[regno];
335 if (REGNO (ALLOCNO_REG (src_allocno))
336 == REGNO (ALLOCNO_REG (dest_allocno)))
337 continue;
338 /* Actually it is not a optimization we need this code because
339 the memory (remember about equivalent memory) might be ROM
340 (or placed in read only section). */
341 if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
342 && ALLOCNO_HARD_REGNO (src_allocno) >= 0
343 && not_modified_p (src_allocno, dest_allocno))
345 ALLOCNO_MEM_OPTIMIZED_DEST (src_allocno) = dest_allocno;
346 ALLOCNO_MEM_OPTIMIZED_DEST_P (dest_allocno) = TRUE;
347 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
348 fprintf (ira_dump_file, " Remove r%d:a%d->a%d(mem)\n",
349 regno, ALLOCNO_NUM (src_allocno),
350 ALLOCNO_NUM (dest_allocno));
351 continue;
353 move = create_move (dest_allocno, src_allocno);
354 add_to_edge_list (e, move, TRUE);
358 /* Bitmap of allocnos local for the current loop. */
359 static bitmap local_allocno_bitmap;
361 /* This bitmap is used to find that we need to generate and to use a
362 new pseudo-register when processing allocnos with the same original
363 regno. */
364 static bitmap used_regno_bitmap;
366 /* This bitmap contains regnos of allocnos which were renamed locally
367 because the allocnos correspond to disjoint live ranges in loops
368 with a common parent. */
369 static bitmap renamed_regno_bitmap;
371 /* The following function changes (if necessary) pseudo-registers
372 inside loop given by loop tree node NODE. */
373 static void
374 change_loop (loop_tree_node_t node)
376 bitmap_iterator bi;
377 unsigned int i;
378 int regno, used_p;
379 allocno_t allocno, father_allocno, *map;
380 rtx insn, original_reg;
381 enum reg_class cover_class;
382 loop_tree_node_t father;
384 if (node != ira_loop_tree_root)
387 if (node->bb != NULL)
389 FOR_BB_INSNS (node->bb, insn)
390 if (INSN_P (insn) && change_regs (&insn))
392 df_insn_rescan (insn);
393 df_notes_rescan (insn);
395 return;
398 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
399 fprintf (ira_dump_file,
400 " Changing RTL for loop %d (header bb%d)\n",
401 node->loop->num, node->loop->header->index);
403 father = ira_curr_loop_tree_node->father;
404 map = father->regno_allocno_map;
405 EXECUTE_IF_SET_IN_REG_SET (ira_curr_loop_tree_node->border_allocnos,
406 0, i, bi)
408 allocno = allocnos[i];
409 regno = ALLOCNO_REGNO (allocno);
410 cover_class = ALLOCNO_COVER_CLASS (allocno);
411 father_allocno = map[regno];
412 ira_assert (regno < reg_equiv_len);
413 /* We generate the same hard register move because the
414 reload pass can put an allocno into memory in this case
415 we will have live range splitting. If it does not happen
416 such the same hard register moves will be removed. The
417 worst case when the both allocnos are put into memory by
418 the reload is very rare. */
419 if (father_allocno != NULL
420 && (ALLOCNO_HARD_REGNO (allocno)
421 == ALLOCNO_HARD_REGNO (father_allocno))
422 && (ALLOCNO_HARD_REGNO (allocno) < 0
423 || (father->reg_pressure[cover_class] + 1
424 <= available_class_regs[cover_class])
425 || TEST_HARD_REG_BIT (prohibited_mode_move_regs
426 [ALLOCNO_MODE (allocno)],
427 ALLOCNO_HARD_REGNO (allocno))
428 /* don't create copies because reload can spill an
429 allocno set by copy although the allocno will not
430 get memory slot. */
431 || reg_equiv_invariant_p[regno]
432 || reg_equiv_const[regno] != NULL_RTX))
433 continue;
434 original_reg = ALLOCNO_REG (allocno);
435 if (father_allocno == NULL
436 || REGNO (ALLOCNO_REG (father_allocno)) == REGNO (original_reg))
438 if (internal_flag_ira_verbose > 3 && ira_dump_file)
439 fprintf (ira_dump_file, " %i vs father %i:",
440 ALLOCNO_HARD_REGNO (allocno),
441 ALLOCNO_HARD_REGNO (father_allocno));
442 set_allocno_reg (allocno, create_new_reg (original_reg));
446 /* Rename locals: Local allocnos with same regno in different loops
447 might get the different hard register. So we need to change
448 ALLOCNO_REG. */
449 bitmap_and_compl (local_allocno_bitmap,
450 ira_curr_loop_tree_node->mentioned_allocnos,
451 ira_curr_loop_tree_node->border_allocnos);
452 EXECUTE_IF_SET_IN_REG_SET (local_allocno_bitmap, 0, i, bi)
454 allocno = allocnos[i];
455 regno = ALLOCNO_REGNO (allocno);
456 if (ALLOCNO_CAP_MEMBER (allocno) != NULL)
457 continue;
458 used_p = bitmap_bit_p (used_regno_bitmap, regno);
459 bitmap_set_bit (used_regno_bitmap, regno);
460 ALLOCNO_SOMEWHERE_RENAMED_P (allocno) = TRUE;
461 if (! used_p)
462 continue;
463 bitmap_set_bit (renamed_regno_bitmap, regno);
464 set_allocno_reg (allocno, create_new_reg (ALLOCNO_REG (allocno)));
468 /* The function processes to set up flag somewhere_renamed_p. */
469 static void
470 set_allocno_somewhere_renamed_p (void)
472 unsigned int regno;
473 allocno_t allocno;
474 allocno_iterator ai;
476 FOR_EACH_ALLOCNO (allocno, ai)
478 regno = ALLOCNO_REGNO (allocno);
479 if (bitmap_bit_p (renamed_regno_bitmap, regno)
480 && REGNO (ALLOCNO_REG (allocno)) == regno)
481 ALLOCNO_SOMEWHERE_RENAMED_P (allocno) = TRUE;
485 /* The function returns nonzero if move lists on all edges given in
486 vector VEC are equal. */
487 static int
488 eq_edge_move_lists_p (VEC(edge,gc) *vec)
490 struct move *list;
491 int i;
493 list = EDGE_I (vec, 0)->aux;
494 for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
495 if (! eq_move_lists_p (list, EDGE_I (vec, i)->aux))
496 return FALSE;
497 return TRUE;
500 /* The function looks at all entry edges (if START_P) or exit edges of
501 basic block BB and puts move lists at the BB start or end if it is
502 possible. In other words, it decreases code duplication of
503 allocno moves. */
504 static void
505 unify_moves (basic_block bb, int start_p)
507 int i;
508 edge e;
509 struct move *list;
510 VEC(edge,gc) *vec;
512 vec = (start_p ? bb->preds : bb->succs);
513 if (EDGE_COUNT (vec) == 0 || ! eq_edge_move_lists_p (vec))
514 return;
515 e = EDGE_I (vec, 0);
516 list = e->aux;
517 if (! start_p && control_flow_insn_p (BB_END (bb)))
518 return;
519 e->aux = NULL;
520 for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
522 e = EDGE_I (vec, i);
523 free_move_list (e->aux);
524 e->aux = NULL;
526 if (start_p)
527 at_bb_start[bb->index] = list;
528 else
529 at_bb_end[bb->index] = list;
532 /* Last move (in move sequence being processed) setting up the
533 corresponding hard register. */
534 static struct move *hard_regno_last_set[FIRST_PSEUDO_REGISTER];
536 /* If the element value is equal to CURR_TICK then the corresponding
537 element in `hard_regno_last_set' is defined and correct. */
538 static int hard_regno_last_set_check[FIRST_PSEUDO_REGISTER];
540 /* Last move (in move sequence being processed) setting up the
541 corresponding allocno. */
542 static struct move **allocno_last_set;
544 /* If the element value is equal to CURR_TICK then the corresponding
545 element in . `allocno_last_set' is defined and correct. */
546 static int *allocno_last_set_check;
548 typedef struct move *move_t;
550 /* Definition of vector of moves. */
551 DEF_VEC_P(move_t);
552 DEF_VEC_ALLOC_P(move_t, heap);
554 /* This vec contains moves sorted topologically (depth-first) on their
555 dependency graph. */
556 static VEC(move_t,heap) *move_vec;
558 /* The variable value is used to check correctness of values of
559 elements of arrays `hard_regno_last_set' and
560 `allocno_last_set_check'. */
561 static int curr_tick;
563 /* This recursive function traverses dependencies of MOVE and produces
564 topological sorting (in depth-first order). */
565 static void
566 traverse_moves (move_t move)
568 int i;
570 if (move->visited_p)
571 return;
572 move->visited_p = TRUE;
573 for (i = move->deps_num - 1; i >= 0; i--)
574 traverse_moves (move->deps[i]);
575 VEC_safe_push (move_t, heap, move_vec, move);
578 /* The function removes unnecessary moves in the LIST, makes
579 topological sorting, and removes cycles on hard reg dependencies by
580 introducing new allocnos assigned to memory and additional moves.
581 It returns the result move list. */
582 static move_t
583 modify_move_list (move_t list)
585 int i, n, nregs, hard_regno;
586 allocno_t to, from, new_allocno;
587 move_t move, new_move, set_move, first, last;
589 if (list == NULL)
590 return NULL;
591 /* Creat move deps. */
592 curr_tick++;
593 for (move = list; move != NULL; move = move->next)
595 to = move->to;
596 if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
597 continue;
598 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
599 for (i = 0; i < nregs; i++)
601 hard_regno_last_set[hard_regno + i] = move;
602 hard_regno_last_set_check[hard_regno + i] = curr_tick;
605 for (move = list; move != NULL; move = move->next)
607 from = move->from;
608 to = move->to;
609 if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
611 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
612 for (n = i = 0; i < nregs; i++)
613 if (hard_regno_last_set_check[hard_regno + i] == curr_tick
614 && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
615 != ALLOCNO_REGNO (from)))
616 n++;
617 move->deps = ira_allocate (n * sizeof (move_t));
618 for (n = i = 0; i < nregs; i++)
619 if (hard_regno_last_set_check[hard_regno + i] == curr_tick
620 && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
621 != ALLOCNO_REGNO (from)))
622 move->deps[n++] = hard_regno_last_set[hard_regno + i];
623 move->deps_num = n;
626 /* Toplogical sorting: */
627 VEC_truncate (move_t, move_vec, 0);
628 for (move = list; move != NULL; move = move->next)
629 traverse_moves (move);
630 last = NULL;
631 for (i = (int) VEC_length (move_t, move_vec) - 1; i >= 0; i--)
633 move = VEC_index (move_t, move_vec, i);
634 move->next = NULL;
635 if (last != NULL)
636 last->next = move;
637 last = move;
639 first = VEC_last (move_t, move_vec);
640 /* Removing cycles: */
641 curr_tick++;
642 VEC_truncate (move_t, move_vec, 0);
643 for (move = first; move != NULL; move = move->next)
645 from = move->from;
646 to = move->to;
647 if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
649 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
650 for (i = 0; i < nregs; i++)
651 if (hard_regno_last_set_check[hard_regno + i] == curr_tick
652 && ALLOCNO_HARD_REGNO
653 (hard_regno_last_set[hard_regno + i]->to) >= 0)
655 set_move = hard_regno_last_set[hard_regno + i];
656 /* It does not matter what loop_tree_node (of TO or
657 FROM) to use for the new allocno because of
658 subsequent IRA internal representation
659 flattening. */
660 new_allocno
661 = create_allocno (ALLOCNO_REGNO (set_move->to), FALSE,
662 ALLOCNO_LOOP_TREE_NODE (set_move->to));
663 ALLOCNO_MODE (new_allocno) = ALLOCNO_MODE (set_move->to);
664 set_allocno_cover_class (new_allocno,
665 ALLOCNO_COVER_CLASS (set_move->to));
666 ALLOCNO_ASSIGNED_P (new_allocno) = TRUE;
667 ALLOCNO_HARD_REGNO (new_allocno) = -1;
668 ALLOCNO_REG (new_allocno)
669 = create_new_reg (ALLOCNO_REG (set_move->to));
670 ALLOCNO_CONFLICT_ID (new_allocno) = ALLOCNO_NUM (new_allocno);
671 /* Make it possibly conflicting with all earlier
672 created allocnos. Cases where temporary allocnos
673 created to remove the cycles are quite rare. */
674 ALLOCNO_MIN (new_allocno) = 0;
675 ALLOCNO_MAX (new_allocno) = allocnos_num - 1;
676 new_move = create_move (set_move->to, new_allocno);
677 set_move->to = new_allocno;
678 VEC_safe_push (move_t, heap, move_vec, new_move);
679 move_loops_num++;
680 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
681 fprintf (ira_dump_file,
682 " Creating temporary allocno a%dr%d\n",
683 ALLOCNO_NUM (new_allocno),
684 REGNO (ALLOCNO_REG (new_allocno)));
687 if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
688 continue;
689 nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
690 for (i = 0; i < nregs; i++)
692 hard_regno_last_set[hard_regno + i] = move;
693 hard_regno_last_set_check[hard_regno + i] = curr_tick;
696 for (i = (int) VEC_length (move_t, move_vec) - 1; i >= 0; i--)
698 move = VEC_index (move_t, move_vec, i);
699 move->next = NULL;
700 last->next = move;
701 last = move;
703 return first;
706 /* The function generates RTX move insns from the move list LIST. It
707 updates allocation cost using move execution frequency FREQ. */
708 static rtx
709 emit_move_list (move_t list, int freq)
711 int cost;
712 rtx result, insn;
713 enum machine_mode mode;
714 enum reg_class cover_class;
716 start_sequence ();
717 for (; list != NULL; list = list->next)
719 start_sequence ();
720 emit_move_insn (ALLOCNO_REG (list->to), ALLOCNO_REG (list->from));
721 list->insn = get_insns ();
722 end_sequence ();
723 /* The reload needs to have set up insn codes. If the reload
724 sets up insn codes by itself, it may fail because insns will
725 have hard registers instead of pseudos and there may be no
726 machine insn with given hard registers. */
727 for (insn = list->insn; insn != NULL_RTX; insn = NEXT_INSN (insn))
728 recog_memoized (insn);
729 emit_insn (list->insn);
730 mode = ALLOCNO_MODE (list->to);
731 cover_class = ALLOCNO_COVER_CLASS (list->to);
732 cost = 0;
733 if (ALLOCNO_HARD_REGNO (list->to) < 0)
735 if (ALLOCNO_HARD_REGNO (list->from) >= 0)
737 cost = memory_move_cost[mode][cover_class][0] * freq;
738 store_cost += cost;
741 else if (ALLOCNO_HARD_REGNO (list->from) < 0)
743 if (ALLOCNO_HARD_REGNO (list->to) >= 0)
745 cost = memory_move_cost[mode][cover_class][0] * freq;
746 load_cost += cost;
749 else
751 cost = register_move_cost[mode][cover_class][cover_class] * freq;
752 shuffle_cost += cost;
754 overall_cost += cost;
756 result = get_insns ();
757 end_sequence ();
758 return result;
761 /* The function generates RTX move insns from move lists attached to
762 basic blocks and edges. */
763 static void
764 emit_moves (void)
766 basic_block bb;
767 edge_iterator ei;
768 edge e;
769 rtx insns, tmp;
771 FOR_EACH_BB (bb)
773 if (at_bb_start[bb->index] != NULL)
775 at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
776 insns = emit_move_list (at_bb_start[bb->index],
777 REG_FREQ_FROM_BB (bb));
778 tmp = BB_HEAD (bb);
779 if (LABEL_P (tmp))
780 tmp = NEXT_INSN (tmp);
781 if (NOTE_INSN_BASIC_BLOCK_P (tmp))
782 tmp = NEXT_INSN (tmp);
783 if (tmp == BB_HEAD (bb))
784 emit_insn_before (insns, tmp);
785 else if (tmp != NULL_RTX)
786 emit_insn_after (insns, PREV_INSN (tmp));
787 else
788 emit_insn_after (insns, get_last_insn ());
791 if (at_bb_end[bb->index] != NULL)
793 at_bb_end[bb->index] = modify_move_list (at_bb_end[bb->index]);
794 insns = emit_move_list (at_bb_end[bb->index], REG_FREQ_FROM_BB (bb));
795 ira_assert (! control_flow_insn_p (BB_END (bb)));
796 emit_insn_after (insns, BB_END (bb));
799 FOR_EACH_EDGE (e, ei, bb->succs)
801 if (e->aux == NULL)
802 continue;
803 ira_assert ((e->flags & EDGE_ABNORMAL) == 0
804 || ! EDGE_CRITICAL_P (e));
805 e->aux = modify_move_list (e->aux);
806 insert_insn_on_edge
807 (emit_move_list (e->aux,
808 REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e))),
810 if (e->src->next_bb != e->dest)
811 additional_jumps_num++;
816 /* Update costs of A and corresponding allocnos on upper levels on the
817 loop tree from reading (if READ_P) or writing A on an execution
818 path with FREQ. */
819 static void
820 update_costs (allocno_t a, int read_p, int freq)
822 loop_tree_node_t father;
824 for (;;)
826 ALLOCNO_NREFS (a)++;
827 ALLOCNO_FREQ (a) += freq;
828 ALLOCNO_MEMORY_COST (a)
829 += (memory_move_cost[ALLOCNO_MODE (a)][ALLOCNO_COVER_CLASS (a)]
830 [read_p ? 1 : 0] * freq);
831 if ((father = ALLOCNO_LOOP_TREE_NODE (a)->father) == NULL
832 || (a = father->regno_allocno_map[ALLOCNO_REGNO (a)]) == NULL)
833 break;
837 /* The function processes moves from LIST with execution FREQ to add
838 ranges, copies, and modify costs for allocnos involved in the
839 moves. All regnos living through the list is in LIVE_THROUGH, and
840 the loop tree node used to find corresponding allocnos is NODE. */
841 static void
842 add_range_and_copies_from_move_list (move_t list, loop_tree_node_t node,
843 bitmap live_through, int freq)
845 int start, n;
846 unsigned int regno;
847 move_t move;
848 allocno_t to, from, a;
849 copy_t cp;
850 allocno_live_range_t r;
851 bitmap_iterator bi;
852 HARD_REG_SET hard_regs_live;
854 if (list == NULL)
855 return;
856 n = 0;
857 EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
858 n++;
859 REG_SET_TO_HARD_REG_SET (hard_regs_live, live_through);
860 /* This is a trick to guarantee that new ranges is not merged with
861 the old ones. */
862 max_point++;
863 start = max_point;
864 for (move = list; move != NULL; move = move->next)
866 from = move->from;
867 to = move->to;
868 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (to) == NULL)
870 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
871 fprintf (ira_dump_file, " Allocate conflicts for a%dr%d\n",
872 ALLOCNO_NUM (to), REGNO (ALLOCNO_REG (to)));
873 allocate_allocno_conflicts (to, n);
875 bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
876 bitmap_clear_bit (live_through, ALLOCNO_REGNO (to));
877 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (from), hard_regs_live);
878 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (to), hard_regs_live);
879 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from),
880 hard_regs_live);
881 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (to), hard_regs_live);
882 update_costs (from, TRUE, freq);
883 update_costs (to, FALSE, freq);
884 cp = add_allocno_copy (from, to, freq, move->insn, NULL);
885 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
886 fprintf (ira_dump_file, " Adding cp%d:a%dr%d-a%dr%d\n",
887 cp->num, ALLOCNO_NUM (cp->first),
888 REGNO (ALLOCNO_REG (cp->first)), ALLOCNO_NUM (cp->second),
889 REGNO (ALLOCNO_REG (cp->second)));
890 r = ALLOCNO_LIVE_RANGES (from);
891 if (r == NULL || r->finish >= 0)
893 ALLOCNO_LIVE_RANGES (from)
894 = create_allocno_live_range (from, start, max_point, r);
895 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
896 fprintf (ira_dump_file,
897 " Adding range [%d..%d] to allocno a%dr%d\n",
898 start, max_point, ALLOCNO_NUM (from),
899 REGNO (ALLOCNO_REG (from)));
901 else
902 r->finish = max_point;
903 max_point++;
904 ALLOCNO_LIVE_RANGES (to)
905 = create_allocno_live_range (to, max_point, -1,
906 ALLOCNO_LIVE_RANGES (to));
907 max_point++;
909 for (move = list; move != NULL; move = move->next)
911 r = ALLOCNO_LIVE_RANGES (move->to);
912 if (r->finish < 0)
914 r->finish = max_point - 1;
915 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
916 fprintf (ira_dump_file,
917 " Adding range [%d..%d] to allocno a%dr%d\n",
918 r->start, r->finish, ALLOCNO_NUM (move->to),
919 REGNO (ALLOCNO_REG (move->to)));
922 EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
924 a = node->regno_allocno_map[regno];
925 if (ALLOCNO_MEM_OPTIMIZED_DEST (a) == NULL)
927 ALLOCNO_LIVE_RANGES (a)
928 = create_allocno_live_range (a, start, max_point - 1,
929 ALLOCNO_LIVE_RANGES (a));
930 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
931 fprintf
932 (ira_dump_file,
933 " Adding range [%d..%d] to live through allocno a%dr%d\n",
934 start, max_point - 1, ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)));
939 /* The function processes all move list to add ranges, conflicts,
940 copies, and modify costs for allocnos involved in the moves. */
941 static void
942 add_ranges_and_copies (void)
944 basic_block bb;
945 edge_iterator ei;
946 edge e;
947 loop_tree_node_t node;
948 bitmap live_through;
950 live_through = ira_allocate_bitmap ();
951 FOR_EACH_BB (bb)
953 /* It does not matter what loop_tree_node (of source or
954 destination block) to use for searching allocnos by their
955 regnos because of subsequent IR flattening. */
956 node = IRA_BB_NODE (bb)->father;
957 bitmap_copy (live_through, DF_LR_IN (bb));
958 add_range_and_copies_from_move_list
959 (at_bb_start[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
960 bitmap_copy (live_through, DF_LR_OUT (bb));
961 add_range_and_copies_from_move_list
962 (at_bb_end[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
963 FOR_EACH_EDGE (e, ei, bb->succs)
965 bitmap_and (live_through, DF_LR_IN (e->dest), DF_LR_OUT (bb));
966 add_range_and_copies_from_move_list
967 (e->aux, node, live_through,
968 REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e)));
971 ira_free_bitmap (live_through);
974 /* The entry function changes code and generates shuffling allocnos on
975 region borders for the regional (LOOPS_P is TRUE in this case)
976 register allocation. */
977 void
978 ira_emit (int loops_p)
980 basic_block bb;
981 edge_iterator ei;
982 edge e;
983 allocno_t a;
984 allocno_iterator ai;
986 FOR_EACH_ALLOCNO (a, ai)
987 ALLOCNO_REG (a) = regno_reg_rtx[ALLOCNO_REGNO (a)];
988 if (! loops_p)
989 return;
990 at_bb_start = ira_allocate (sizeof (move_t) * last_basic_block);
991 memset (at_bb_start, 0, sizeof (move_t) * last_basic_block);
992 at_bb_end = ira_allocate (sizeof (move_t) * last_basic_block);
993 memset (at_bb_end, 0, sizeof (move_t) * last_basic_block);
994 local_allocno_bitmap = ira_allocate_bitmap ();
995 used_regno_bitmap = ira_allocate_bitmap ();
996 renamed_regno_bitmap = ira_allocate_bitmap ();
997 max_regno_before_changing = max_reg_num ();
998 traverse_loop_tree (TRUE, ira_loop_tree_root, change_loop, NULL);
999 set_allocno_somewhere_renamed_p ();
1000 ira_free_bitmap (used_regno_bitmap);
1001 ira_free_bitmap (renamed_regno_bitmap);
1002 ira_free_bitmap (local_allocno_bitmap);
1003 FOR_EACH_BB (bb)
1005 at_bb_start[bb->index] = NULL;
1006 at_bb_end[bb->index] = NULL;
1007 FOR_EACH_EDGE (e, ei, bb->succs)
1008 if (e->dest != EXIT_BLOCK_PTR)
1009 generate_edge_moves (e);
1011 allocno_last_set = ira_allocate (sizeof (move_t) * max_reg_num ());
1012 allocno_last_set_check = ira_allocate (sizeof (int) * max_reg_num ());
1013 memset (allocno_last_set_check, 0, sizeof (int) * max_reg_num ());
1014 memset (hard_regno_last_set_check, 0, sizeof (hard_regno_last_set_check));
1015 curr_tick = 0;
1016 FOR_EACH_BB (bb)
1017 unify_moves (bb, TRUE);
1018 FOR_EACH_BB (bb)
1019 unify_moves (bb, FALSE);
1020 move_vec = VEC_alloc (move_t, heap, allocnos_num);
1021 emit_moves ();
1022 add_ranges_and_copies ();
1023 /* Clean up: */
1024 FOR_EACH_BB (bb)
1026 free_move_list (at_bb_start[bb->index]);
1027 free_move_list (at_bb_end[bb->index]);
1028 FOR_EACH_EDGE (e, ei, bb->succs)
1030 free_move_list (e->aux);
1031 e->aux = NULL;
1034 VEC_free (move_t, heap, move_vec);
1035 ira_free (allocno_last_set_check);
1036 ira_free (allocno_last_set);
1037 commit_edge_insertions ();
1038 ira_free (at_bb_end);
1039 ira_free (at_bb_start);