1 /* Basic block reordering routines for the GNU compiler.
2 Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 /* This (greedy) algorithm constructs traces in several rounds.
22 The construction starts from "seeds". The seed for the first round
23 is the entry point of function. When there are more than one seed
24 that one is selected first that has the lowest key in the heap
25 (see function bb_to_key). Then the algorithm repeatedly adds the most
26 probable successor to the end of a trace. Finally it connects the traces.
28 There are two parameters: Branch Threshold and Exec Threshold.
29 If the edge to a successor of the actual basic block is lower than
30 Branch Threshold or the frequency of the successor is lower than
31 Exec Threshold the successor will be the seed in one of the next rounds.
32 Each round has these parameters lower than the previous one.
33 The last round has to have these parameters set to zero
34 so that the remaining blocks are picked up.
36 The algorithm selects the most probable successor from all unvisited
37 successors and successors that have been added to this trace.
38 The other successors (that has not been "sent" to the next round) will be
39 other seeds for this round and the secondary traces will start in them.
40 If the successor has not been visited in this trace it is added to the trace
41 (however, there is some heuristic for simple branches).
42 If the successor has been visited in this trace the loop has been found.
43 If the loop has many iterations the loop is rotated so that the
44 source block of the most probable edge going out from the loop
45 is the last block of the trace.
46 If the loop has few iterations and there is no edge from the last block of
47 the loop going out from loop the loop header is duplicated.
48 Finally, the construction of the trace is terminated.
50 When connecting traces it first checks whether there is an edge from the
51 last block of one trace to the first block of another trace.
52 When there are still some unconnected traces it checks whether there exists
53 a basic block BB such that BB is a successor of the last bb of one trace
54 and BB is a predecessor of the first block of another trace. In this case,
55 BB is duplicated and the traces are connected through this duplicate.
56 The rest of traces are simply connected so there will be a jump to the
57 beginning of the rest of trace.
62 "Software Trace Cache"
63 A. Ramirez, J. Larriba-Pey, C. Navarro, J. Torrellas and M. Valero; 1999
64 http://citeseer.nj.nec.com/15361.html
70 #include "coretypes.h"
73 #include "basic-block.h"
77 #include "cfglayout.h"
81 /* The number of rounds. */
84 /* Branch thresholds in thousandths (per mille) of the REG_BR_PROB_BASE. */
85 static int branch_threshold
[N_ROUNDS
] = {400, 200, 100, 0};
87 /* Exec thresholds in thousandths (per mille) of the frequency of bb 0. */
88 static int exec_threshold
[N_ROUNDS
] = {500, 200, 50, 0};
90 /* If edge frequency is lower than DUPLICATION_THRESHOLD per mille of entry
91 block the edge destination is not duplicated while connecting traces. */
92 #define DUPLICATION_THRESHOLD 100
94 /* Length of unconditional jump instruction. */
95 static int uncond_jump_length
;
97 /* Structure to hold needed information for each basic block. */
98 typedef struct bbro_basic_block_data_def
100 /* Which trace is the bb start of (-1 means it is not a start of a trace). */
103 /* Which trace is the bb end of (-1 means it is not an end of a trace). */
106 /* Which heap is BB in (if any)? */
109 /* Which heap node is BB in (if any)? */
111 } bbro_basic_block_data
;
113 /* The current size of the following dynamic array. */
114 static int array_size
;
116 /* The array which holds needed information for basic blocks. */
117 static bbro_basic_block_data
*bbd
;
119 /* To avoid frequent reallocation the size of arrays is greater than needed,
120 the number of elements is (not less than) 1.25 * size_wanted. */
121 #define GET_ARRAY_SIZE(X) ((((X) / 4) + 1) * 5)
123 /* Free the memory and set the pointer to NULL. */
125 do { if (P) { free (P); P = 0; } else { abort (); } } while (0)
127 /* Structure for holding information about a trace. */
130 /* First and last basic block of the trace. */
131 basic_block first
, last
;
133 /* The round of the STC creation which this trace was found in. */
136 /* The length (i.e. the number of basic blocks) of the trace. */
140 /* Maximum frequency and count of one of the entry blocks. */
141 int max_entry_frequency
;
142 gcov_type max_entry_count
;
144 /* Local function prototypes. */
145 static void find_traces (int *, struct trace
*);
146 static basic_block
rotate_loop (edge
, struct trace
*, int);
147 static void mark_bb_visited (basic_block
, int);
148 static void find_traces_1_round (int, int, gcov_type
, struct trace
*, int *,
150 static basic_block
copy_bb (basic_block
, edge
, basic_block
, int);
151 static fibheapkey_t
bb_to_key (basic_block
);
152 static bool better_edge_p (basic_block
, edge
, int, int, int, int);
153 static void connect_traces (int, struct trace
*);
154 static bool copy_bb_p (basic_block
, int);
155 static int get_uncond_jump_length (void);
157 /* Find the traces for Software Trace Cache. Chain each trace through
158 RBI()->next. Store the number of traces to N_TRACES and description of
162 find_traces (int *n_traces
, struct trace
*traces
)
168 /* Insert entry points of function into heap. */
169 heap
= fibheap_new ();
170 max_entry_frequency
= 0;
172 for (e
= ENTRY_BLOCK_PTR
->succ
; e
; e
= e
->succ_next
)
174 bbd
[e
->dest
->index
].heap
= heap
;
175 bbd
[e
->dest
->index
].node
= fibheap_insert (heap
, bb_to_key (e
->dest
),
177 if (e
->dest
->frequency
> max_entry_frequency
)
178 max_entry_frequency
= e
->dest
->frequency
;
179 if (e
->dest
->count
> max_entry_count
)
180 max_entry_count
= e
->dest
->count
;
183 /* Find the traces. */
184 for (i
= 0; i
< N_ROUNDS
; i
++)
186 gcov_type count_threshold
;
189 fprintf (rtl_dump_file
, "STC - round %d\n", i
+ 1);
191 if (max_entry_count
< INT_MAX
/ 1000)
192 count_threshold
= max_entry_count
* exec_threshold
[i
] / 1000;
194 count_threshold
= max_entry_count
/ 1000 * exec_threshold
[i
];
196 find_traces_1_round (REG_BR_PROB_BASE
* branch_threshold
[i
] / 1000,
197 max_entry_frequency
* exec_threshold
[i
] / 1000,
198 count_threshold
, traces
, n_traces
, i
, &heap
);
200 fibheap_delete (heap
);
204 for (i
= 0; i
< *n_traces
; i
++)
207 fprintf (rtl_dump_file
, "Trace %d (round %d): ", i
+ 1,
208 traces
[i
].round
+ 1);
209 for (bb
= traces
[i
].first
; bb
!= traces
[i
].last
; bb
= bb
->rbi
->next
)
210 fprintf (rtl_dump_file
, "%d [%d] ", bb
->index
, bb
->frequency
);
211 fprintf (rtl_dump_file
, "%d [%d]\n", bb
->index
, bb
->frequency
);
213 fflush (rtl_dump_file
);
217 /* Rotate loop whose back edge is BACK_EDGE in the tail of trace TRACE
218 (with sequential number TRACE_N). */
221 rotate_loop (edge back_edge
, struct trace
*trace
, int trace_n
)
225 /* Information about the best end (end after rotation) of the loop. */
226 basic_block best_bb
= NULL
;
227 edge best_edge
= NULL
;
229 gcov_type best_count
= -1;
230 /* The best edge is preferred when its destination is not visited yet
231 or is a start block of some trace. */
232 bool is_preferred
= false;
234 /* Find the most frequent edge that goes out from current trace. */
235 bb
= back_edge
->dest
;
239 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
240 if (e
->dest
!= EXIT_BLOCK_PTR
241 && e
->dest
->rbi
->visited
!= trace_n
242 && (e
->flags
& EDGE_CAN_FALLTHRU
)
243 && !(e
->flags
& EDGE_COMPLEX
))
247 /* The best edge is preferred. */
248 if (!e
->dest
->rbi
->visited
249 || bbd
[e
->dest
->index
].start_of_trace
>= 0)
251 /* The current edge E is also preferred. */
252 int freq
= EDGE_FREQUENCY (e
);
253 if (freq
> best_freq
|| e
->count
> best_count
)
256 best_count
= e
->count
;
264 if (!e
->dest
->rbi
->visited
265 || bbd
[e
->dest
->index
].start_of_trace
>= 0)
267 /* The current edge E is preferred. */
269 best_freq
= EDGE_FREQUENCY (e
);
270 best_count
= e
->count
;
276 int freq
= EDGE_FREQUENCY (e
);
277 if (!best_edge
|| freq
> best_freq
|| e
->count
> best_count
)
280 best_count
= e
->count
;
289 while (bb
!= back_edge
->dest
);
293 /* Rotate the loop so that the BEST_EDGE goes out from the last block of
295 if (back_edge
->dest
== trace
->first
)
297 trace
->first
= best_bb
->rbi
->next
;
303 for (prev_bb
= trace
->first
;
304 prev_bb
->rbi
->next
!= back_edge
->dest
;
305 prev_bb
= prev_bb
->rbi
->next
)
307 prev_bb
->rbi
->next
= best_bb
->rbi
->next
;
309 /* Try to get rid of uncond jump to cond jump. */
310 if (prev_bb
->succ
&& !prev_bb
->succ
->succ_next
)
312 basic_block header
= prev_bb
->succ
->dest
;
314 /* Duplicate HEADER if it is a small block containing cond jump
316 if (any_condjump_p (BB_END (header
)) && copy_bb_p (header
, 0))
318 copy_bb (header
, prev_bb
->succ
, prev_bb
, trace_n
);
325 /* We have not found suitable loop tail so do no rotation. */
326 best_bb
= back_edge
->src
;
328 best_bb
->rbi
->next
= NULL
;
332 /* This function marks BB that it was visited in trace number TRACE. */
335 mark_bb_visited (basic_block bb
, int trace
)
337 bb
->rbi
->visited
= trace
;
338 if (bbd
[bb
->index
].heap
)
340 fibheap_delete_node (bbd
[bb
->index
].heap
, bbd
[bb
->index
].node
);
341 bbd
[bb
->index
].heap
= NULL
;
342 bbd
[bb
->index
].node
= NULL
;
346 /* One round of finding traces. Find traces for BRANCH_TH and EXEC_TH i.e. do
347 not include basic blocks their probability is lower than BRANCH_TH or their
348 frequency is lower than EXEC_TH into traces (or count is lower than
349 COUNT_TH). It stores the new traces into TRACES and modifies the number of
350 traces *N_TRACES. Sets the round (which the trace belongs to) to ROUND. It
351 expects that starting basic blocks are in *HEAP and at the end it deletes
352 *HEAP and stores starting points for the next round into new *HEAP. */
355 find_traces_1_round (int branch_th
, int exec_th
, gcov_type count_th
,
356 struct trace
*traces
, int *n_traces
, int round
,
359 /* Heap for discarded basic blocks which are possible starting points for
361 fibheap_t new_heap
= fibheap_new ();
363 while (!fibheap_empty (*heap
))
370 bb
= fibheap_extract_min (*heap
);
371 bbd
[bb
->index
].heap
= NULL
;
372 bbd
[bb
->index
].node
= NULL
;
375 fprintf (rtl_dump_file
, "Getting bb %d\n", bb
->index
);
377 /* If the BB's frequency is too low send BB to the next round. */
378 if (round
< N_ROUNDS
- 1
379 && (bb
->frequency
< exec_th
|| bb
->count
< count_th
380 || probably_never_executed_bb_p (bb
)))
382 int key
= bb_to_key (bb
);
383 bbd
[bb
->index
].heap
= new_heap
;
384 bbd
[bb
->index
].node
= fibheap_insert (new_heap
, key
, bb
);
387 fprintf (rtl_dump_file
,
388 " Possible start point of next round: %d (key: %d)\n",
393 trace
= traces
+ *n_traces
;
395 trace
->round
= round
;
403 /* The probability and frequency of the best edge. */
404 int best_prob
= INT_MIN
/ 2;
405 int best_freq
= INT_MIN
/ 2;
408 mark_bb_visited (bb
, *n_traces
);
412 fprintf (rtl_dump_file
, "Basic block %d was visited in trace %d\n",
413 bb
->index
, *n_traces
- 1);
415 /* Select the successor that will be placed after BB. */
416 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
418 #ifdef ENABLE_CHECKING
419 if (e
->flags
& EDGE_FAKE
)
423 if (e
->dest
== EXIT_BLOCK_PTR
)
426 if (e
->dest
->rbi
->visited
427 && e
->dest
->rbi
->visited
!= *n_traces
)
430 prob
= e
->probability
;
431 freq
= EDGE_FREQUENCY (e
);
433 /* Edge that cannot be fallthru or improbable or infrequent
434 successor (ie. it is unsuitable successor). */
435 if (!(e
->flags
& EDGE_CAN_FALLTHRU
) || (e
->flags
& EDGE_COMPLEX
)
436 || prob
< branch_th
|| freq
< exec_th
|| e
->count
< count_th
)
439 if (better_edge_p (bb
, e
, prob
, freq
, best_prob
, best_freq
))
447 /* If the best destination has multiple predecessors, and can be
448 duplicated cheaper than a jump, don't allow it to be added
449 to a trace. We'll duplicate it when connecting traces. */
450 if (best_edge
&& best_edge
->dest
->pred
->pred_next
451 && copy_bb_p (best_edge
->dest
, 0))
454 /* Add all non-selected successors to the heaps. */
455 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
458 || e
->dest
== EXIT_BLOCK_PTR
459 || e
->dest
->rbi
->visited
)
462 key
= bb_to_key (e
->dest
);
464 if (bbd
[e
->dest
->index
].heap
)
466 /* E->DEST is already in some heap. */
467 if (key
!= bbd
[e
->dest
->index
].node
->key
)
471 fprintf (rtl_dump_file
,
472 "Changing key for bb %d from %ld to %ld.\n",
474 (long) bbd
[e
->dest
->index
].node
->key
,
477 fibheap_replace_key (bbd
[e
->dest
->index
].heap
,
478 bbd
[e
->dest
->index
].node
, key
);
483 fibheap_t which_heap
= *heap
;
485 prob
= e
->probability
;
486 freq
= EDGE_FREQUENCY (e
);
488 if (!(e
->flags
& EDGE_CAN_FALLTHRU
)
489 || (e
->flags
& EDGE_COMPLEX
)
490 || prob
< branch_th
|| freq
< exec_th
491 || e
->count
< count_th
)
493 if (round
< N_ROUNDS
- 1)
494 which_heap
= new_heap
;
497 bbd
[e
->dest
->index
].heap
= which_heap
;
498 bbd
[e
->dest
->index
].node
= fibheap_insert (which_heap
,
503 fprintf (rtl_dump_file
,
504 " Possible start of %s round: %d (key: %ld)\n",
505 (which_heap
== new_heap
) ? "next" : "this",
506 e
->dest
->index
, (long) key
);
512 if (best_edge
) /* Suitable successor was found. */
514 if (best_edge
->dest
->rbi
->visited
== *n_traces
)
516 /* We do nothing with one basic block loops. */
517 if (best_edge
->dest
!= bb
)
519 if (EDGE_FREQUENCY (best_edge
)
520 > 4 * best_edge
->dest
->frequency
/ 5)
522 /* The loop has at least 4 iterations. If the loop
523 header is not the first block of the function
524 we can rotate the loop. */
526 if (best_edge
->dest
!= ENTRY_BLOCK_PTR
->next_bb
)
530 fprintf (rtl_dump_file
,
531 "Rotating loop %d - %d\n",
532 best_edge
->dest
->index
, bb
->index
);
534 bb
->rbi
->next
= best_edge
->dest
;
535 bb
= rotate_loop (best_edge
, trace
, *n_traces
);
540 /* The loop has less than 4 iterations. */
542 /* Check whether there is another edge from BB. */
544 for (another_edge
= bb
->succ
;
546 another_edge
= another_edge
->succ_next
)
547 if (another_edge
!= best_edge
)
550 if (!another_edge
&& copy_bb_p (best_edge
->dest
,
553 bb
= copy_bb (best_edge
->dest
, best_edge
, bb
,
559 /* Terminate the trace. */
564 /* Check for a situation
573 EDGE_FREQUENCY (AB) + EDGE_FREQUENCY (BC)
574 >= EDGE_FREQUENCY (AC).
575 (i.e. 2 * B->frequency >= EDGE_FREQUENCY (AC) )
576 Best ordering is then A B C.
578 This situation is created for example by:
585 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
587 && (e
->flags
& EDGE_CAN_FALLTHRU
)
588 && !(e
->flags
& EDGE_COMPLEX
)
589 && !e
->dest
->rbi
->visited
590 && !e
->dest
->pred
->pred_next
592 && (e
->dest
->succ
->flags
& EDGE_CAN_FALLTHRU
)
593 && !(e
->dest
->succ
->flags
& EDGE_COMPLEX
)
594 && !e
->dest
->succ
->succ_next
595 && e
->dest
->succ
->dest
== best_edge
->dest
596 && 2 * e
->dest
->frequency
>= EDGE_FREQUENCY (best_edge
))
600 fprintf (rtl_dump_file
, "Selecting BB %d\n",
601 best_edge
->dest
->index
);
605 bb
->rbi
->next
= best_edge
->dest
;
606 bb
= best_edge
->dest
;
612 bbd
[trace
->first
->index
].start_of_trace
= *n_traces
- 1;
613 bbd
[trace
->last
->index
].end_of_trace
= *n_traces
- 1;
615 /* The trace is terminated so we have to recount the keys in heap
616 (some block can have a lower key because now one of its predecessors
617 is an end of the trace). */
618 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
620 if (e
->dest
== EXIT_BLOCK_PTR
621 || e
->dest
->rbi
->visited
)
624 if (bbd
[e
->dest
->index
].heap
)
626 key
= bb_to_key (e
->dest
);
627 if (key
!= bbd
[e
->dest
->index
].node
->key
)
631 fprintf (rtl_dump_file
,
632 "Changing key for bb %d from %ld to %ld.\n",
634 (long) bbd
[e
->dest
->index
].node
->key
, key
);
636 fibheap_replace_key (bbd
[e
->dest
->index
].heap
,
637 bbd
[e
->dest
->index
].node
,
644 fibheap_delete (*heap
);
646 /* "Return" the new heap. */
650 /* Create a duplicate of the basic block OLD_BB and redirect edge E to it, add
651 it to trace after BB, mark OLD_BB visited and update pass' data structures
652 (TRACE is a number of trace which OLD_BB is duplicated to). */
655 copy_bb (basic_block old_bb
, edge e
, basic_block bb
, int trace
)
659 new_bb
= cfg_layout_duplicate_bb (old_bb
, e
);
660 if (e
->dest
!= new_bb
)
662 if (e
->dest
->rbi
->visited
)
665 fprintf (rtl_dump_file
,
666 "Duplicated bb %d (created bb %d)\n",
667 old_bb
->index
, new_bb
->index
);
668 new_bb
->rbi
->visited
= trace
;
669 new_bb
->rbi
->next
= bb
->rbi
->next
;
670 bb
->rbi
->next
= new_bb
;
672 if (new_bb
->index
>= array_size
|| last_basic_block
> array_size
)
677 new_size
= MAX (last_basic_block
, new_bb
->index
+ 1);
678 new_size
= GET_ARRAY_SIZE (new_size
);
679 bbd
= xrealloc (bbd
, new_size
* sizeof (bbro_basic_block_data
));
680 for (i
= array_size
; i
< new_size
; i
++)
682 bbd
[i
].start_of_trace
= -1;
683 bbd
[i
].end_of_trace
= -1;
687 array_size
= new_size
;
691 fprintf (rtl_dump_file
,
692 "Growing the dynamic array to %d elements.\n",
700 /* Compute and return the key (for the heap) of the basic block BB. */
703 bb_to_key (basic_block bb
)
709 /* Do not start in probably never executed blocks. */
710 if (probably_never_executed_bb_p (bb
))
713 /* Prefer blocks whose predecessor is an end of some trace
714 or whose predecessor edge is EDGE_DFS_BACK. */
715 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
717 if ((e
->src
!= ENTRY_BLOCK_PTR
&& bbd
[e
->src
->index
].end_of_trace
>= 0)
718 || (e
->flags
& EDGE_DFS_BACK
))
720 int edge_freq
= EDGE_FREQUENCY (e
);
722 if (edge_freq
> priority
)
723 priority
= edge_freq
;
728 /* The block with priority should have significantly lower key. */
729 return -(100 * BB_FREQ_MAX
+ 100 * priority
+ bb
->frequency
);
730 return -bb
->frequency
;
733 /* Return true when the edge E from basic block BB is better than the temporary
734 best edge (details are in function). The probability of edge E is PROB. The
735 frequency of the successor is FREQ. The current best probability is
736 BEST_PROB, the best frequency is BEST_FREQ.
737 The edge is considered to be equivalent when PROB does not differ much from
738 BEST_PROB; similarly for frequency. */
741 better_edge_p (basic_block bb
, edge e
, int prob
, int freq
, int best_prob
,
746 /* The BEST_* values do not have to be best, but can be a bit smaller than
748 int diff_prob
= best_prob
/ 10;
749 int diff_freq
= best_freq
/ 10;
751 if (prob
> best_prob
+ diff_prob
)
752 /* The edge has higher probability than the temporary best edge. */
753 is_better_edge
= true;
754 else if (prob
< best_prob
- diff_prob
)
755 /* The edge has lower probability than the temporary best edge. */
756 is_better_edge
= false;
757 else if (freq
< best_freq
- diff_freq
)
758 /* The edge and the temporary best edge have almost equivalent
759 probabilities. The higher frequency of a successor now means
760 that there is another edge going into that successor.
761 This successor has lower frequency so it is better. */
762 is_better_edge
= true;
763 else if (freq
> best_freq
+ diff_freq
)
764 /* This successor has higher frequency so it is worse. */
765 is_better_edge
= false;
766 else if (e
->dest
->prev_bb
== bb
)
767 /* The edges have equivalent probabilities and the successors
768 have equivalent frequencies. Select the previous successor. */
769 is_better_edge
= true;
771 is_better_edge
= false;
773 return is_better_edge
;
776 /* Connect traces in array TRACES, N_TRACES is the count of traces. */
779 connect_traces (int n_traces
, struct trace
*traces
)
785 gcov_type count_threshold
;
787 freq_threshold
= max_entry_frequency
* DUPLICATION_THRESHOLD
/ 1000;
788 if (max_entry_count
< INT_MAX
/ 1000)
789 count_threshold
= max_entry_count
* DUPLICATION_THRESHOLD
/ 1000;
791 count_threshold
= max_entry_count
/ 1000 * DUPLICATION_THRESHOLD
;
793 connected
= xcalloc (n_traces
, sizeof (bool));
795 for (i
= 0; i
< n_traces
; i
++)
807 /* Find the predecessor traces. */
808 for (t2
= t
; t2
> 0;)
812 for (e
= traces
[t2
].first
->pred
; e
; e
= e
->pred_next
)
814 int si
= e
->src
->index
;
816 if (e
->src
!= ENTRY_BLOCK_PTR
817 && (e
->flags
& EDGE_CAN_FALLTHRU
)
818 && !(e
->flags
& EDGE_COMPLEX
)
819 && bbd
[si
].end_of_trace
>= 0
820 && !connected
[bbd
[si
].end_of_trace
]
822 || e
->probability
> best
->probability
823 || (e
->probability
== best
->probability
824 && traces
[bbd
[si
].end_of_trace
].length
> best_len
)))
827 best_len
= traces
[bbd
[si
].end_of_trace
].length
;
832 best
->src
->rbi
->next
= best
->dest
;
833 t2
= bbd
[best
->src
->index
].end_of_trace
;
834 connected
[t2
] = true;
837 fprintf (rtl_dump_file
, "Connection: %d %d\n",
838 best
->src
->index
, best
->dest
->index
);
846 traces
[last_trace
].last
->rbi
->next
= traces
[t2
].first
;
849 /* Find the successor traces. */
852 /* Find the continuation of the chain. */
855 for (e
= traces
[t
].last
->succ
; e
; e
= e
->succ_next
)
857 int di
= e
->dest
->index
;
859 if (e
->dest
!= EXIT_BLOCK_PTR
860 && (e
->flags
& EDGE_CAN_FALLTHRU
)
861 && !(e
->flags
& EDGE_COMPLEX
)
862 && bbd
[di
].start_of_trace
>= 0
863 && !connected
[bbd
[di
].start_of_trace
]
865 || e
->probability
> best
->probability
866 || (e
->probability
== best
->probability
867 && traces
[bbd
[di
].start_of_trace
].length
> best_len
)))
870 best_len
= traces
[bbd
[di
].start_of_trace
].length
;
878 fprintf (rtl_dump_file
, "Connection: %d %d\n",
879 best
->src
->index
, best
->dest
->index
);
881 t
= bbd
[best
->dest
->index
].start_of_trace
;
882 traces
[last_trace
].last
->rbi
->next
= traces
[t
].first
;
888 /* Try to connect the traces by duplication of 1 block. */
890 basic_block next_bb
= NULL
;
891 bool try_copy
= false;
893 for (e
= traces
[t
].last
->succ
; e
; e
= e
->succ_next
)
894 if (e
->dest
!= EXIT_BLOCK_PTR
895 && (e
->flags
& EDGE_CAN_FALLTHRU
)
896 && !(e
->flags
& EDGE_COMPLEX
)
897 && (!best
|| e
->probability
> best
->probability
))
902 /* If the destination is a start of a trace which is only
903 one block long, then no need to search the successor
904 blocks of the trace. Accept it. */
905 if (bbd
[e
->dest
->index
].start_of_trace
>= 0
906 && traces
[bbd
[e
->dest
->index
].start_of_trace
].length
914 for (e2
= e
->dest
->succ
; e2
; e2
= e2
->succ_next
)
916 int di
= e2
->dest
->index
;
918 if (e2
->dest
== EXIT_BLOCK_PTR
919 || ((e2
->flags
& EDGE_CAN_FALLTHRU
)
920 && !(e2
->flags
& EDGE_COMPLEX
)
921 && bbd
[di
].start_of_trace
>= 0
922 && !connected
[bbd
[di
].start_of_trace
]
923 && (EDGE_FREQUENCY (e2
) >= freq_threshold
)
924 && (e2
->count
>= count_threshold
)
926 || e2
->probability
> best2
->probability
927 || (e2
->probability
== best2
->probability
928 && traces
[bbd
[di
].start_of_trace
].length
933 if (e2
->dest
!= EXIT_BLOCK_PTR
)
934 best2_len
= traces
[bbd
[di
].start_of_trace
].length
;
943 /* Copy tiny blocks always; copy larger blocks only when the
944 edge is traversed frequently enough. */
946 && copy_bb_p (best
->dest
,
948 && EDGE_FREQUENCY (best
) >= freq_threshold
949 && best
->count
>= count_threshold
))
955 fprintf (rtl_dump_file
, "Connection: %d %d ",
956 traces
[t
].last
->index
, best
->dest
->index
);
958 fputc ('\n', rtl_dump_file
);
959 else if (next_bb
== EXIT_BLOCK_PTR
)
960 fprintf (rtl_dump_file
, "exit\n");
962 fprintf (rtl_dump_file
, "%d\n", next_bb
->index
);
965 new_bb
= copy_bb (best
->dest
, best
, traces
[t
].last
, t
);
966 traces
[t
].last
= new_bb
;
967 if (next_bb
&& next_bb
!= EXIT_BLOCK_PTR
)
969 t
= bbd
[next_bb
->index
].start_of_trace
;
970 traces
[last_trace
].last
->rbi
->next
= traces
[t
].first
;
975 break; /* Stop finding the successor traces. */
978 break; /* Stop finding the successor traces. */
987 fprintf (rtl_dump_file
, "Final order:\n");
988 for (bb
= traces
[0].first
; bb
; bb
= bb
->rbi
->next
)
989 fprintf (rtl_dump_file
, "%d ", bb
->index
);
990 fprintf (rtl_dump_file
, "\n");
991 fflush (rtl_dump_file
);
997 /* Return true when BB can and should be copied. CODE_MAY_GROW is true
998 when code size is allowed to grow by duplication. */
1001 copy_bb_p (basic_block bb
, int code_may_grow
)
1004 int max_size
= uncond_jump_length
;
1011 if (!bb
->pred
|| !bb
->pred
->pred_next
)
1013 if (!cfg_layout_can_duplicate_bb_p (bb
))
1016 /* Avoid duplicating blocks which have many successors (PR/13430). */
1018 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
1025 if (code_may_grow
&& maybe_hot_bb_p (bb
))
1028 for (insn
= BB_HEAD (bb
); insn
!= NEXT_INSN (BB_END (bb
));
1029 insn
= NEXT_INSN (insn
))
1032 size
+= get_attr_length (insn
);
1035 if (size
<= max_size
)
1040 fprintf (rtl_dump_file
,
1041 "Block %d can't be copied because its size = %d.\n",
1048 /* Return the length of unconditional jump instruction. */
1051 get_uncond_jump_length (void)
1056 label
= emit_label_before (gen_label_rtx (), get_insns ());
1057 jump
= emit_jump_insn (gen_jump (label
));
1059 length
= get_attr_length (jump
);
1062 delete_insn (label
);
1066 /* Reorder basic blocks. The main entry point to this file. */
1069 reorder_basic_blocks (void)
1073 struct trace
*traces
;
1075 if (n_basic_blocks
<= 1)
1078 if ((* targetm
.cannot_modify_jumps_p
) ())
1081 timevar_push (TV_REORDER_BLOCKS
);
1083 cfg_layout_initialize ();
1085 set_edge_can_fallthru_flag ();
1086 mark_dfs_back_edges ();
1088 /* We are estimating the length of uncond jump insn only once since the code
1089 for getting the insn length always returns the minimal length now. */
1090 if (uncond_jump_length
== 0)
1091 uncond_jump_length
= get_uncond_jump_length ();
1093 /* We need to know some information for each basic block. */
1094 array_size
= GET_ARRAY_SIZE (last_basic_block
);
1095 bbd
= xmalloc (array_size
* sizeof (bbro_basic_block_data
));
1096 for (i
= 0; i
< array_size
; i
++)
1098 bbd
[i
].start_of_trace
= -1;
1099 bbd
[i
].end_of_trace
= -1;
1104 traces
= xmalloc (n_basic_blocks
* sizeof (struct trace
));
1106 find_traces (&n_traces
, traces
);
1107 connect_traces (n_traces
, traces
);
1112 dump_flow_info (rtl_dump_file
);
1114 cfg_layout_finalize ();
1116 timevar_pop (TV_REORDER_BLOCKS
);