1*e4b17023SJohn Marino /* Instruction scheduling pass.
2*e4b17023SJohn Marino Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3*e4b17023SJohn Marino 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
4*e4b17023SJohn Marino Free Software Foundation, Inc.
5*e4b17023SJohn Marino Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
6*e4b17023SJohn Marino and currently maintained by, Jim Wilson (wilson@cygnus.com)
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino This file is part of GCC.
9*e4b17023SJohn Marino
10*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
11*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
12*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
13*e4b17023SJohn Marino version.
14*e4b17023SJohn Marino
15*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
17*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18*e4b17023SJohn Marino for more details.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
21*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
22*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
23*e4b17023SJohn Marino
24*e4b17023SJohn Marino /* This pass implements list scheduling within basic blocks. It is
25*e4b17023SJohn Marino run twice: (1) after flow analysis, but before register allocation,
26*e4b17023SJohn Marino and (2) after register allocation.
27*e4b17023SJohn Marino
28*e4b17023SJohn Marino The first run performs interblock scheduling, moving insns between
29*e4b17023SJohn Marino different blocks in the same "region", and the second runs only
30*e4b17023SJohn Marino basic block scheduling.
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino Interblock motions performed are useful motions and speculative
33*e4b17023SJohn Marino motions, including speculative loads. Motions requiring code
34*e4b17023SJohn Marino duplication are not supported. The identification of motion type
35*e4b17023SJohn Marino and the check for validity of speculative motions requires
36*e4b17023SJohn Marino construction and analysis of the function's control flow graph.
37*e4b17023SJohn Marino
38*e4b17023SJohn Marino The main entry point for this pass is schedule_insns(), called for
39*e4b17023SJohn Marino each function. The work of the scheduler is organized in three
40*e4b17023SJohn Marino levels: (1) function level: insns are subject to splitting,
41*e4b17023SJohn Marino control-flow-graph is constructed, regions are computed (after
42*e4b17023SJohn Marino reload, each region is of one block), (2) region level: control
43*e4b17023SJohn Marino flow graph attributes required for interblock scheduling are
44*e4b17023SJohn Marino computed (dominators, reachability, etc.), data dependences and
45*e4b17023SJohn Marino priorities are computed, and (3) block level: insns in the block
46*e4b17023SJohn Marino are actually scheduled. */
47*e4b17023SJohn Marino
48*e4b17023SJohn Marino #include "config.h"
49*e4b17023SJohn Marino #include "system.h"
50*e4b17023SJohn Marino #include "coretypes.h"
51*e4b17023SJohn Marino #include "tm.h"
52*e4b17023SJohn Marino #include "diagnostic-core.h"
53*e4b17023SJohn Marino #include "rtl.h"
54*e4b17023SJohn Marino #include "tm_p.h"
55*e4b17023SJohn Marino #include "hard-reg-set.h"
56*e4b17023SJohn Marino #include "regs.h"
57*e4b17023SJohn Marino #include "function.h"
58*e4b17023SJohn Marino #include "flags.h"
59*e4b17023SJohn Marino #include "insn-config.h"
60*e4b17023SJohn Marino #include "insn-attr.h"
61*e4b17023SJohn Marino #include "except.h"
62*e4b17023SJohn Marino #include "recog.h"
63*e4b17023SJohn Marino #include "cfglayout.h"
64*e4b17023SJohn Marino #include "params.h"
65*e4b17023SJohn Marino #include "sched-int.h"
66*e4b17023SJohn Marino #include "sel-sched.h"
67*e4b17023SJohn Marino #include "target.h"
68*e4b17023SJohn Marino #include "timevar.h"
69*e4b17023SJohn Marino #include "tree-pass.h"
70*e4b17023SJohn Marino #include "dbgcnt.h"
71*e4b17023SJohn Marino
72*e4b17023SJohn Marino #ifdef INSN_SCHEDULING
73*e4b17023SJohn Marino
74*e4b17023SJohn Marino /* Some accessor macros for h_i_d members only used within this file. */
75*e4b17023SJohn Marino #define FED_BY_SPEC_LOAD(INSN) (HID (INSN)->fed_by_spec_load)
76*e4b17023SJohn Marino #define IS_LOAD_INSN(INSN) (HID (insn)->is_load_insn)
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino /* nr_inter/spec counts interblock/speculative motion for the function. */
79*e4b17023SJohn Marino static int nr_inter, nr_spec;
80*e4b17023SJohn Marino
81*e4b17023SJohn Marino static int is_cfg_nonregular (void);
82*e4b17023SJohn Marino
83*e4b17023SJohn Marino /* Number of regions in the procedure. */
84*e4b17023SJohn Marino int nr_regions = 0;
85*e4b17023SJohn Marino
86*e4b17023SJohn Marino /* Table of region descriptions. */
87*e4b17023SJohn Marino region *rgn_table = NULL;
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino /* Array of lists of regions' blocks. */
90*e4b17023SJohn Marino int *rgn_bb_table = NULL;
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino /* Topological order of blocks in the region (if b2 is reachable from
93*e4b17023SJohn Marino b1, block_to_bb[b2] > block_to_bb[b1]). Note: A basic block is
94*e4b17023SJohn Marino always referred to by either block or b, while its topological
95*e4b17023SJohn Marino order name (in the region) is referred to by bb. */
96*e4b17023SJohn Marino int *block_to_bb = NULL;
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino /* The number of the region containing a block. */
99*e4b17023SJohn Marino int *containing_rgn = NULL;
100*e4b17023SJohn Marino
101*e4b17023SJohn Marino /* ebb_head [i] - is index in rgn_bb_table of the head basic block of i'th ebb.
102*e4b17023SJohn Marino Currently we can get a ebb only through splitting of currently
103*e4b17023SJohn Marino scheduling block, therefore, we don't need ebb_head array for every region,
104*e4b17023SJohn Marino hence, its sufficient to hold it for current one only. */
105*e4b17023SJohn Marino int *ebb_head = NULL;
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino /* The minimum probability of reaching a source block so that it will be
108*e4b17023SJohn Marino considered for speculative scheduling. */
109*e4b17023SJohn Marino static int min_spec_prob;
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino static void find_single_block_region (bool);
112*e4b17023SJohn Marino static void find_rgns (void);
113*e4b17023SJohn Marino static bool too_large (int, int *, int *);
114*e4b17023SJohn Marino
115*e4b17023SJohn Marino /* Blocks of the current region being scheduled. */
116*e4b17023SJohn Marino int current_nr_blocks;
117*e4b17023SJohn Marino int current_blocks;
118*e4b17023SJohn Marino
119*e4b17023SJohn Marino /* A speculative motion requires checking live information on the path
120*e4b17023SJohn Marino from 'source' to 'target'. The split blocks are those to be checked.
121*e4b17023SJohn Marino After a speculative motion, live information should be modified in
122*e4b17023SJohn Marino the 'update' blocks.
123*e4b17023SJohn Marino
124*e4b17023SJohn Marino Lists of split and update blocks for each candidate of the current
125*e4b17023SJohn Marino target are in array bblst_table. */
126*e4b17023SJohn Marino static basic_block *bblst_table;
127*e4b17023SJohn Marino static int bblst_size, bblst_last;
128*e4b17023SJohn Marino
129*e4b17023SJohn Marino /* Target info declarations.
130*e4b17023SJohn Marino
131*e4b17023SJohn Marino The block currently being scheduled is referred to as the "target" block,
132*e4b17023SJohn Marino while other blocks in the region from which insns can be moved to the
133*e4b17023SJohn Marino target are called "source" blocks. The candidate structure holds info
134*e4b17023SJohn Marino about such sources: are they valid? Speculative? Etc. */
135*e4b17023SJohn Marino typedef struct
136*e4b17023SJohn Marino {
137*e4b17023SJohn Marino basic_block *first_member;
138*e4b17023SJohn Marino int nr_members;
139*e4b17023SJohn Marino }
140*e4b17023SJohn Marino bblst;
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino typedef struct
143*e4b17023SJohn Marino {
144*e4b17023SJohn Marino char is_valid;
145*e4b17023SJohn Marino char is_speculative;
146*e4b17023SJohn Marino int src_prob;
147*e4b17023SJohn Marino bblst split_bbs;
148*e4b17023SJohn Marino bblst update_bbs;
149*e4b17023SJohn Marino }
150*e4b17023SJohn Marino candidate;
151*e4b17023SJohn Marino
152*e4b17023SJohn Marino static candidate *candidate_table;
153*e4b17023SJohn Marino #define IS_VALID(src) (candidate_table[src].is_valid)
154*e4b17023SJohn Marino #define IS_SPECULATIVE(src) (candidate_table[src].is_speculative)
155*e4b17023SJohn Marino #define IS_SPECULATIVE_INSN(INSN) \
156*e4b17023SJohn Marino (IS_SPECULATIVE (BLOCK_TO_BB (BLOCK_NUM (INSN))))
157*e4b17023SJohn Marino #define SRC_PROB(src) ( candidate_table[src].src_prob )
158*e4b17023SJohn Marino
159*e4b17023SJohn Marino /* The bb being currently scheduled. */
160*e4b17023SJohn Marino int target_bb;
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino /* List of edges. */
163*e4b17023SJohn Marino typedef struct
164*e4b17023SJohn Marino {
165*e4b17023SJohn Marino edge *first_member;
166*e4b17023SJohn Marino int nr_members;
167*e4b17023SJohn Marino }
168*e4b17023SJohn Marino edgelst;
169*e4b17023SJohn Marino
170*e4b17023SJohn Marino static edge *edgelst_table;
171*e4b17023SJohn Marino static int edgelst_last;
172*e4b17023SJohn Marino
173*e4b17023SJohn Marino static void extract_edgelst (sbitmap, edgelst *);
174*e4b17023SJohn Marino
175*e4b17023SJohn Marino /* Target info functions. */
176*e4b17023SJohn Marino static void split_edges (int, int, edgelst *);
177*e4b17023SJohn Marino static void compute_trg_info (int);
178*e4b17023SJohn Marino void debug_candidate (int);
179*e4b17023SJohn Marino void debug_candidates (int);
180*e4b17023SJohn Marino
181*e4b17023SJohn Marino /* Dominators array: dom[i] contains the sbitmap of dominators of
182*e4b17023SJohn Marino bb i in the region. */
183*e4b17023SJohn Marino static sbitmap *dom;
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino /* bb 0 is the only region entry. */
186*e4b17023SJohn Marino #define IS_RGN_ENTRY(bb) (!bb)
187*e4b17023SJohn Marino
188*e4b17023SJohn Marino /* Is bb_src dominated by bb_trg. */
189*e4b17023SJohn Marino #define IS_DOMINATED(bb_src, bb_trg) \
190*e4b17023SJohn Marino ( TEST_BIT (dom[bb_src], bb_trg) )
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino /* Probability: Prob[i] is an int in [0, REG_BR_PROB_BASE] which is
193*e4b17023SJohn Marino the probability of bb i relative to the region entry. */
194*e4b17023SJohn Marino static int *prob;
195*e4b17023SJohn Marino
196*e4b17023SJohn Marino /* Bit-set of edges, where bit i stands for edge i. */
197*e4b17023SJohn Marino typedef sbitmap edgeset;
198*e4b17023SJohn Marino
199*e4b17023SJohn Marino /* Number of edges in the region. */
200*e4b17023SJohn Marino static int rgn_nr_edges;
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino /* Array of size rgn_nr_edges. */
203*e4b17023SJohn Marino static edge *rgn_edges;
204*e4b17023SJohn Marino
205*e4b17023SJohn Marino /* Mapping from each edge in the graph to its number in the rgn. */
206*e4b17023SJohn Marino #define EDGE_TO_BIT(edge) ((int)(size_t)(edge)->aux)
207*e4b17023SJohn Marino #define SET_EDGE_TO_BIT(edge,nr) ((edge)->aux = (void *)(size_t)(nr))
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino /* The split edges of a source bb is different for each target
210*e4b17023SJohn Marino bb. In order to compute this efficiently, the 'potential-split edges'
211*e4b17023SJohn Marino are computed for each bb prior to scheduling a region. This is actually
212*e4b17023SJohn Marino the split edges of each bb relative to the region entry.
213*e4b17023SJohn Marino
214*e4b17023SJohn Marino pot_split[bb] is the set of potential split edges of bb. */
215*e4b17023SJohn Marino static edgeset *pot_split;
216*e4b17023SJohn Marino
217*e4b17023SJohn Marino /* For every bb, a set of its ancestor edges. */
218*e4b17023SJohn Marino static edgeset *ancestor_edges;
219*e4b17023SJohn Marino
220*e4b17023SJohn Marino #define INSN_PROBABILITY(INSN) (SRC_PROB (BLOCK_TO_BB (BLOCK_NUM (INSN))))
221*e4b17023SJohn Marino
222*e4b17023SJohn Marino /* Speculative scheduling functions. */
223*e4b17023SJohn Marino static int check_live_1 (int, rtx);
224*e4b17023SJohn Marino static void update_live_1 (int, rtx);
225*e4b17023SJohn Marino static int is_pfree (rtx, int, int);
226*e4b17023SJohn Marino static int find_conditional_protection (rtx, int);
227*e4b17023SJohn Marino static int is_conditionally_protected (rtx, int, int);
228*e4b17023SJohn Marino static int is_prisky (rtx, int, int);
229*e4b17023SJohn Marino static int is_exception_free (rtx, int, int);
230*e4b17023SJohn Marino
231*e4b17023SJohn Marino static bool sets_likely_spilled (rtx);
232*e4b17023SJohn Marino static void sets_likely_spilled_1 (rtx, const_rtx, void *);
233*e4b17023SJohn Marino static void add_branch_dependences (rtx, rtx);
234*e4b17023SJohn Marino static void compute_block_dependences (int);
235*e4b17023SJohn Marino
236*e4b17023SJohn Marino static void schedule_region (int);
237*e4b17023SJohn Marino static void concat_insn_mem_list (rtx, rtx, rtx *, rtx *);
238*e4b17023SJohn Marino static void propagate_deps (int, struct deps_desc *);
239*e4b17023SJohn Marino static void free_pending_lists (void);
240*e4b17023SJohn Marino
241*e4b17023SJohn Marino /* Functions for construction of the control flow graph. */
242*e4b17023SJohn Marino
243*e4b17023SJohn Marino /* Return 1 if control flow graph should not be constructed, 0 otherwise.
244*e4b17023SJohn Marino
245*e4b17023SJohn Marino We decide not to build the control flow graph if there is possibly more
246*e4b17023SJohn Marino than one entry to the function, if computed branches exist, if we
247*e4b17023SJohn Marino have nonlocal gotos, or if we have an unreachable loop. */
248*e4b17023SJohn Marino
249*e4b17023SJohn Marino static int
is_cfg_nonregular(void)250*e4b17023SJohn Marino is_cfg_nonregular (void)
251*e4b17023SJohn Marino {
252*e4b17023SJohn Marino basic_block b;
253*e4b17023SJohn Marino rtx insn;
254*e4b17023SJohn Marino
255*e4b17023SJohn Marino /* If we have a label that could be the target of a nonlocal goto, then
256*e4b17023SJohn Marino the cfg is not well structured. */
257*e4b17023SJohn Marino if (nonlocal_goto_handler_labels)
258*e4b17023SJohn Marino return 1;
259*e4b17023SJohn Marino
260*e4b17023SJohn Marino /* If we have any forced labels, then the cfg is not well structured. */
261*e4b17023SJohn Marino if (forced_labels)
262*e4b17023SJohn Marino return 1;
263*e4b17023SJohn Marino
264*e4b17023SJohn Marino /* If we have exception handlers, then we consider the cfg not well
265*e4b17023SJohn Marino structured. ?!? We should be able to handle this now that we
266*e4b17023SJohn Marino compute an accurate cfg for EH. */
267*e4b17023SJohn Marino if (current_function_has_exception_handlers ())
268*e4b17023SJohn Marino return 1;
269*e4b17023SJohn Marino
270*e4b17023SJohn Marino /* If we have insns which refer to labels as non-jumped-to operands,
271*e4b17023SJohn Marino then we consider the cfg not well structured. */
272*e4b17023SJohn Marino FOR_EACH_BB (b)
273*e4b17023SJohn Marino FOR_BB_INSNS (b, insn)
274*e4b17023SJohn Marino {
275*e4b17023SJohn Marino rtx note, next, set, dest;
276*e4b17023SJohn Marino
277*e4b17023SJohn Marino /* If this function has a computed jump, then we consider the cfg
278*e4b17023SJohn Marino not well structured. */
279*e4b17023SJohn Marino if (JUMP_P (insn) && computed_jump_p (insn))
280*e4b17023SJohn Marino return 1;
281*e4b17023SJohn Marino
282*e4b17023SJohn Marino if (!INSN_P (insn))
283*e4b17023SJohn Marino continue;
284*e4b17023SJohn Marino
285*e4b17023SJohn Marino note = find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX);
286*e4b17023SJohn Marino if (note == NULL_RTX)
287*e4b17023SJohn Marino continue;
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino /* For that label not to be seen as a referred-to label, this
290*e4b17023SJohn Marino must be a single-set which is feeding a jump *only*. This
291*e4b17023SJohn Marino could be a conditional jump with the label split off for
292*e4b17023SJohn Marino machine-specific reasons or a casesi/tablejump. */
293*e4b17023SJohn Marino next = next_nonnote_insn (insn);
294*e4b17023SJohn Marino if (next == NULL_RTX
295*e4b17023SJohn Marino || !JUMP_P (next)
296*e4b17023SJohn Marino || (JUMP_LABEL (next) != XEXP (note, 0)
297*e4b17023SJohn Marino && find_reg_note (next, REG_LABEL_TARGET,
298*e4b17023SJohn Marino XEXP (note, 0)) == NULL_RTX)
299*e4b17023SJohn Marino || BLOCK_FOR_INSN (insn) != BLOCK_FOR_INSN (next))
300*e4b17023SJohn Marino return 1;
301*e4b17023SJohn Marino
302*e4b17023SJohn Marino set = single_set (insn);
303*e4b17023SJohn Marino if (set == NULL_RTX)
304*e4b17023SJohn Marino return 1;
305*e4b17023SJohn Marino
306*e4b17023SJohn Marino dest = SET_DEST (set);
307*e4b17023SJohn Marino if (!REG_P (dest) || !dead_or_set_p (next, dest))
308*e4b17023SJohn Marino return 1;
309*e4b17023SJohn Marino }
310*e4b17023SJohn Marino
311*e4b17023SJohn Marino /* Unreachable loops with more than one basic block are detected
312*e4b17023SJohn Marino during the DFS traversal in find_rgns.
313*e4b17023SJohn Marino
314*e4b17023SJohn Marino Unreachable loops with a single block are detected here. This
315*e4b17023SJohn Marino test is redundant with the one in find_rgns, but it's much
316*e4b17023SJohn Marino cheaper to go ahead and catch the trivial case here. */
317*e4b17023SJohn Marino FOR_EACH_BB (b)
318*e4b17023SJohn Marino {
319*e4b17023SJohn Marino if (EDGE_COUNT (b->preds) == 0
320*e4b17023SJohn Marino || (single_pred_p (b)
321*e4b17023SJohn Marino && single_pred (b) == b))
322*e4b17023SJohn Marino return 1;
323*e4b17023SJohn Marino }
324*e4b17023SJohn Marino
325*e4b17023SJohn Marino /* All the tests passed. Consider the cfg well structured. */
326*e4b17023SJohn Marino return 0;
327*e4b17023SJohn Marino }
328*e4b17023SJohn Marino
329*e4b17023SJohn Marino /* Extract list of edges from a bitmap containing EDGE_TO_BIT bits. */
330*e4b17023SJohn Marino
331*e4b17023SJohn Marino static void
extract_edgelst(sbitmap set,edgelst * el)332*e4b17023SJohn Marino extract_edgelst (sbitmap set, edgelst *el)
333*e4b17023SJohn Marino {
334*e4b17023SJohn Marino unsigned int i = 0;
335*e4b17023SJohn Marino sbitmap_iterator sbi;
336*e4b17023SJohn Marino
337*e4b17023SJohn Marino /* edgelst table space is reused in each call to extract_edgelst. */
338*e4b17023SJohn Marino edgelst_last = 0;
339*e4b17023SJohn Marino
340*e4b17023SJohn Marino el->first_member = &edgelst_table[edgelst_last];
341*e4b17023SJohn Marino el->nr_members = 0;
342*e4b17023SJohn Marino
343*e4b17023SJohn Marino /* Iterate over each word in the bitset. */
344*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SBITMAP (set, 0, i, sbi)
345*e4b17023SJohn Marino {
346*e4b17023SJohn Marino edgelst_table[edgelst_last++] = rgn_edges[i];
347*e4b17023SJohn Marino el->nr_members++;
348*e4b17023SJohn Marino }
349*e4b17023SJohn Marino }
350*e4b17023SJohn Marino
351*e4b17023SJohn Marino /* Functions for the construction of regions. */
352*e4b17023SJohn Marino
353*e4b17023SJohn Marino /* Print the regions, for debugging purposes. Callable from debugger. */
354*e4b17023SJohn Marino
355*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_regions(void)356*e4b17023SJohn Marino debug_regions (void)
357*e4b17023SJohn Marino {
358*e4b17023SJohn Marino int rgn, bb;
359*e4b17023SJohn Marino
360*e4b17023SJohn Marino fprintf (sched_dump, "\n;; ------------ REGIONS ----------\n\n");
361*e4b17023SJohn Marino for (rgn = 0; rgn < nr_regions; rgn++)
362*e4b17023SJohn Marino {
363*e4b17023SJohn Marino fprintf (sched_dump, ";;\trgn %d nr_blocks %d:\n", rgn,
364*e4b17023SJohn Marino rgn_table[rgn].rgn_nr_blocks);
365*e4b17023SJohn Marino fprintf (sched_dump, ";;\tbb/block: ");
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino /* We don't have ebb_head initialized yet, so we can't use
368*e4b17023SJohn Marino BB_TO_BLOCK (). */
369*e4b17023SJohn Marino current_blocks = RGN_BLOCKS (rgn);
370*e4b17023SJohn Marino
371*e4b17023SJohn Marino for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++)
372*e4b17023SJohn Marino fprintf (sched_dump, " %d/%d ", bb, rgn_bb_table[current_blocks + bb]);
373*e4b17023SJohn Marino
374*e4b17023SJohn Marino fprintf (sched_dump, "\n\n");
375*e4b17023SJohn Marino }
376*e4b17023SJohn Marino }
377*e4b17023SJohn Marino
378*e4b17023SJohn Marino /* Print the region's basic blocks. */
379*e4b17023SJohn Marino
380*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_region(int rgn)381*e4b17023SJohn Marino debug_region (int rgn)
382*e4b17023SJohn Marino {
383*e4b17023SJohn Marino int bb;
384*e4b17023SJohn Marino
385*e4b17023SJohn Marino fprintf (stderr, "\n;; ------------ REGION %d ----------\n\n", rgn);
386*e4b17023SJohn Marino fprintf (stderr, ";;\trgn %d nr_blocks %d:\n", rgn,
387*e4b17023SJohn Marino rgn_table[rgn].rgn_nr_blocks);
388*e4b17023SJohn Marino fprintf (stderr, ";;\tbb/block: ");
389*e4b17023SJohn Marino
390*e4b17023SJohn Marino /* We don't have ebb_head initialized yet, so we can't use
391*e4b17023SJohn Marino BB_TO_BLOCK (). */
392*e4b17023SJohn Marino current_blocks = RGN_BLOCKS (rgn);
393*e4b17023SJohn Marino
394*e4b17023SJohn Marino for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++)
395*e4b17023SJohn Marino fprintf (stderr, " %d/%d ", bb, rgn_bb_table[current_blocks + bb]);
396*e4b17023SJohn Marino
397*e4b17023SJohn Marino fprintf (stderr, "\n\n");
398*e4b17023SJohn Marino
399*e4b17023SJohn Marino for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++)
400*e4b17023SJohn Marino {
401*e4b17023SJohn Marino debug_bb_n_slim (rgn_bb_table[current_blocks + bb]);
402*e4b17023SJohn Marino fprintf (stderr, "\n");
403*e4b17023SJohn Marino }
404*e4b17023SJohn Marino
405*e4b17023SJohn Marino fprintf (stderr, "\n");
406*e4b17023SJohn Marino
407*e4b17023SJohn Marino }
408*e4b17023SJohn Marino
409*e4b17023SJohn Marino /* True when a bb with index BB_INDEX contained in region RGN. */
410*e4b17023SJohn Marino static bool
bb_in_region_p(int bb_index,int rgn)411*e4b17023SJohn Marino bb_in_region_p (int bb_index, int rgn)
412*e4b17023SJohn Marino {
413*e4b17023SJohn Marino int i;
414*e4b17023SJohn Marino
415*e4b17023SJohn Marino for (i = 0; i < rgn_table[rgn].rgn_nr_blocks; i++)
416*e4b17023SJohn Marino if (rgn_bb_table[current_blocks + i] == bb_index)
417*e4b17023SJohn Marino return true;
418*e4b17023SJohn Marino
419*e4b17023SJohn Marino return false;
420*e4b17023SJohn Marino }
421*e4b17023SJohn Marino
422*e4b17023SJohn Marino /* Dump region RGN to file F using dot syntax. */
423*e4b17023SJohn Marino void
dump_region_dot(FILE * f,int rgn)424*e4b17023SJohn Marino dump_region_dot (FILE *f, int rgn)
425*e4b17023SJohn Marino {
426*e4b17023SJohn Marino int i;
427*e4b17023SJohn Marino
428*e4b17023SJohn Marino fprintf (f, "digraph Region_%d {\n", rgn);
429*e4b17023SJohn Marino
430*e4b17023SJohn Marino /* We don't have ebb_head initialized yet, so we can't use
431*e4b17023SJohn Marino BB_TO_BLOCK (). */
432*e4b17023SJohn Marino current_blocks = RGN_BLOCKS (rgn);
433*e4b17023SJohn Marino
434*e4b17023SJohn Marino for (i = 0; i < rgn_table[rgn].rgn_nr_blocks; i++)
435*e4b17023SJohn Marino {
436*e4b17023SJohn Marino edge e;
437*e4b17023SJohn Marino edge_iterator ei;
438*e4b17023SJohn Marino int src_bb_num = rgn_bb_table[current_blocks + i];
439*e4b17023SJohn Marino struct basic_block_def *bb = BASIC_BLOCK (src_bb_num);
440*e4b17023SJohn Marino
441*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
442*e4b17023SJohn Marino if (bb_in_region_p (e->dest->index, rgn))
443*e4b17023SJohn Marino fprintf (f, "\t%d -> %d\n", src_bb_num, e->dest->index);
444*e4b17023SJohn Marino }
445*e4b17023SJohn Marino fprintf (f, "}\n");
446*e4b17023SJohn Marino }
447*e4b17023SJohn Marino
448*e4b17023SJohn Marino /* The same, but first open a file specified by FNAME. */
449*e4b17023SJohn Marino void
dump_region_dot_file(const char * fname,int rgn)450*e4b17023SJohn Marino dump_region_dot_file (const char *fname, int rgn)
451*e4b17023SJohn Marino {
452*e4b17023SJohn Marino FILE *f = fopen (fname, "wt");
453*e4b17023SJohn Marino dump_region_dot (f, rgn);
454*e4b17023SJohn Marino fclose (f);
455*e4b17023SJohn Marino }
456*e4b17023SJohn Marino
457*e4b17023SJohn Marino /* Build a single block region for each basic block in the function.
458*e4b17023SJohn Marino This allows for using the same code for interblock and basic block
459*e4b17023SJohn Marino scheduling. */
460*e4b17023SJohn Marino
461*e4b17023SJohn Marino static void
find_single_block_region(bool ebbs_p)462*e4b17023SJohn Marino find_single_block_region (bool ebbs_p)
463*e4b17023SJohn Marino {
464*e4b17023SJohn Marino basic_block bb, ebb_start;
465*e4b17023SJohn Marino int i = 0;
466*e4b17023SJohn Marino
467*e4b17023SJohn Marino nr_regions = 0;
468*e4b17023SJohn Marino
469*e4b17023SJohn Marino if (ebbs_p) {
470*e4b17023SJohn Marino int probability_cutoff;
471*e4b17023SJohn Marino if (profile_info && flag_branch_probabilities)
472*e4b17023SJohn Marino probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
473*e4b17023SJohn Marino else
474*e4b17023SJohn Marino probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
475*e4b17023SJohn Marino probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
476*e4b17023SJohn Marino
477*e4b17023SJohn Marino FOR_EACH_BB (ebb_start)
478*e4b17023SJohn Marino {
479*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = 0;
480*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = i;
481*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
482*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
483*e4b17023SJohn Marino
484*e4b17023SJohn Marino for (bb = ebb_start; ; bb = bb->next_bb)
485*e4b17023SJohn Marino {
486*e4b17023SJohn Marino edge e;
487*e4b17023SJohn Marino
488*e4b17023SJohn Marino rgn_bb_table[i] = bb->index;
489*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions)++;
490*e4b17023SJohn Marino CONTAINING_RGN (bb->index) = nr_regions;
491*e4b17023SJohn Marino BLOCK_TO_BB (bb->index) = i - RGN_BLOCKS (nr_regions);
492*e4b17023SJohn Marino i++;
493*e4b17023SJohn Marino
494*e4b17023SJohn Marino if (bb->next_bb == EXIT_BLOCK_PTR
495*e4b17023SJohn Marino || LABEL_P (BB_HEAD (bb->next_bb)))
496*e4b17023SJohn Marino break;
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino e = find_fallthru_edge (bb->succs);
499*e4b17023SJohn Marino if (! e)
500*e4b17023SJohn Marino break;
501*e4b17023SJohn Marino if (e->probability <= probability_cutoff)
502*e4b17023SJohn Marino break;
503*e4b17023SJohn Marino }
504*e4b17023SJohn Marino
505*e4b17023SJohn Marino ebb_start = bb;
506*e4b17023SJohn Marino nr_regions++;
507*e4b17023SJohn Marino }
508*e4b17023SJohn Marino }
509*e4b17023SJohn Marino else
510*e4b17023SJohn Marino FOR_EACH_BB (bb)
511*e4b17023SJohn Marino {
512*e4b17023SJohn Marino rgn_bb_table[nr_regions] = bb->index;
513*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = 1;
514*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = nr_regions;
515*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
516*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino CONTAINING_RGN (bb->index) = nr_regions;
519*e4b17023SJohn Marino BLOCK_TO_BB (bb->index) = 0;
520*e4b17023SJohn Marino nr_regions++;
521*e4b17023SJohn Marino }
522*e4b17023SJohn Marino }
523*e4b17023SJohn Marino
524*e4b17023SJohn Marino /* Estimate number of the insns in the BB. */
525*e4b17023SJohn Marino static int
rgn_estimate_number_of_insns(basic_block bb)526*e4b17023SJohn Marino rgn_estimate_number_of_insns (basic_block bb)
527*e4b17023SJohn Marino {
528*e4b17023SJohn Marino int count;
529*e4b17023SJohn Marino
530*e4b17023SJohn Marino count = INSN_LUID (BB_END (bb)) - INSN_LUID (BB_HEAD (bb));
531*e4b17023SJohn Marino
532*e4b17023SJohn Marino if (MAY_HAVE_DEBUG_INSNS)
533*e4b17023SJohn Marino {
534*e4b17023SJohn Marino rtx insn;
535*e4b17023SJohn Marino
536*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn)
537*e4b17023SJohn Marino if (DEBUG_INSN_P (insn))
538*e4b17023SJohn Marino count--;
539*e4b17023SJohn Marino }
540*e4b17023SJohn Marino
541*e4b17023SJohn Marino return count;
542*e4b17023SJohn Marino }
543*e4b17023SJohn Marino
544*e4b17023SJohn Marino /* Update number of blocks and the estimate for number of insns
545*e4b17023SJohn Marino in the region. Return true if the region is "too large" for interblock
546*e4b17023SJohn Marino scheduling (compile time considerations). */
547*e4b17023SJohn Marino
548*e4b17023SJohn Marino static bool
too_large(int block,int * num_bbs,int * num_insns)549*e4b17023SJohn Marino too_large (int block, int *num_bbs, int *num_insns)
550*e4b17023SJohn Marino {
551*e4b17023SJohn Marino (*num_bbs)++;
552*e4b17023SJohn Marino (*num_insns) += (common_sched_info->estimate_number_of_insns
553*e4b17023SJohn Marino (BASIC_BLOCK (block)));
554*e4b17023SJohn Marino
555*e4b17023SJohn Marino return ((*num_bbs > PARAM_VALUE (PARAM_MAX_SCHED_REGION_BLOCKS))
556*e4b17023SJohn Marino || (*num_insns > PARAM_VALUE (PARAM_MAX_SCHED_REGION_INSNS)));
557*e4b17023SJohn Marino }
558*e4b17023SJohn Marino
559*e4b17023SJohn Marino /* Update_loop_relations(blk, hdr): Check if the loop headed by max_hdr[blk]
560*e4b17023SJohn Marino is still an inner loop. Put in max_hdr[blk] the header of the most inner
561*e4b17023SJohn Marino loop containing blk. */
562*e4b17023SJohn Marino #define UPDATE_LOOP_RELATIONS(blk, hdr) \
563*e4b17023SJohn Marino { \
564*e4b17023SJohn Marino if (max_hdr[blk] == -1) \
565*e4b17023SJohn Marino max_hdr[blk] = hdr; \
566*e4b17023SJohn Marino else if (dfs_nr[max_hdr[blk]] > dfs_nr[hdr]) \
567*e4b17023SJohn Marino RESET_BIT (inner, hdr); \
568*e4b17023SJohn Marino else if (dfs_nr[max_hdr[blk]] < dfs_nr[hdr]) \
569*e4b17023SJohn Marino { \
570*e4b17023SJohn Marino RESET_BIT (inner,max_hdr[blk]); \
571*e4b17023SJohn Marino max_hdr[blk] = hdr; \
572*e4b17023SJohn Marino } \
573*e4b17023SJohn Marino }
574*e4b17023SJohn Marino
575*e4b17023SJohn Marino /* Find regions for interblock scheduling.
576*e4b17023SJohn Marino
577*e4b17023SJohn Marino A region for scheduling can be:
578*e4b17023SJohn Marino
579*e4b17023SJohn Marino * A loop-free procedure, or
580*e4b17023SJohn Marino
581*e4b17023SJohn Marino * A reducible inner loop, or
582*e4b17023SJohn Marino
583*e4b17023SJohn Marino * A basic block not contained in any other region.
584*e4b17023SJohn Marino
585*e4b17023SJohn Marino ?!? In theory we could build other regions based on extended basic
586*e4b17023SJohn Marino blocks or reverse extended basic blocks. Is it worth the trouble?
587*e4b17023SJohn Marino
588*e4b17023SJohn Marino Loop blocks that form a region are put into the region's block list
589*e4b17023SJohn Marino in topological order.
590*e4b17023SJohn Marino
591*e4b17023SJohn Marino This procedure stores its results into the following global (ick) variables
592*e4b17023SJohn Marino
593*e4b17023SJohn Marino * rgn_nr
594*e4b17023SJohn Marino * rgn_table
595*e4b17023SJohn Marino * rgn_bb_table
596*e4b17023SJohn Marino * block_to_bb
597*e4b17023SJohn Marino * containing region
598*e4b17023SJohn Marino
599*e4b17023SJohn Marino We use dominator relationships to avoid making regions out of non-reducible
600*e4b17023SJohn Marino loops.
601*e4b17023SJohn Marino
602*e4b17023SJohn Marino This procedure needs to be converted to work on pred/succ lists instead
603*e4b17023SJohn Marino of edge tables. That would simplify it somewhat. */
604*e4b17023SJohn Marino
605*e4b17023SJohn Marino static void
haifa_find_rgns(void)606*e4b17023SJohn Marino haifa_find_rgns (void)
607*e4b17023SJohn Marino {
608*e4b17023SJohn Marino int *max_hdr, *dfs_nr, *degree;
609*e4b17023SJohn Marino char no_loops = 1;
610*e4b17023SJohn Marino int node, child, loop_head, i, head, tail;
611*e4b17023SJohn Marino int count = 0, sp, idx = 0;
612*e4b17023SJohn Marino edge_iterator current_edge;
613*e4b17023SJohn Marino edge_iterator *stack;
614*e4b17023SJohn Marino int num_bbs, num_insns, unreachable;
615*e4b17023SJohn Marino int too_large_failure;
616*e4b17023SJohn Marino basic_block bb;
617*e4b17023SJohn Marino
618*e4b17023SJohn Marino /* Note if a block is a natural loop header. */
619*e4b17023SJohn Marino sbitmap header;
620*e4b17023SJohn Marino
621*e4b17023SJohn Marino /* Note if a block is a natural inner loop header. */
622*e4b17023SJohn Marino sbitmap inner;
623*e4b17023SJohn Marino
624*e4b17023SJohn Marino /* Note if a block is in the block queue. */
625*e4b17023SJohn Marino sbitmap in_queue;
626*e4b17023SJohn Marino
627*e4b17023SJohn Marino /* Note if a block is in the block queue. */
628*e4b17023SJohn Marino sbitmap in_stack;
629*e4b17023SJohn Marino
630*e4b17023SJohn Marino /* Perform a DFS traversal of the cfg. Identify loop headers, inner loops
631*e4b17023SJohn Marino and a mapping from block to its loop header (if the block is contained
632*e4b17023SJohn Marino in a loop, else -1).
633*e4b17023SJohn Marino
634*e4b17023SJohn Marino Store results in HEADER, INNER, and MAX_HDR respectively, these will
635*e4b17023SJohn Marino be used as inputs to the second traversal.
636*e4b17023SJohn Marino
637*e4b17023SJohn Marino STACK, SP and DFS_NR are only used during the first traversal. */
638*e4b17023SJohn Marino
639*e4b17023SJohn Marino /* Allocate and initialize variables for the first traversal. */
640*e4b17023SJohn Marino max_hdr = XNEWVEC (int, last_basic_block);
641*e4b17023SJohn Marino dfs_nr = XCNEWVEC (int, last_basic_block);
642*e4b17023SJohn Marino stack = XNEWVEC (edge_iterator, n_edges);
643*e4b17023SJohn Marino
644*e4b17023SJohn Marino inner = sbitmap_alloc (last_basic_block);
645*e4b17023SJohn Marino sbitmap_ones (inner);
646*e4b17023SJohn Marino
647*e4b17023SJohn Marino header = sbitmap_alloc (last_basic_block);
648*e4b17023SJohn Marino sbitmap_zero (header);
649*e4b17023SJohn Marino
650*e4b17023SJohn Marino in_queue = sbitmap_alloc (last_basic_block);
651*e4b17023SJohn Marino sbitmap_zero (in_queue);
652*e4b17023SJohn Marino
653*e4b17023SJohn Marino in_stack = sbitmap_alloc (last_basic_block);
654*e4b17023SJohn Marino sbitmap_zero (in_stack);
655*e4b17023SJohn Marino
656*e4b17023SJohn Marino for (i = 0; i < last_basic_block; i++)
657*e4b17023SJohn Marino max_hdr[i] = -1;
658*e4b17023SJohn Marino
659*e4b17023SJohn Marino #define EDGE_PASSED(E) (ei_end_p ((E)) || ei_edge ((E))->aux)
660*e4b17023SJohn Marino #define SET_EDGE_PASSED(E) (ei_edge ((E))->aux = ei_edge ((E)))
661*e4b17023SJohn Marino
662*e4b17023SJohn Marino /* DFS traversal to find inner loops in the cfg. */
663*e4b17023SJohn Marino
664*e4b17023SJohn Marino current_edge = ei_start (single_succ (ENTRY_BLOCK_PTR)->succs);
665*e4b17023SJohn Marino sp = -1;
666*e4b17023SJohn Marino
667*e4b17023SJohn Marino while (1)
668*e4b17023SJohn Marino {
669*e4b17023SJohn Marino if (EDGE_PASSED (current_edge))
670*e4b17023SJohn Marino {
671*e4b17023SJohn Marino /* We have reached a leaf node or a node that was already
672*e4b17023SJohn Marino processed. Pop edges off the stack until we find
673*e4b17023SJohn Marino an edge that has not yet been processed. */
674*e4b17023SJohn Marino while (sp >= 0 && EDGE_PASSED (current_edge))
675*e4b17023SJohn Marino {
676*e4b17023SJohn Marino /* Pop entry off the stack. */
677*e4b17023SJohn Marino current_edge = stack[sp--];
678*e4b17023SJohn Marino node = ei_edge (current_edge)->src->index;
679*e4b17023SJohn Marino gcc_assert (node != ENTRY_BLOCK);
680*e4b17023SJohn Marino child = ei_edge (current_edge)->dest->index;
681*e4b17023SJohn Marino gcc_assert (child != EXIT_BLOCK);
682*e4b17023SJohn Marino RESET_BIT (in_stack, child);
683*e4b17023SJohn Marino if (max_hdr[child] >= 0 && TEST_BIT (in_stack, max_hdr[child]))
684*e4b17023SJohn Marino UPDATE_LOOP_RELATIONS (node, max_hdr[child]);
685*e4b17023SJohn Marino ei_next (¤t_edge);
686*e4b17023SJohn Marino }
687*e4b17023SJohn Marino
688*e4b17023SJohn Marino /* See if have finished the DFS tree traversal. */
689*e4b17023SJohn Marino if (sp < 0 && EDGE_PASSED (current_edge))
690*e4b17023SJohn Marino break;
691*e4b17023SJohn Marino
692*e4b17023SJohn Marino /* Nope, continue the traversal with the popped node. */
693*e4b17023SJohn Marino continue;
694*e4b17023SJohn Marino }
695*e4b17023SJohn Marino
696*e4b17023SJohn Marino /* Process a node. */
697*e4b17023SJohn Marino node = ei_edge (current_edge)->src->index;
698*e4b17023SJohn Marino gcc_assert (node != ENTRY_BLOCK);
699*e4b17023SJohn Marino SET_BIT (in_stack, node);
700*e4b17023SJohn Marino dfs_nr[node] = ++count;
701*e4b17023SJohn Marino
702*e4b17023SJohn Marino /* We don't traverse to the exit block. */
703*e4b17023SJohn Marino child = ei_edge (current_edge)->dest->index;
704*e4b17023SJohn Marino if (child == EXIT_BLOCK)
705*e4b17023SJohn Marino {
706*e4b17023SJohn Marino SET_EDGE_PASSED (current_edge);
707*e4b17023SJohn Marino ei_next (¤t_edge);
708*e4b17023SJohn Marino continue;
709*e4b17023SJohn Marino }
710*e4b17023SJohn Marino
711*e4b17023SJohn Marino /* If the successor is in the stack, then we've found a loop.
712*e4b17023SJohn Marino Mark the loop, if it is not a natural loop, then it will
713*e4b17023SJohn Marino be rejected during the second traversal. */
714*e4b17023SJohn Marino if (TEST_BIT (in_stack, child))
715*e4b17023SJohn Marino {
716*e4b17023SJohn Marino no_loops = 0;
717*e4b17023SJohn Marino SET_BIT (header, child);
718*e4b17023SJohn Marino UPDATE_LOOP_RELATIONS (node, child);
719*e4b17023SJohn Marino SET_EDGE_PASSED (current_edge);
720*e4b17023SJohn Marino ei_next (¤t_edge);
721*e4b17023SJohn Marino continue;
722*e4b17023SJohn Marino }
723*e4b17023SJohn Marino
724*e4b17023SJohn Marino /* If the child was already visited, then there is no need to visit
725*e4b17023SJohn Marino it again. Just update the loop relationships and restart
726*e4b17023SJohn Marino with a new edge. */
727*e4b17023SJohn Marino if (dfs_nr[child])
728*e4b17023SJohn Marino {
729*e4b17023SJohn Marino if (max_hdr[child] >= 0 && TEST_BIT (in_stack, max_hdr[child]))
730*e4b17023SJohn Marino UPDATE_LOOP_RELATIONS (node, max_hdr[child]);
731*e4b17023SJohn Marino SET_EDGE_PASSED (current_edge);
732*e4b17023SJohn Marino ei_next (¤t_edge);
733*e4b17023SJohn Marino continue;
734*e4b17023SJohn Marino }
735*e4b17023SJohn Marino
736*e4b17023SJohn Marino /* Push an entry on the stack and continue DFS traversal. */
737*e4b17023SJohn Marino stack[++sp] = current_edge;
738*e4b17023SJohn Marino SET_EDGE_PASSED (current_edge);
739*e4b17023SJohn Marino current_edge = ei_start (ei_edge (current_edge)->dest->succs);
740*e4b17023SJohn Marino }
741*e4b17023SJohn Marino
742*e4b17023SJohn Marino /* Reset ->aux field used by EDGE_PASSED. */
743*e4b17023SJohn Marino FOR_ALL_BB (bb)
744*e4b17023SJohn Marino {
745*e4b17023SJohn Marino edge_iterator ei;
746*e4b17023SJohn Marino edge e;
747*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
748*e4b17023SJohn Marino e->aux = NULL;
749*e4b17023SJohn Marino }
750*e4b17023SJohn Marino
751*e4b17023SJohn Marino
752*e4b17023SJohn Marino /* Another check for unreachable blocks. The earlier test in
753*e4b17023SJohn Marino is_cfg_nonregular only finds unreachable blocks that do not
754*e4b17023SJohn Marino form a loop.
755*e4b17023SJohn Marino
756*e4b17023SJohn Marino The DFS traversal will mark every block that is reachable from
757*e4b17023SJohn Marino the entry node by placing a nonzero value in dfs_nr. Thus if
758*e4b17023SJohn Marino dfs_nr is zero for any block, then it must be unreachable. */
759*e4b17023SJohn Marino unreachable = 0;
760*e4b17023SJohn Marino FOR_EACH_BB (bb)
761*e4b17023SJohn Marino if (dfs_nr[bb->index] == 0)
762*e4b17023SJohn Marino {
763*e4b17023SJohn Marino unreachable = 1;
764*e4b17023SJohn Marino break;
765*e4b17023SJohn Marino }
766*e4b17023SJohn Marino
767*e4b17023SJohn Marino /* Gross. To avoid wasting memory, the second pass uses the dfs_nr array
768*e4b17023SJohn Marino to hold degree counts. */
769*e4b17023SJohn Marino degree = dfs_nr;
770*e4b17023SJohn Marino
771*e4b17023SJohn Marino FOR_EACH_BB (bb)
772*e4b17023SJohn Marino degree[bb->index] = EDGE_COUNT (bb->preds);
773*e4b17023SJohn Marino
774*e4b17023SJohn Marino /* Do not perform region scheduling if there are any unreachable
775*e4b17023SJohn Marino blocks. */
776*e4b17023SJohn Marino if (!unreachable)
777*e4b17023SJohn Marino {
778*e4b17023SJohn Marino int *queue, *degree1 = NULL;
779*e4b17023SJohn Marino /* We use EXTENDED_RGN_HEADER as an addition to HEADER and put
780*e4b17023SJohn Marino there basic blocks, which are forced to be region heads.
781*e4b17023SJohn Marino This is done to try to assemble few smaller regions
782*e4b17023SJohn Marino from a too_large region. */
783*e4b17023SJohn Marino sbitmap extended_rgn_header = NULL;
784*e4b17023SJohn Marino bool extend_regions_p;
785*e4b17023SJohn Marino
786*e4b17023SJohn Marino if (no_loops)
787*e4b17023SJohn Marino SET_BIT (header, 0);
788*e4b17023SJohn Marino
789*e4b17023SJohn Marino /* Second traversal:find reducible inner loops and topologically sort
790*e4b17023SJohn Marino block of each region. */
791*e4b17023SJohn Marino
792*e4b17023SJohn Marino queue = XNEWVEC (int, n_basic_blocks);
793*e4b17023SJohn Marino
794*e4b17023SJohn Marino extend_regions_p = PARAM_VALUE (PARAM_MAX_SCHED_EXTEND_REGIONS_ITERS) > 0;
795*e4b17023SJohn Marino if (extend_regions_p)
796*e4b17023SJohn Marino {
797*e4b17023SJohn Marino degree1 = XNEWVEC (int, last_basic_block);
798*e4b17023SJohn Marino extended_rgn_header = sbitmap_alloc (last_basic_block);
799*e4b17023SJohn Marino sbitmap_zero (extended_rgn_header);
800*e4b17023SJohn Marino }
801*e4b17023SJohn Marino
802*e4b17023SJohn Marino /* Find blocks which are inner loop headers. We still have non-reducible
803*e4b17023SJohn Marino loops to consider at this point. */
804*e4b17023SJohn Marino FOR_EACH_BB (bb)
805*e4b17023SJohn Marino {
806*e4b17023SJohn Marino if (TEST_BIT (header, bb->index) && TEST_BIT (inner, bb->index))
807*e4b17023SJohn Marino {
808*e4b17023SJohn Marino edge e;
809*e4b17023SJohn Marino edge_iterator ei;
810*e4b17023SJohn Marino basic_block jbb;
811*e4b17023SJohn Marino
812*e4b17023SJohn Marino /* Now check that the loop is reducible. We do this separate
813*e4b17023SJohn Marino from finding inner loops so that we do not find a reducible
814*e4b17023SJohn Marino loop which contains an inner non-reducible loop.
815*e4b17023SJohn Marino
816*e4b17023SJohn Marino A simple way to find reducible/natural loops is to verify
817*e4b17023SJohn Marino that each block in the loop is dominated by the loop
818*e4b17023SJohn Marino header.
819*e4b17023SJohn Marino
820*e4b17023SJohn Marino If there exists a block that is not dominated by the loop
821*e4b17023SJohn Marino header, then the block is reachable from outside the loop
822*e4b17023SJohn Marino and thus the loop is not a natural loop. */
823*e4b17023SJohn Marino FOR_EACH_BB (jbb)
824*e4b17023SJohn Marino {
825*e4b17023SJohn Marino /* First identify blocks in the loop, except for the loop
826*e4b17023SJohn Marino entry block. */
827*e4b17023SJohn Marino if (bb->index == max_hdr[jbb->index] && bb != jbb)
828*e4b17023SJohn Marino {
829*e4b17023SJohn Marino /* Now verify that the block is dominated by the loop
830*e4b17023SJohn Marino header. */
831*e4b17023SJohn Marino if (!dominated_by_p (CDI_DOMINATORS, jbb, bb))
832*e4b17023SJohn Marino break;
833*e4b17023SJohn Marino }
834*e4b17023SJohn Marino }
835*e4b17023SJohn Marino
836*e4b17023SJohn Marino /* If we exited the loop early, then I is the header of
837*e4b17023SJohn Marino a non-reducible loop and we should quit processing it
838*e4b17023SJohn Marino now. */
839*e4b17023SJohn Marino if (jbb != EXIT_BLOCK_PTR)
840*e4b17023SJohn Marino continue;
841*e4b17023SJohn Marino
842*e4b17023SJohn Marino /* I is a header of an inner loop, or block 0 in a subroutine
843*e4b17023SJohn Marino with no loops at all. */
844*e4b17023SJohn Marino head = tail = -1;
845*e4b17023SJohn Marino too_large_failure = 0;
846*e4b17023SJohn Marino loop_head = max_hdr[bb->index];
847*e4b17023SJohn Marino
848*e4b17023SJohn Marino if (extend_regions_p)
849*e4b17023SJohn Marino /* We save degree in case when we meet a too_large region
850*e4b17023SJohn Marino and cancel it. We need a correct degree later when
851*e4b17023SJohn Marino calling extend_rgns. */
852*e4b17023SJohn Marino memcpy (degree1, degree, last_basic_block * sizeof (int));
853*e4b17023SJohn Marino
854*e4b17023SJohn Marino /* Decrease degree of all I's successors for topological
855*e4b17023SJohn Marino ordering. */
856*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
857*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR)
858*e4b17023SJohn Marino --degree[e->dest->index];
859*e4b17023SJohn Marino
860*e4b17023SJohn Marino /* Estimate # insns, and count # blocks in the region. */
861*e4b17023SJohn Marino num_bbs = 1;
862*e4b17023SJohn Marino num_insns = common_sched_info->estimate_number_of_insns (bb);
863*e4b17023SJohn Marino
864*e4b17023SJohn Marino /* Find all loop latches (blocks with back edges to the loop
865*e4b17023SJohn Marino header) or all the leaf blocks in the cfg has no loops.
866*e4b17023SJohn Marino
867*e4b17023SJohn Marino Place those blocks into the queue. */
868*e4b17023SJohn Marino if (no_loops)
869*e4b17023SJohn Marino {
870*e4b17023SJohn Marino FOR_EACH_BB (jbb)
871*e4b17023SJohn Marino /* Leaf nodes have only a single successor which must
872*e4b17023SJohn Marino be EXIT_BLOCK. */
873*e4b17023SJohn Marino if (single_succ_p (jbb)
874*e4b17023SJohn Marino && single_succ (jbb) == EXIT_BLOCK_PTR)
875*e4b17023SJohn Marino {
876*e4b17023SJohn Marino queue[++tail] = jbb->index;
877*e4b17023SJohn Marino SET_BIT (in_queue, jbb->index);
878*e4b17023SJohn Marino
879*e4b17023SJohn Marino if (too_large (jbb->index, &num_bbs, &num_insns))
880*e4b17023SJohn Marino {
881*e4b17023SJohn Marino too_large_failure = 1;
882*e4b17023SJohn Marino break;
883*e4b17023SJohn Marino }
884*e4b17023SJohn Marino }
885*e4b17023SJohn Marino }
886*e4b17023SJohn Marino else
887*e4b17023SJohn Marino {
888*e4b17023SJohn Marino edge e;
889*e4b17023SJohn Marino
890*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds)
891*e4b17023SJohn Marino {
892*e4b17023SJohn Marino if (e->src == ENTRY_BLOCK_PTR)
893*e4b17023SJohn Marino continue;
894*e4b17023SJohn Marino
895*e4b17023SJohn Marino node = e->src->index;
896*e4b17023SJohn Marino
897*e4b17023SJohn Marino if (max_hdr[node] == loop_head && node != bb->index)
898*e4b17023SJohn Marino {
899*e4b17023SJohn Marino /* This is a loop latch. */
900*e4b17023SJohn Marino queue[++tail] = node;
901*e4b17023SJohn Marino SET_BIT (in_queue, node);
902*e4b17023SJohn Marino
903*e4b17023SJohn Marino if (too_large (node, &num_bbs, &num_insns))
904*e4b17023SJohn Marino {
905*e4b17023SJohn Marino too_large_failure = 1;
906*e4b17023SJohn Marino break;
907*e4b17023SJohn Marino }
908*e4b17023SJohn Marino }
909*e4b17023SJohn Marino }
910*e4b17023SJohn Marino }
911*e4b17023SJohn Marino
912*e4b17023SJohn Marino /* Now add all the blocks in the loop to the queue.
913*e4b17023SJohn Marino
914*e4b17023SJohn Marino We know the loop is a natural loop; however the algorithm
915*e4b17023SJohn Marino above will not always mark certain blocks as being in the
916*e4b17023SJohn Marino loop. Consider:
917*e4b17023SJohn Marino node children
918*e4b17023SJohn Marino a b,c
919*e4b17023SJohn Marino b c
920*e4b17023SJohn Marino c a,d
921*e4b17023SJohn Marino d b
922*e4b17023SJohn Marino
923*e4b17023SJohn Marino The algorithm in the DFS traversal may not mark B & D as part
924*e4b17023SJohn Marino of the loop (i.e. they will not have max_hdr set to A).
925*e4b17023SJohn Marino
926*e4b17023SJohn Marino We know they can not be loop latches (else they would have
927*e4b17023SJohn Marino had max_hdr set since they'd have a backedge to a dominator
928*e4b17023SJohn Marino block). So we don't need them on the initial queue.
929*e4b17023SJohn Marino
930*e4b17023SJohn Marino We know they are part of the loop because they are dominated
931*e4b17023SJohn Marino by the loop header and can be reached by a backwards walk of
932*e4b17023SJohn Marino the edges starting with nodes on the initial queue.
933*e4b17023SJohn Marino
934*e4b17023SJohn Marino It is safe and desirable to include those nodes in the
935*e4b17023SJohn Marino loop/scheduling region. To do so we would need to decrease
936*e4b17023SJohn Marino the degree of a node if it is the target of a backedge
937*e4b17023SJohn Marino within the loop itself as the node is placed in the queue.
938*e4b17023SJohn Marino
939*e4b17023SJohn Marino We do not do this because I'm not sure that the actual
940*e4b17023SJohn Marino scheduling code will properly handle this case. ?!? */
941*e4b17023SJohn Marino
942*e4b17023SJohn Marino while (head < tail && !too_large_failure)
943*e4b17023SJohn Marino {
944*e4b17023SJohn Marino edge e;
945*e4b17023SJohn Marino child = queue[++head];
946*e4b17023SJohn Marino
947*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, BASIC_BLOCK (child)->preds)
948*e4b17023SJohn Marino {
949*e4b17023SJohn Marino node = e->src->index;
950*e4b17023SJohn Marino
951*e4b17023SJohn Marino /* See discussion above about nodes not marked as in
952*e4b17023SJohn Marino this loop during the initial DFS traversal. */
953*e4b17023SJohn Marino if (e->src == ENTRY_BLOCK_PTR
954*e4b17023SJohn Marino || max_hdr[node] != loop_head)
955*e4b17023SJohn Marino {
956*e4b17023SJohn Marino tail = -1;
957*e4b17023SJohn Marino break;
958*e4b17023SJohn Marino }
959*e4b17023SJohn Marino else if (!TEST_BIT (in_queue, node) && node != bb->index)
960*e4b17023SJohn Marino {
961*e4b17023SJohn Marino queue[++tail] = node;
962*e4b17023SJohn Marino SET_BIT (in_queue, node);
963*e4b17023SJohn Marino
964*e4b17023SJohn Marino if (too_large (node, &num_bbs, &num_insns))
965*e4b17023SJohn Marino {
966*e4b17023SJohn Marino too_large_failure = 1;
967*e4b17023SJohn Marino break;
968*e4b17023SJohn Marino }
969*e4b17023SJohn Marino }
970*e4b17023SJohn Marino }
971*e4b17023SJohn Marino }
972*e4b17023SJohn Marino
973*e4b17023SJohn Marino if (tail >= 0 && !too_large_failure)
974*e4b17023SJohn Marino {
975*e4b17023SJohn Marino /* Place the loop header into list of region blocks. */
976*e4b17023SJohn Marino degree[bb->index] = -1;
977*e4b17023SJohn Marino rgn_bb_table[idx] = bb->index;
978*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = num_bbs;
979*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = idx++;
980*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
981*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
982*e4b17023SJohn Marino CONTAINING_RGN (bb->index) = nr_regions;
983*e4b17023SJohn Marino BLOCK_TO_BB (bb->index) = count = 0;
984*e4b17023SJohn Marino
985*e4b17023SJohn Marino /* Remove blocks from queue[] when their in degree
986*e4b17023SJohn Marino becomes zero. Repeat until no blocks are left on the
987*e4b17023SJohn Marino list. This produces a topological list of blocks in
988*e4b17023SJohn Marino the region. */
989*e4b17023SJohn Marino while (tail >= 0)
990*e4b17023SJohn Marino {
991*e4b17023SJohn Marino if (head < 0)
992*e4b17023SJohn Marino head = tail;
993*e4b17023SJohn Marino child = queue[head];
994*e4b17023SJohn Marino if (degree[child] == 0)
995*e4b17023SJohn Marino {
996*e4b17023SJohn Marino edge e;
997*e4b17023SJohn Marino
998*e4b17023SJohn Marino degree[child] = -1;
999*e4b17023SJohn Marino rgn_bb_table[idx++] = child;
1000*e4b17023SJohn Marino BLOCK_TO_BB (child) = ++count;
1001*e4b17023SJohn Marino CONTAINING_RGN (child) = nr_regions;
1002*e4b17023SJohn Marino queue[head] = queue[tail--];
1003*e4b17023SJohn Marino
1004*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, BASIC_BLOCK (child)->succs)
1005*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR)
1006*e4b17023SJohn Marino --degree[e->dest->index];
1007*e4b17023SJohn Marino }
1008*e4b17023SJohn Marino else
1009*e4b17023SJohn Marino --head;
1010*e4b17023SJohn Marino }
1011*e4b17023SJohn Marino ++nr_regions;
1012*e4b17023SJohn Marino }
1013*e4b17023SJohn Marino else if (extend_regions_p)
1014*e4b17023SJohn Marino {
1015*e4b17023SJohn Marino /* Restore DEGREE. */
1016*e4b17023SJohn Marino int *t = degree;
1017*e4b17023SJohn Marino
1018*e4b17023SJohn Marino degree = degree1;
1019*e4b17023SJohn Marino degree1 = t;
1020*e4b17023SJohn Marino
1021*e4b17023SJohn Marino /* And force successors of BB to be region heads.
1022*e4b17023SJohn Marino This may provide several smaller regions instead
1023*e4b17023SJohn Marino of one too_large region. */
1024*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
1025*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR)
1026*e4b17023SJohn Marino SET_BIT (extended_rgn_header, e->dest->index);
1027*e4b17023SJohn Marino }
1028*e4b17023SJohn Marino }
1029*e4b17023SJohn Marino }
1030*e4b17023SJohn Marino free (queue);
1031*e4b17023SJohn Marino
1032*e4b17023SJohn Marino if (extend_regions_p)
1033*e4b17023SJohn Marino {
1034*e4b17023SJohn Marino free (degree1);
1035*e4b17023SJohn Marino
1036*e4b17023SJohn Marino sbitmap_a_or_b (header, header, extended_rgn_header);
1037*e4b17023SJohn Marino sbitmap_free (extended_rgn_header);
1038*e4b17023SJohn Marino
1039*e4b17023SJohn Marino extend_rgns (degree, &idx, header, max_hdr);
1040*e4b17023SJohn Marino }
1041*e4b17023SJohn Marino }
1042*e4b17023SJohn Marino
1043*e4b17023SJohn Marino /* Any block that did not end up in a region is placed into a region
1044*e4b17023SJohn Marino by itself. */
1045*e4b17023SJohn Marino FOR_EACH_BB (bb)
1046*e4b17023SJohn Marino if (degree[bb->index] >= 0)
1047*e4b17023SJohn Marino {
1048*e4b17023SJohn Marino rgn_bb_table[idx] = bb->index;
1049*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = 1;
1050*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = idx++;
1051*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
1052*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
1053*e4b17023SJohn Marino CONTAINING_RGN (bb->index) = nr_regions++;
1054*e4b17023SJohn Marino BLOCK_TO_BB (bb->index) = 0;
1055*e4b17023SJohn Marino }
1056*e4b17023SJohn Marino
1057*e4b17023SJohn Marino free (max_hdr);
1058*e4b17023SJohn Marino free (degree);
1059*e4b17023SJohn Marino free (stack);
1060*e4b17023SJohn Marino sbitmap_free (header);
1061*e4b17023SJohn Marino sbitmap_free (inner);
1062*e4b17023SJohn Marino sbitmap_free (in_queue);
1063*e4b17023SJohn Marino sbitmap_free (in_stack);
1064*e4b17023SJohn Marino }
1065*e4b17023SJohn Marino
1066*e4b17023SJohn Marino
1067*e4b17023SJohn Marino /* Wrapper function.
1068*e4b17023SJohn Marino If FLAG_SEL_SCHED_PIPELINING is set, then use custom function to form
1069*e4b17023SJohn Marino regions. Otherwise just call find_rgns_haifa. */
1070*e4b17023SJohn Marino static void
find_rgns(void)1071*e4b17023SJohn Marino find_rgns (void)
1072*e4b17023SJohn Marino {
1073*e4b17023SJohn Marino if (sel_sched_p () && flag_sel_sched_pipelining)
1074*e4b17023SJohn Marino sel_find_rgns ();
1075*e4b17023SJohn Marino else
1076*e4b17023SJohn Marino haifa_find_rgns ();
1077*e4b17023SJohn Marino }
1078*e4b17023SJohn Marino
1079*e4b17023SJohn Marino static int gather_region_statistics (int **);
1080*e4b17023SJohn Marino static void print_region_statistics (int *, int, int *, int);
1081*e4b17023SJohn Marino
1082*e4b17023SJohn Marino /* Calculate the histogram that shows the number of regions having the
1083*e4b17023SJohn Marino given number of basic blocks, and store it in the RSP array. Return
1084*e4b17023SJohn Marino the size of this array. */
1085*e4b17023SJohn Marino static int
gather_region_statistics(int ** rsp)1086*e4b17023SJohn Marino gather_region_statistics (int **rsp)
1087*e4b17023SJohn Marino {
1088*e4b17023SJohn Marino int i, *a = 0, a_sz = 0;
1089*e4b17023SJohn Marino
1090*e4b17023SJohn Marino /* a[i] is the number of regions that have (i + 1) basic blocks. */
1091*e4b17023SJohn Marino for (i = 0; i < nr_regions; i++)
1092*e4b17023SJohn Marino {
1093*e4b17023SJohn Marino int nr_blocks = RGN_NR_BLOCKS (i);
1094*e4b17023SJohn Marino
1095*e4b17023SJohn Marino gcc_assert (nr_blocks >= 1);
1096*e4b17023SJohn Marino
1097*e4b17023SJohn Marino if (nr_blocks > a_sz)
1098*e4b17023SJohn Marino {
1099*e4b17023SJohn Marino a = XRESIZEVEC (int, a, nr_blocks);
1100*e4b17023SJohn Marino do
1101*e4b17023SJohn Marino a[a_sz++] = 0;
1102*e4b17023SJohn Marino while (a_sz != nr_blocks);
1103*e4b17023SJohn Marino }
1104*e4b17023SJohn Marino
1105*e4b17023SJohn Marino a[nr_blocks - 1]++;
1106*e4b17023SJohn Marino }
1107*e4b17023SJohn Marino
1108*e4b17023SJohn Marino *rsp = a;
1109*e4b17023SJohn Marino return a_sz;
1110*e4b17023SJohn Marino }
1111*e4b17023SJohn Marino
1112*e4b17023SJohn Marino /* Print regions statistics. S1 and S2 denote the data before and after
1113*e4b17023SJohn Marino calling extend_rgns, respectively. */
1114*e4b17023SJohn Marino static void
print_region_statistics(int * s1,int s1_sz,int * s2,int s2_sz)1115*e4b17023SJohn Marino print_region_statistics (int *s1, int s1_sz, int *s2, int s2_sz)
1116*e4b17023SJohn Marino {
1117*e4b17023SJohn Marino int i;
1118*e4b17023SJohn Marino
1119*e4b17023SJohn Marino /* We iterate until s2_sz because extend_rgns does not decrease
1120*e4b17023SJohn Marino the maximal region size. */
1121*e4b17023SJohn Marino for (i = 1; i < s2_sz; i++)
1122*e4b17023SJohn Marino {
1123*e4b17023SJohn Marino int n1, n2;
1124*e4b17023SJohn Marino
1125*e4b17023SJohn Marino n2 = s2[i];
1126*e4b17023SJohn Marino
1127*e4b17023SJohn Marino if (n2 == 0)
1128*e4b17023SJohn Marino continue;
1129*e4b17023SJohn Marino
1130*e4b17023SJohn Marino if (i >= s1_sz)
1131*e4b17023SJohn Marino n1 = 0;
1132*e4b17023SJohn Marino else
1133*e4b17023SJohn Marino n1 = s1[i];
1134*e4b17023SJohn Marino
1135*e4b17023SJohn Marino fprintf (sched_dump, ";; Region extension statistics: size %d: " \
1136*e4b17023SJohn Marino "was %d + %d more\n", i + 1, n1, n2 - n1);
1137*e4b17023SJohn Marino }
1138*e4b17023SJohn Marino }
1139*e4b17023SJohn Marino
1140*e4b17023SJohn Marino /* Extend regions.
1141*e4b17023SJohn Marino DEGREE - Array of incoming edge count, considering only
1142*e4b17023SJohn Marino the edges, that don't have their sources in formed regions yet.
1143*e4b17023SJohn Marino IDXP - pointer to the next available index in rgn_bb_table.
1144*e4b17023SJohn Marino HEADER - set of all region heads.
1145*e4b17023SJohn Marino LOOP_HDR - mapping from block to the containing loop
1146*e4b17023SJohn Marino (two blocks can reside within one region if they have
1147*e4b17023SJohn Marino the same loop header). */
1148*e4b17023SJohn Marino void
extend_rgns(int * degree,int * idxp,sbitmap header,int * loop_hdr)1149*e4b17023SJohn Marino extend_rgns (int *degree, int *idxp, sbitmap header, int *loop_hdr)
1150*e4b17023SJohn Marino {
1151*e4b17023SJohn Marino int *order, i, rescan = 0, idx = *idxp, iter = 0, max_iter, *max_hdr;
1152*e4b17023SJohn Marino int nblocks = n_basic_blocks - NUM_FIXED_BLOCKS;
1153*e4b17023SJohn Marino
1154*e4b17023SJohn Marino max_iter = PARAM_VALUE (PARAM_MAX_SCHED_EXTEND_REGIONS_ITERS);
1155*e4b17023SJohn Marino
1156*e4b17023SJohn Marino max_hdr = XNEWVEC (int, last_basic_block);
1157*e4b17023SJohn Marino
1158*e4b17023SJohn Marino order = XNEWVEC (int, last_basic_block);
1159*e4b17023SJohn Marino post_order_compute (order, false, false);
1160*e4b17023SJohn Marino
1161*e4b17023SJohn Marino for (i = nblocks - 1; i >= 0; i--)
1162*e4b17023SJohn Marino {
1163*e4b17023SJohn Marino int bbn = order[i];
1164*e4b17023SJohn Marino if (degree[bbn] >= 0)
1165*e4b17023SJohn Marino {
1166*e4b17023SJohn Marino max_hdr[bbn] = bbn;
1167*e4b17023SJohn Marino rescan = 1;
1168*e4b17023SJohn Marino }
1169*e4b17023SJohn Marino else
1170*e4b17023SJohn Marino /* This block already was processed in find_rgns. */
1171*e4b17023SJohn Marino max_hdr[bbn] = -1;
1172*e4b17023SJohn Marino }
1173*e4b17023SJohn Marino
1174*e4b17023SJohn Marino /* The idea is to topologically walk through CFG in top-down order.
1175*e4b17023SJohn Marino During the traversal, if all the predecessors of a node are
1176*e4b17023SJohn Marino marked to be in the same region (they all have the same max_hdr),
1177*e4b17023SJohn Marino then current node is also marked to be a part of that region.
1178*e4b17023SJohn Marino Otherwise the node starts its own region.
1179*e4b17023SJohn Marino CFG should be traversed until no further changes are made. On each
1180*e4b17023SJohn Marino iteration the set of the region heads is extended (the set of those
1181*e4b17023SJohn Marino blocks that have max_hdr[bbi] == bbi). This set is upper bounded by the
1182*e4b17023SJohn Marino set of all basic blocks, thus the algorithm is guaranteed to
1183*e4b17023SJohn Marino terminate. */
1184*e4b17023SJohn Marino
1185*e4b17023SJohn Marino while (rescan && iter < max_iter)
1186*e4b17023SJohn Marino {
1187*e4b17023SJohn Marino rescan = 0;
1188*e4b17023SJohn Marino
1189*e4b17023SJohn Marino for (i = nblocks - 1; i >= 0; i--)
1190*e4b17023SJohn Marino {
1191*e4b17023SJohn Marino edge e;
1192*e4b17023SJohn Marino edge_iterator ei;
1193*e4b17023SJohn Marino int bbn = order[i];
1194*e4b17023SJohn Marino
1195*e4b17023SJohn Marino if (max_hdr[bbn] != -1 && !TEST_BIT (header, bbn))
1196*e4b17023SJohn Marino {
1197*e4b17023SJohn Marino int hdr = -1;
1198*e4b17023SJohn Marino
1199*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, BASIC_BLOCK (bbn)->preds)
1200*e4b17023SJohn Marino {
1201*e4b17023SJohn Marino int predn = e->src->index;
1202*e4b17023SJohn Marino
1203*e4b17023SJohn Marino if (predn != ENTRY_BLOCK
1204*e4b17023SJohn Marino /* If pred wasn't processed in find_rgns. */
1205*e4b17023SJohn Marino && max_hdr[predn] != -1
1206*e4b17023SJohn Marino /* And pred and bb reside in the same loop.
1207*e4b17023SJohn Marino (Or out of any loop). */
1208*e4b17023SJohn Marino && loop_hdr[bbn] == loop_hdr[predn])
1209*e4b17023SJohn Marino {
1210*e4b17023SJohn Marino if (hdr == -1)
1211*e4b17023SJohn Marino /* Then bb extends the containing region of pred. */
1212*e4b17023SJohn Marino hdr = max_hdr[predn];
1213*e4b17023SJohn Marino else if (hdr != max_hdr[predn])
1214*e4b17023SJohn Marino /* Too bad, there are at least two predecessors
1215*e4b17023SJohn Marino that reside in different regions. Thus, BB should
1216*e4b17023SJohn Marino begin its own region. */
1217*e4b17023SJohn Marino {
1218*e4b17023SJohn Marino hdr = bbn;
1219*e4b17023SJohn Marino break;
1220*e4b17023SJohn Marino }
1221*e4b17023SJohn Marino }
1222*e4b17023SJohn Marino else
1223*e4b17023SJohn Marino /* BB starts its own region. */
1224*e4b17023SJohn Marino {
1225*e4b17023SJohn Marino hdr = bbn;
1226*e4b17023SJohn Marino break;
1227*e4b17023SJohn Marino }
1228*e4b17023SJohn Marino }
1229*e4b17023SJohn Marino
1230*e4b17023SJohn Marino if (hdr == bbn)
1231*e4b17023SJohn Marino {
1232*e4b17023SJohn Marino /* If BB start its own region,
1233*e4b17023SJohn Marino update set of headers with BB. */
1234*e4b17023SJohn Marino SET_BIT (header, bbn);
1235*e4b17023SJohn Marino rescan = 1;
1236*e4b17023SJohn Marino }
1237*e4b17023SJohn Marino else
1238*e4b17023SJohn Marino gcc_assert (hdr != -1);
1239*e4b17023SJohn Marino
1240*e4b17023SJohn Marino max_hdr[bbn] = hdr;
1241*e4b17023SJohn Marino }
1242*e4b17023SJohn Marino }
1243*e4b17023SJohn Marino
1244*e4b17023SJohn Marino iter++;
1245*e4b17023SJohn Marino }
1246*e4b17023SJohn Marino
1247*e4b17023SJohn Marino /* Statistics were gathered on the SPEC2000 package of tests with
1248*e4b17023SJohn Marino mainline weekly snapshot gcc-4.1-20051015 on ia64.
1249*e4b17023SJohn Marino
1250*e4b17023SJohn Marino Statistics for SPECint:
1251*e4b17023SJohn Marino 1 iteration : 1751 cases (38.7%)
1252*e4b17023SJohn Marino 2 iterations: 2770 cases (61.3%)
1253*e4b17023SJohn Marino Blocks wrapped in regions by find_rgns without extension: 18295 blocks
1254*e4b17023SJohn Marino Blocks wrapped in regions by 2 iterations in extend_rgns: 23821 blocks
1255*e4b17023SJohn Marino (We don't count single block regions here).
1256*e4b17023SJohn Marino
1257*e4b17023SJohn Marino Statistics for SPECfp:
1258*e4b17023SJohn Marino 1 iteration : 621 cases (35.9%)
1259*e4b17023SJohn Marino 2 iterations: 1110 cases (64.1%)
1260*e4b17023SJohn Marino Blocks wrapped in regions by find_rgns without extension: 6476 blocks
1261*e4b17023SJohn Marino Blocks wrapped in regions by 2 iterations in extend_rgns: 11155 blocks
1262*e4b17023SJohn Marino (We don't count single block regions here).
1263*e4b17023SJohn Marino
1264*e4b17023SJohn Marino By default we do at most 2 iterations.
1265*e4b17023SJohn Marino This can be overridden with max-sched-extend-regions-iters parameter:
1266*e4b17023SJohn Marino 0 - disable region extension,
1267*e4b17023SJohn Marino N > 0 - do at most N iterations. */
1268*e4b17023SJohn Marino
1269*e4b17023SJohn Marino if (sched_verbose && iter != 0)
1270*e4b17023SJohn Marino fprintf (sched_dump, ";; Region extension iterations: %d%s\n", iter,
1271*e4b17023SJohn Marino rescan ? "... failed" : "");
1272*e4b17023SJohn Marino
1273*e4b17023SJohn Marino if (!rescan && iter != 0)
1274*e4b17023SJohn Marino {
1275*e4b17023SJohn Marino int *s1 = NULL, s1_sz = 0;
1276*e4b17023SJohn Marino
1277*e4b17023SJohn Marino /* Save the old statistics for later printout. */
1278*e4b17023SJohn Marino if (sched_verbose >= 6)
1279*e4b17023SJohn Marino s1_sz = gather_region_statistics (&s1);
1280*e4b17023SJohn Marino
1281*e4b17023SJohn Marino /* We have succeeded. Now assemble the regions. */
1282*e4b17023SJohn Marino for (i = nblocks - 1; i >= 0; i--)
1283*e4b17023SJohn Marino {
1284*e4b17023SJohn Marino int bbn = order[i];
1285*e4b17023SJohn Marino
1286*e4b17023SJohn Marino if (max_hdr[bbn] == bbn)
1287*e4b17023SJohn Marino /* BBN is a region head. */
1288*e4b17023SJohn Marino {
1289*e4b17023SJohn Marino edge e;
1290*e4b17023SJohn Marino edge_iterator ei;
1291*e4b17023SJohn Marino int num_bbs = 0, j, num_insns = 0, large;
1292*e4b17023SJohn Marino
1293*e4b17023SJohn Marino large = too_large (bbn, &num_bbs, &num_insns);
1294*e4b17023SJohn Marino
1295*e4b17023SJohn Marino degree[bbn] = -1;
1296*e4b17023SJohn Marino rgn_bb_table[idx] = bbn;
1297*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = idx++;
1298*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
1299*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
1300*e4b17023SJohn Marino CONTAINING_RGN (bbn) = nr_regions;
1301*e4b17023SJohn Marino BLOCK_TO_BB (bbn) = 0;
1302*e4b17023SJohn Marino
1303*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, BASIC_BLOCK (bbn)->succs)
1304*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR)
1305*e4b17023SJohn Marino degree[e->dest->index]--;
1306*e4b17023SJohn Marino
1307*e4b17023SJohn Marino if (!large)
1308*e4b17023SJohn Marino /* Here we check whether the region is too_large. */
1309*e4b17023SJohn Marino for (j = i - 1; j >= 0; j--)
1310*e4b17023SJohn Marino {
1311*e4b17023SJohn Marino int succn = order[j];
1312*e4b17023SJohn Marino if (max_hdr[succn] == bbn)
1313*e4b17023SJohn Marino {
1314*e4b17023SJohn Marino if ((large = too_large (succn, &num_bbs, &num_insns)))
1315*e4b17023SJohn Marino break;
1316*e4b17023SJohn Marino }
1317*e4b17023SJohn Marino }
1318*e4b17023SJohn Marino
1319*e4b17023SJohn Marino if (large)
1320*e4b17023SJohn Marino /* If the region is too_large, then wrap every block of
1321*e4b17023SJohn Marino the region into single block region.
1322*e4b17023SJohn Marino Here we wrap region head only. Other blocks are
1323*e4b17023SJohn Marino processed in the below cycle. */
1324*e4b17023SJohn Marino {
1325*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = 1;
1326*e4b17023SJohn Marino nr_regions++;
1327*e4b17023SJohn Marino }
1328*e4b17023SJohn Marino
1329*e4b17023SJohn Marino num_bbs = 1;
1330*e4b17023SJohn Marino
1331*e4b17023SJohn Marino for (j = i - 1; j >= 0; j--)
1332*e4b17023SJohn Marino {
1333*e4b17023SJohn Marino int succn = order[j];
1334*e4b17023SJohn Marino
1335*e4b17023SJohn Marino if (max_hdr[succn] == bbn)
1336*e4b17023SJohn Marino /* This cycle iterates over all basic blocks, that
1337*e4b17023SJohn Marino are supposed to be in the region with head BBN,
1338*e4b17023SJohn Marino and wraps them into that region (or in single
1339*e4b17023SJohn Marino block region). */
1340*e4b17023SJohn Marino {
1341*e4b17023SJohn Marino gcc_assert (degree[succn] == 0);
1342*e4b17023SJohn Marino
1343*e4b17023SJohn Marino degree[succn] = -1;
1344*e4b17023SJohn Marino rgn_bb_table[idx] = succn;
1345*e4b17023SJohn Marino BLOCK_TO_BB (succn) = large ? 0 : num_bbs++;
1346*e4b17023SJohn Marino CONTAINING_RGN (succn) = nr_regions;
1347*e4b17023SJohn Marino
1348*e4b17023SJohn Marino if (large)
1349*e4b17023SJohn Marino /* Wrap SUCCN into single block region. */
1350*e4b17023SJohn Marino {
1351*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = idx;
1352*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = 1;
1353*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
1354*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
1355*e4b17023SJohn Marino nr_regions++;
1356*e4b17023SJohn Marino }
1357*e4b17023SJohn Marino
1358*e4b17023SJohn Marino idx++;
1359*e4b17023SJohn Marino
1360*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, BASIC_BLOCK (succn)->succs)
1361*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR)
1362*e4b17023SJohn Marino degree[e->dest->index]--;
1363*e4b17023SJohn Marino }
1364*e4b17023SJohn Marino }
1365*e4b17023SJohn Marino
1366*e4b17023SJohn Marino if (!large)
1367*e4b17023SJohn Marino {
1368*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = num_bbs;
1369*e4b17023SJohn Marino nr_regions++;
1370*e4b17023SJohn Marino }
1371*e4b17023SJohn Marino }
1372*e4b17023SJohn Marino }
1373*e4b17023SJohn Marino
1374*e4b17023SJohn Marino if (sched_verbose >= 6)
1375*e4b17023SJohn Marino {
1376*e4b17023SJohn Marino int *s2, s2_sz;
1377*e4b17023SJohn Marino
1378*e4b17023SJohn Marino /* Get the new statistics and print the comparison with the
1379*e4b17023SJohn Marino one before calling this function. */
1380*e4b17023SJohn Marino s2_sz = gather_region_statistics (&s2);
1381*e4b17023SJohn Marino print_region_statistics (s1, s1_sz, s2, s2_sz);
1382*e4b17023SJohn Marino free (s1);
1383*e4b17023SJohn Marino free (s2);
1384*e4b17023SJohn Marino }
1385*e4b17023SJohn Marino }
1386*e4b17023SJohn Marino
1387*e4b17023SJohn Marino free (order);
1388*e4b17023SJohn Marino free (max_hdr);
1389*e4b17023SJohn Marino
1390*e4b17023SJohn Marino *idxp = idx;
1391*e4b17023SJohn Marino }
1392*e4b17023SJohn Marino
1393*e4b17023SJohn Marino /* Functions for regions scheduling information. */
1394*e4b17023SJohn Marino
1395*e4b17023SJohn Marino /* Compute dominators, probability, and potential-split-edges of bb.
1396*e4b17023SJohn Marino Assume that these values were already computed for bb's predecessors. */
1397*e4b17023SJohn Marino
1398*e4b17023SJohn Marino static void
compute_dom_prob_ps(int bb)1399*e4b17023SJohn Marino compute_dom_prob_ps (int bb)
1400*e4b17023SJohn Marino {
1401*e4b17023SJohn Marino edge_iterator in_ei;
1402*e4b17023SJohn Marino edge in_edge;
1403*e4b17023SJohn Marino
1404*e4b17023SJohn Marino /* We shouldn't have any real ebbs yet. */
1405*e4b17023SJohn Marino gcc_assert (ebb_head [bb] == bb + current_blocks);
1406*e4b17023SJohn Marino
1407*e4b17023SJohn Marino if (IS_RGN_ENTRY (bb))
1408*e4b17023SJohn Marino {
1409*e4b17023SJohn Marino SET_BIT (dom[bb], 0);
1410*e4b17023SJohn Marino prob[bb] = REG_BR_PROB_BASE;
1411*e4b17023SJohn Marino return;
1412*e4b17023SJohn Marino }
1413*e4b17023SJohn Marino
1414*e4b17023SJohn Marino prob[bb] = 0;
1415*e4b17023SJohn Marino
1416*e4b17023SJohn Marino /* Initialize dom[bb] to '111..1'. */
1417*e4b17023SJohn Marino sbitmap_ones (dom[bb]);
1418*e4b17023SJohn Marino
1419*e4b17023SJohn Marino FOR_EACH_EDGE (in_edge, in_ei, BASIC_BLOCK (BB_TO_BLOCK (bb))->preds)
1420*e4b17023SJohn Marino {
1421*e4b17023SJohn Marino int pred_bb;
1422*e4b17023SJohn Marino edge out_edge;
1423*e4b17023SJohn Marino edge_iterator out_ei;
1424*e4b17023SJohn Marino
1425*e4b17023SJohn Marino if (in_edge->src == ENTRY_BLOCK_PTR)
1426*e4b17023SJohn Marino continue;
1427*e4b17023SJohn Marino
1428*e4b17023SJohn Marino pred_bb = BLOCK_TO_BB (in_edge->src->index);
1429*e4b17023SJohn Marino sbitmap_a_and_b (dom[bb], dom[bb], dom[pred_bb]);
1430*e4b17023SJohn Marino sbitmap_a_or_b (ancestor_edges[bb],
1431*e4b17023SJohn Marino ancestor_edges[bb], ancestor_edges[pred_bb]);
1432*e4b17023SJohn Marino
1433*e4b17023SJohn Marino SET_BIT (ancestor_edges[bb], EDGE_TO_BIT (in_edge));
1434*e4b17023SJohn Marino
1435*e4b17023SJohn Marino sbitmap_a_or_b (pot_split[bb], pot_split[bb], pot_split[pred_bb]);
1436*e4b17023SJohn Marino
1437*e4b17023SJohn Marino FOR_EACH_EDGE (out_edge, out_ei, in_edge->src->succs)
1438*e4b17023SJohn Marino SET_BIT (pot_split[bb], EDGE_TO_BIT (out_edge));
1439*e4b17023SJohn Marino
1440*e4b17023SJohn Marino prob[bb] += ((prob[pred_bb] * in_edge->probability) / REG_BR_PROB_BASE);
1441*e4b17023SJohn Marino }
1442*e4b17023SJohn Marino
1443*e4b17023SJohn Marino SET_BIT (dom[bb], bb);
1444*e4b17023SJohn Marino sbitmap_difference (pot_split[bb], pot_split[bb], ancestor_edges[bb]);
1445*e4b17023SJohn Marino
1446*e4b17023SJohn Marino if (sched_verbose >= 2)
1447*e4b17023SJohn Marino fprintf (sched_dump, ";; bb_prob(%d, %d) = %3d\n", bb, BB_TO_BLOCK (bb),
1448*e4b17023SJohn Marino (100 * prob[bb]) / REG_BR_PROB_BASE);
1449*e4b17023SJohn Marino }
1450*e4b17023SJohn Marino
1451*e4b17023SJohn Marino /* Functions for target info. */
1452*e4b17023SJohn Marino
1453*e4b17023SJohn Marino /* Compute in BL the list of split-edges of bb_src relatively to bb_trg.
1454*e4b17023SJohn Marino Note that bb_trg dominates bb_src. */
1455*e4b17023SJohn Marino
1456*e4b17023SJohn Marino static void
split_edges(int bb_src,int bb_trg,edgelst * bl)1457*e4b17023SJohn Marino split_edges (int bb_src, int bb_trg, edgelst *bl)
1458*e4b17023SJohn Marino {
1459*e4b17023SJohn Marino sbitmap src = sbitmap_alloc (pot_split[bb_src]->n_bits);
1460*e4b17023SJohn Marino sbitmap_copy (src, pot_split[bb_src]);
1461*e4b17023SJohn Marino
1462*e4b17023SJohn Marino sbitmap_difference (src, src, pot_split[bb_trg]);
1463*e4b17023SJohn Marino extract_edgelst (src, bl);
1464*e4b17023SJohn Marino sbitmap_free (src);
1465*e4b17023SJohn Marino }
1466*e4b17023SJohn Marino
1467*e4b17023SJohn Marino /* Find the valid candidate-source-blocks for the target block TRG, compute
1468*e4b17023SJohn Marino their probability, and check if they are speculative or not.
1469*e4b17023SJohn Marino For speculative sources, compute their update-blocks and split-blocks. */
1470*e4b17023SJohn Marino
1471*e4b17023SJohn Marino static void
compute_trg_info(int trg)1472*e4b17023SJohn Marino compute_trg_info (int trg)
1473*e4b17023SJohn Marino {
1474*e4b17023SJohn Marino candidate *sp;
1475*e4b17023SJohn Marino edgelst el = { NULL, 0 };
1476*e4b17023SJohn Marino int i, j, k, update_idx;
1477*e4b17023SJohn Marino basic_block block;
1478*e4b17023SJohn Marino sbitmap visited;
1479*e4b17023SJohn Marino edge_iterator ei;
1480*e4b17023SJohn Marino edge e;
1481*e4b17023SJohn Marino
1482*e4b17023SJohn Marino candidate_table = XNEWVEC (candidate, current_nr_blocks);
1483*e4b17023SJohn Marino
1484*e4b17023SJohn Marino bblst_last = 0;
1485*e4b17023SJohn Marino /* bblst_table holds split blocks and update blocks for each block after
1486*e4b17023SJohn Marino the current one in the region. split blocks and update blocks are
1487*e4b17023SJohn Marino the TO blocks of region edges, so there can be at most rgn_nr_edges
1488*e4b17023SJohn Marino of them. */
1489*e4b17023SJohn Marino bblst_size = (current_nr_blocks - target_bb) * rgn_nr_edges;
1490*e4b17023SJohn Marino bblst_table = XNEWVEC (basic_block, bblst_size);
1491*e4b17023SJohn Marino
1492*e4b17023SJohn Marino edgelst_last = 0;
1493*e4b17023SJohn Marino edgelst_table = XNEWVEC (edge, rgn_nr_edges);
1494*e4b17023SJohn Marino
1495*e4b17023SJohn Marino /* Define some of the fields for the target bb as well. */
1496*e4b17023SJohn Marino sp = candidate_table + trg;
1497*e4b17023SJohn Marino sp->is_valid = 1;
1498*e4b17023SJohn Marino sp->is_speculative = 0;
1499*e4b17023SJohn Marino sp->src_prob = REG_BR_PROB_BASE;
1500*e4b17023SJohn Marino
1501*e4b17023SJohn Marino visited = sbitmap_alloc (last_basic_block);
1502*e4b17023SJohn Marino
1503*e4b17023SJohn Marino for (i = trg + 1; i < current_nr_blocks; i++)
1504*e4b17023SJohn Marino {
1505*e4b17023SJohn Marino sp = candidate_table + i;
1506*e4b17023SJohn Marino
1507*e4b17023SJohn Marino sp->is_valid = IS_DOMINATED (i, trg);
1508*e4b17023SJohn Marino if (sp->is_valid)
1509*e4b17023SJohn Marino {
1510*e4b17023SJohn Marino int tf = prob[trg], cf = prob[i];
1511*e4b17023SJohn Marino
1512*e4b17023SJohn Marino /* In CFGs with low probability edges TF can possibly be zero. */
1513*e4b17023SJohn Marino sp->src_prob = (tf ? ((cf * REG_BR_PROB_BASE) / tf) : 0);
1514*e4b17023SJohn Marino sp->is_valid = (sp->src_prob >= min_spec_prob);
1515*e4b17023SJohn Marino }
1516*e4b17023SJohn Marino
1517*e4b17023SJohn Marino if (sp->is_valid)
1518*e4b17023SJohn Marino {
1519*e4b17023SJohn Marino split_edges (i, trg, &el);
1520*e4b17023SJohn Marino sp->is_speculative = (el.nr_members) ? 1 : 0;
1521*e4b17023SJohn Marino if (sp->is_speculative && !flag_schedule_speculative)
1522*e4b17023SJohn Marino sp->is_valid = 0;
1523*e4b17023SJohn Marino }
1524*e4b17023SJohn Marino
1525*e4b17023SJohn Marino if (sp->is_valid)
1526*e4b17023SJohn Marino {
1527*e4b17023SJohn Marino /* Compute split blocks and store them in bblst_table.
1528*e4b17023SJohn Marino The TO block of every split edge is a split block. */
1529*e4b17023SJohn Marino sp->split_bbs.first_member = &bblst_table[bblst_last];
1530*e4b17023SJohn Marino sp->split_bbs.nr_members = el.nr_members;
1531*e4b17023SJohn Marino for (j = 0; j < el.nr_members; bblst_last++, j++)
1532*e4b17023SJohn Marino bblst_table[bblst_last] = el.first_member[j]->dest;
1533*e4b17023SJohn Marino sp->update_bbs.first_member = &bblst_table[bblst_last];
1534*e4b17023SJohn Marino
1535*e4b17023SJohn Marino /* Compute update blocks and store them in bblst_table.
1536*e4b17023SJohn Marino For every split edge, look at the FROM block, and check
1537*e4b17023SJohn Marino all out edges. For each out edge that is not a split edge,
1538*e4b17023SJohn Marino add the TO block to the update block list. This list can end
1539*e4b17023SJohn Marino up with a lot of duplicates. We need to weed them out to avoid
1540*e4b17023SJohn Marino overrunning the end of the bblst_table. */
1541*e4b17023SJohn Marino
1542*e4b17023SJohn Marino update_idx = 0;
1543*e4b17023SJohn Marino sbitmap_zero (visited);
1544*e4b17023SJohn Marino for (j = 0; j < el.nr_members; j++)
1545*e4b17023SJohn Marino {
1546*e4b17023SJohn Marino block = el.first_member[j]->src;
1547*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, block->succs)
1548*e4b17023SJohn Marino {
1549*e4b17023SJohn Marino if (!TEST_BIT (visited, e->dest->index))
1550*e4b17023SJohn Marino {
1551*e4b17023SJohn Marino for (k = 0; k < el.nr_members; k++)
1552*e4b17023SJohn Marino if (e == el.first_member[k])
1553*e4b17023SJohn Marino break;
1554*e4b17023SJohn Marino
1555*e4b17023SJohn Marino if (k >= el.nr_members)
1556*e4b17023SJohn Marino {
1557*e4b17023SJohn Marino bblst_table[bblst_last++] = e->dest;
1558*e4b17023SJohn Marino SET_BIT (visited, e->dest->index);
1559*e4b17023SJohn Marino update_idx++;
1560*e4b17023SJohn Marino }
1561*e4b17023SJohn Marino }
1562*e4b17023SJohn Marino }
1563*e4b17023SJohn Marino }
1564*e4b17023SJohn Marino sp->update_bbs.nr_members = update_idx;
1565*e4b17023SJohn Marino
1566*e4b17023SJohn Marino /* Make sure we didn't overrun the end of bblst_table. */
1567*e4b17023SJohn Marino gcc_assert (bblst_last <= bblst_size);
1568*e4b17023SJohn Marino }
1569*e4b17023SJohn Marino else
1570*e4b17023SJohn Marino {
1571*e4b17023SJohn Marino sp->split_bbs.nr_members = sp->update_bbs.nr_members = 0;
1572*e4b17023SJohn Marino
1573*e4b17023SJohn Marino sp->is_speculative = 0;
1574*e4b17023SJohn Marino sp->src_prob = 0;
1575*e4b17023SJohn Marino }
1576*e4b17023SJohn Marino }
1577*e4b17023SJohn Marino
1578*e4b17023SJohn Marino sbitmap_free (visited);
1579*e4b17023SJohn Marino }
1580*e4b17023SJohn Marino
1581*e4b17023SJohn Marino /* Free the computed target info. */
1582*e4b17023SJohn Marino static void
free_trg_info(void)1583*e4b17023SJohn Marino free_trg_info (void)
1584*e4b17023SJohn Marino {
1585*e4b17023SJohn Marino free (candidate_table);
1586*e4b17023SJohn Marino free (bblst_table);
1587*e4b17023SJohn Marino free (edgelst_table);
1588*e4b17023SJohn Marino }
1589*e4b17023SJohn Marino
1590*e4b17023SJohn Marino /* Print candidates info, for debugging purposes. Callable from debugger. */
1591*e4b17023SJohn Marino
1592*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_candidate(int i)1593*e4b17023SJohn Marino debug_candidate (int i)
1594*e4b17023SJohn Marino {
1595*e4b17023SJohn Marino if (!candidate_table[i].is_valid)
1596*e4b17023SJohn Marino return;
1597*e4b17023SJohn Marino
1598*e4b17023SJohn Marino if (candidate_table[i].is_speculative)
1599*e4b17023SJohn Marino {
1600*e4b17023SJohn Marino int j;
1601*e4b17023SJohn Marino fprintf (sched_dump, "src b %d bb %d speculative \n", BB_TO_BLOCK (i), i);
1602*e4b17023SJohn Marino
1603*e4b17023SJohn Marino fprintf (sched_dump, "split path: ");
1604*e4b17023SJohn Marino for (j = 0; j < candidate_table[i].split_bbs.nr_members; j++)
1605*e4b17023SJohn Marino {
1606*e4b17023SJohn Marino int b = candidate_table[i].split_bbs.first_member[j]->index;
1607*e4b17023SJohn Marino
1608*e4b17023SJohn Marino fprintf (sched_dump, " %d ", b);
1609*e4b17023SJohn Marino }
1610*e4b17023SJohn Marino fprintf (sched_dump, "\n");
1611*e4b17023SJohn Marino
1612*e4b17023SJohn Marino fprintf (sched_dump, "update path: ");
1613*e4b17023SJohn Marino for (j = 0; j < candidate_table[i].update_bbs.nr_members; j++)
1614*e4b17023SJohn Marino {
1615*e4b17023SJohn Marino int b = candidate_table[i].update_bbs.first_member[j]->index;
1616*e4b17023SJohn Marino
1617*e4b17023SJohn Marino fprintf (sched_dump, " %d ", b);
1618*e4b17023SJohn Marino }
1619*e4b17023SJohn Marino fprintf (sched_dump, "\n");
1620*e4b17023SJohn Marino }
1621*e4b17023SJohn Marino else
1622*e4b17023SJohn Marino {
1623*e4b17023SJohn Marino fprintf (sched_dump, " src %d equivalent\n", BB_TO_BLOCK (i));
1624*e4b17023SJohn Marino }
1625*e4b17023SJohn Marino }
1626*e4b17023SJohn Marino
1627*e4b17023SJohn Marino /* Print candidates info, for debugging purposes. Callable from debugger. */
1628*e4b17023SJohn Marino
1629*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_candidates(int trg)1630*e4b17023SJohn Marino debug_candidates (int trg)
1631*e4b17023SJohn Marino {
1632*e4b17023SJohn Marino int i;
1633*e4b17023SJohn Marino
1634*e4b17023SJohn Marino fprintf (sched_dump, "----------- candidate table: target: b=%d bb=%d ---\n",
1635*e4b17023SJohn Marino BB_TO_BLOCK (trg), trg);
1636*e4b17023SJohn Marino for (i = trg + 1; i < current_nr_blocks; i++)
1637*e4b17023SJohn Marino debug_candidate (i);
1638*e4b17023SJohn Marino }
1639*e4b17023SJohn Marino
1640*e4b17023SJohn Marino /* Functions for speculative scheduling. */
1641*e4b17023SJohn Marino
1642*e4b17023SJohn Marino static bitmap_head not_in_df;
1643*e4b17023SJohn Marino
1644*e4b17023SJohn Marino /* Return 0 if x is a set of a register alive in the beginning of one
1645*e4b17023SJohn Marino of the split-blocks of src, otherwise return 1. */
1646*e4b17023SJohn Marino
1647*e4b17023SJohn Marino static int
check_live_1(int src,rtx x)1648*e4b17023SJohn Marino check_live_1 (int src, rtx x)
1649*e4b17023SJohn Marino {
1650*e4b17023SJohn Marino int i;
1651*e4b17023SJohn Marino int regno;
1652*e4b17023SJohn Marino rtx reg = SET_DEST (x);
1653*e4b17023SJohn Marino
1654*e4b17023SJohn Marino if (reg == 0)
1655*e4b17023SJohn Marino return 1;
1656*e4b17023SJohn Marino
1657*e4b17023SJohn Marino while (GET_CODE (reg) == SUBREG
1658*e4b17023SJohn Marino || GET_CODE (reg) == ZERO_EXTRACT
1659*e4b17023SJohn Marino || GET_CODE (reg) == STRICT_LOW_PART)
1660*e4b17023SJohn Marino reg = XEXP (reg, 0);
1661*e4b17023SJohn Marino
1662*e4b17023SJohn Marino if (GET_CODE (reg) == PARALLEL)
1663*e4b17023SJohn Marino {
1664*e4b17023SJohn Marino int i;
1665*e4b17023SJohn Marino
1666*e4b17023SJohn Marino for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
1667*e4b17023SJohn Marino if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
1668*e4b17023SJohn Marino if (check_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0)))
1669*e4b17023SJohn Marino return 1;
1670*e4b17023SJohn Marino
1671*e4b17023SJohn Marino return 0;
1672*e4b17023SJohn Marino }
1673*e4b17023SJohn Marino
1674*e4b17023SJohn Marino if (!REG_P (reg))
1675*e4b17023SJohn Marino return 1;
1676*e4b17023SJohn Marino
1677*e4b17023SJohn Marino regno = REGNO (reg);
1678*e4b17023SJohn Marino
1679*e4b17023SJohn Marino if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
1680*e4b17023SJohn Marino {
1681*e4b17023SJohn Marino /* Global registers are assumed live. */
1682*e4b17023SJohn Marino return 0;
1683*e4b17023SJohn Marino }
1684*e4b17023SJohn Marino else
1685*e4b17023SJohn Marino {
1686*e4b17023SJohn Marino if (regno < FIRST_PSEUDO_REGISTER)
1687*e4b17023SJohn Marino {
1688*e4b17023SJohn Marino /* Check for hard registers. */
1689*e4b17023SJohn Marino int j = hard_regno_nregs[regno][GET_MODE (reg)];
1690*e4b17023SJohn Marino while (--j >= 0)
1691*e4b17023SJohn Marino {
1692*e4b17023SJohn Marino for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
1693*e4b17023SJohn Marino {
1694*e4b17023SJohn Marino basic_block b = candidate_table[src].split_bbs.first_member[i];
1695*e4b17023SJohn Marino int t = bitmap_bit_p (¬_in_df, b->index);
1696*e4b17023SJohn Marino
1697*e4b17023SJohn Marino /* We can have split blocks, that were recently generated.
1698*e4b17023SJohn Marino Such blocks are always outside current region. */
1699*e4b17023SJohn Marino gcc_assert (!t || (CONTAINING_RGN (b->index)
1700*e4b17023SJohn Marino != CONTAINING_RGN (BB_TO_BLOCK (src))));
1701*e4b17023SJohn Marino
1702*e4b17023SJohn Marino if (t || REGNO_REG_SET_P (df_get_live_in (b), regno + j))
1703*e4b17023SJohn Marino return 0;
1704*e4b17023SJohn Marino }
1705*e4b17023SJohn Marino }
1706*e4b17023SJohn Marino }
1707*e4b17023SJohn Marino else
1708*e4b17023SJohn Marino {
1709*e4b17023SJohn Marino /* Check for pseudo registers. */
1710*e4b17023SJohn Marino for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
1711*e4b17023SJohn Marino {
1712*e4b17023SJohn Marino basic_block b = candidate_table[src].split_bbs.first_member[i];
1713*e4b17023SJohn Marino int t = bitmap_bit_p (¬_in_df, b->index);
1714*e4b17023SJohn Marino
1715*e4b17023SJohn Marino gcc_assert (!t || (CONTAINING_RGN (b->index)
1716*e4b17023SJohn Marino != CONTAINING_RGN (BB_TO_BLOCK (src))));
1717*e4b17023SJohn Marino
1718*e4b17023SJohn Marino if (t || REGNO_REG_SET_P (df_get_live_in (b), regno))
1719*e4b17023SJohn Marino return 0;
1720*e4b17023SJohn Marino }
1721*e4b17023SJohn Marino }
1722*e4b17023SJohn Marino }
1723*e4b17023SJohn Marino
1724*e4b17023SJohn Marino return 1;
1725*e4b17023SJohn Marino }
1726*e4b17023SJohn Marino
1727*e4b17023SJohn Marino /* If x is a set of a register R, mark that R is alive in the beginning
1728*e4b17023SJohn Marino of every update-block of src. */
1729*e4b17023SJohn Marino
1730*e4b17023SJohn Marino static void
update_live_1(int src,rtx x)1731*e4b17023SJohn Marino update_live_1 (int src, rtx x)
1732*e4b17023SJohn Marino {
1733*e4b17023SJohn Marino int i;
1734*e4b17023SJohn Marino int regno;
1735*e4b17023SJohn Marino rtx reg = SET_DEST (x);
1736*e4b17023SJohn Marino
1737*e4b17023SJohn Marino if (reg == 0)
1738*e4b17023SJohn Marino return;
1739*e4b17023SJohn Marino
1740*e4b17023SJohn Marino while (GET_CODE (reg) == SUBREG
1741*e4b17023SJohn Marino || GET_CODE (reg) == ZERO_EXTRACT
1742*e4b17023SJohn Marino || GET_CODE (reg) == STRICT_LOW_PART)
1743*e4b17023SJohn Marino reg = XEXP (reg, 0);
1744*e4b17023SJohn Marino
1745*e4b17023SJohn Marino if (GET_CODE (reg) == PARALLEL)
1746*e4b17023SJohn Marino {
1747*e4b17023SJohn Marino int i;
1748*e4b17023SJohn Marino
1749*e4b17023SJohn Marino for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
1750*e4b17023SJohn Marino if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
1751*e4b17023SJohn Marino update_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0));
1752*e4b17023SJohn Marino
1753*e4b17023SJohn Marino return;
1754*e4b17023SJohn Marino }
1755*e4b17023SJohn Marino
1756*e4b17023SJohn Marino if (!REG_P (reg))
1757*e4b17023SJohn Marino return;
1758*e4b17023SJohn Marino
1759*e4b17023SJohn Marino /* Global registers are always live, so the code below does not apply
1760*e4b17023SJohn Marino to them. */
1761*e4b17023SJohn Marino
1762*e4b17023SJohn Marino regno = REGNO (reg);
1763*e4b17023SJohn Marino
1764*e4b17023SJohn Marino if (! HARD_REGISTER_NUM_P (regno)
1765*e4b17023SJohn Marino || !global_regs[regno])
1766*e4b17023SJohn Marino {
1767*e4b17023SJohn Marino for (i = 0; i < candidate_table[src].update_bbs.nr_members; i++)
1768*e4b17023SJohn Marino {
1769*e4b17023SJohn Marino basic_block b = candidate_table[src].update_bbs.first_member[i];
1770*e4b17023SJohn Marino
1771*e4b17023SJohn Marino if (HARD_REGISTER_NUM_P (regno))
1772*e4b17023SJohn Marino bitmap_set_range (df_get_live_in (b), regno,
1773*e4b17023SJohn Marino hard_regno_nregs[regno][GET_MODE (reg)]);
1774*e4b17023SJohn Marino else
1775*e4b17023SJohn Marino bitmap_set_bit (df_get_live_in (b), regno);
1776*e4b17023SJohn Marino }
1777*e4b17023SJohn Marino }
1778*e4b17023SJohn Marino }
1779*e4b17023SJohn Marino
1780*e4b17023SJohn Marino /* Return 1 if insn can be speculatively moved from block src to trg,
1781*e4b17023SJohn Marino otherwise return 0. Called before first insertion of insn to
1782*e4b17023SJohn Marino ready-list or before the scheduling. */
1783*e4b17023SJohn Marino
1784*e4b17023SJohn Marino static int
check_live(rtx insn,int src)1785*e4b17023SJohn Marino check_live (rtx insn, int src)
1786*e4b17023SJohn Marino {
1787*e4b17023SJohn Marino /* Find the registers set by instruction. */
1788*e4b17023SJohn Marino if (GET_CODE (PATTERN (insn)) == SET
1789*e4b17023SJohn Marino || GET_CODE (PATTERN (insn)) == CLOBBER)
1790*e4b17023SJohn Marino return check_live_1 (src, PATTERN (insn));
1791*e4b17023SJohn Marino else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1792*e4b17023SJohn Marino {
1793*e4b17023SJohn Marino int j;
1794*e4b17023SJohn Marino for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
1795*e4b17023SJohn Marino if ((GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
1796*e4b17023SJohn Marino || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
1797*e4b17023SJohn Marino && !check_live_1 (src, XVECEXP (PATTERN (insn), 0, j)))
1798*e4b17023SJohn Marino return 0;
1799*e4b17023SJohn Marino
1800*e4b17023SJohn Marino return 1;
1801*e4b17023SJohn Marino }
1802*e4b17023SJohn Marino
1803*e4b17023SJohn Marino return 1;
1804*e4b17023SJohn Marino }
1805*e4b17023SJohn Marino
1806*e4b17023SJohn Marino /* Update the live registers info after insn was moved speculatively from
1807*e4b17023SJohn Marino block src to trg. */
1808*e4b17023SJohn Marino
1809*e4b17023SJohn Marino static void
update_live(rtx insn,int src)1810*e4b17023SJohn Marino update_live (rtx insn, int src)
1811*e4b17023SJohn Marino {
1812*e4b17023SJohn Marino /* Find the registers set by instruction. */
1813*e4b17023SJohn Marino if (GET_CODE (PATTERN (insn)) == SET
1814*e4b17023SJohn Marino || GET_CODE (PATTERN (insn)) == CLOBBER)
1815*e4b17023SJohn Marino update_live_1 (src, PATTERN (insn));
1816*e4b17023SJohn Marino else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1817*e4b17023SJohn Marino {
1818*e4b17023SJohn Marino int j;
1819*e4b17023SJohn Marino for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
1820*e4b17023SJohn Marino if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
1821*e4b17023SJohn Marino || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
1822*e4b17023SJohn Marino update_live_1 (src, XVECEXP (PATTERN (insn), 0, j));
1823*e4b17023SJohn Marino }
1824*e4b17023SJohn Marino }
1825*e4b17023SJohn Marino
1826*e4b17023SJohn Marino /* Nonzero if block bb_to is equal to, or reachable from block bb_from. */
1827*e4b17023SJohn Marino #define IS_REACHABLE(bb_from, bb_to) \
1828*e4b17023SJohn Marino (bb_from == bb_to \
1829*e4b17023SJohn Marino || IS_RGN_ENTRY (bb_from) \
1830*e4b17023SJohn Marino || (TEST_BIT (ancestor_edges[bb_to], \
1831*e4b17023SJohn Marino EDGE_TO_BIT (single_pred_edge (BASIC_BLOCK (BB_TO_BLOCK (bb_from)))))))
1832*e4b17023SJohn Marino
1833*e4b17023SJohn Marino /* Turns on the fed_by_spec_load flag for insns fed by load_insn. */
1834*e4b17023SJohn Marino
1835*e4b17023SJohn Marino static void
set_spec_fed(rtx load_insn)1836*e4b17023SJohn Marino set_spec_fed (rtx load_insn)
1837*e4b17023SJohn Marino {
1838*e4b17023SJohn Marino sd_iterator_def sd_it;
1839*e4b17023SJohn Marino dep_t dep;
1840*e4b17023SJohn Marino
1841*e4b17023SJohn Marino FOR_EACH_DEP (load_insn, SD_LIST_FORW, sd_it, dep)
1842*e4b17023SJohn Marino if (DEP_TYPE (dep) == REG_DEP_TRUE)
1843*e4b17023SJohn Marino FED_BY_SPEC_LOAD (DEP_CON (dep)) = 1;
1844*e4b17023SJohn Marino }
1845*e4b17023SJohn Marino
1846*e4b17023SJohn Marino /* On the path from the insn to load_insn_bb, find a conditional
1847*e4b17023SJohn Marino branch depending on insn, that guards the speculative load. */
1848*e4b17023SJohn Marino
1849*e4b17023SJohn Marino static int
find_conditional_protection(rtx insn,int load_insn_bb)1850*e4b17023SJohn Marino find_conditional_protection (rtx insn, int load_insn_bb)
1851*e4b17023SJohn Marino {
1852*e4b17023SJohn Marino sd_iterator_def sd_it;
1853*e4b17023SJohn Marino dep_t dep;
1854*e4b17023SJohn Marino
1855*e4b17023SJohn Marino /* Iterate through DEF-USE forward dependences. */
1856*e4b17023SJohn Marino FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
1857*e4b17023SJohn Marino {
1858*e4b17023SJohn Marino rtx next = DEP_CON (dep);
1859*e4b17023SJohn Marino
1860*e4b17023SJohn Marino if ((CONTAINING_RGN (BLOCK_NUM (next)) ==
1861*e4b17023SJohn Marino CONTAINING_RGN (BB_TO_BLOCK (load_insn_bb)))
1862*e4b17023SJohn Marino && IS_REACHABLE (INSN_BB (next), load_insn_bb)
1863*e4b17023SJohn Marino && load_insn_bb != INSN_BB (next)
1864*e4b17023SJohn Marino && DEP_TYPE (dep) == REG_DEP_TRUE
1865*e4b17023SJohn Marino && (JUMP_P (next)
1866*e4b17023SJohn Marino || find_conditional_protection (next, load_insn_bb)))
1867*e4b17023SJohn Marino return 1;
1868*e4b17023SJohn Marino }
1869*e4b17023SJohn Marino return 0;
1870*e4b17023SJohn Marino } /* find_conditional_protection */
1871*e4b17023SJohn Marino
1872*e4b17023SJohn Marino /* Returns 1 if the same insn1 that participates in the computation
1873*e4b17023SJohn Marino of load_insn's address is feeding a conditional branch that is
1874*e4b17023SJohn Marino guarding on load_insn. This is true if we find two DEF-USE
1875*e4b17023SJohn Marino chains:
1876*e4b17023SJohn Marino insn1 -> ... -> conditional-branch
1877*e4b17023SJohn Marino insn1 -> ... -> load_insn,
1878*e4b17023SJohn Marino and if a flow path exists:
1879*e4b17023SJohn Marino insn1 -> ... -> conditional-branch -> ... -> load_insn,
1880*e4b17023SJohn Marino and if insn1 is on the path
1881*e4b17023SJohn Marino region-entry -> ... -> bb_trg -> ... load_insn.
1882*e4b17023SJohn Marino
1883*e4b17023SJohn Marino Locate insn1 by climbing on INSN_BACK_DEPS from load_insn.
1884*e4b17023SJohn Marino Locate the branch by following INSN_FORW_DEPS from insn1. */
1885*e4b17023SJohn Marino
1886*e4b17023SJohn Marino static int
is_conditionally_protected(rtx load_insn,int bb_src,int bb_trg)1887*e4b17023SJohn Marino is_conditionally_protected (rtx load_insn, int bb_src, int bb_trg)
1888*e4b17023SJohn Marino {
1889*e4b17023SJohn Marino sd_iterator_def sd_it;
1890*e4b17023SJohn Marino dep_t dep;
1891*e4b17023SJohn Marino
1892*e4b17023SJohn Marino FOR_EACH_DEP (load_insn, SD_LIST_BACK, sd_it, dep)
1893*e4b17023SJohn Marino {
1894*e4b17023SJohn Marino rtx insn1 = DEP_PRO (dep);
1895*e4b17023SJohn Marino
1896*e4b17023SJohn Marino /* Must be a DEF-USE dependence upon non-branch. */
1897*e4b17023SJohn Marino if (DEP_TYPE (dep) != REG_DEP_TRUE
1898*e4b17023SJohn Marino || JUMP_P (insn1))
1899*e4b17023SJohn Marino continue;
1900*e4b17023SJohn Marino
1901*e4b17023SJohn Marino /* Must exist a path: region-entry -> ... -> bb_trg -> ... load_insn. */
1902*e4b17023SJohn Marino if (INSN_BB (insn1) == bb_src
1903*e4b17023SJohn Marino || (CONTAINING_RGN (BLOCK_NUM (insn1))
1904*e4b17023SJohn Marino != CONTAINING_RGN (BB_TO_BLOCK (bb_src)))
1905*e4b17023SJohn Marino || (!IS_REACHABLE (bb_trg, INSN_BB (insn1))
1906*e4b17023SJohn Marino && !IS_REACHABLE (INSN_BB (insn1), bb_trg)))
1907*e4b17023SJohn Marino continue;
1908*e4b17023SJohn Marino
1909*e4b17023SJohn Marino /* Now search for the conditional-branch. */
1910*e4b17023SJohn Marino if (find_conditional_protection (insn1, bb_src))
1911*e4b17023SJohn Marino return 1;
1912*e4b17023SJohn Marino
1913*e4b17023SJohn Marino /* Recursive step: search another insn1, "above" current insn1. */
1914*e4b17023SJohn Marino return is_conditionally_protected (insn1, bb_src, bb_trg);
1915*e4b17023SJohn Marino }
1916*e4b17023SJohn Marino
1917*e4b17023SJohn Marino /* The chain does not exist. */
1918*e4b17023SJohn Marino return 0;
1919*e4b17023SJohn Marino } /* is_conditionally_protected */
1920*e4b17023SJohn Marino
1921*e4b17023SJohn Marino /* Returns 1 if a clue for "similar load" 'insn2' is found, and hence
1922*e4b17023SJohn Marino load_insn can move speculatively from bb_src to bb_trg. All the
1923*e4b17023SJohn Marino following must hold:
1924*e4b17023SJohn Marino
1925*e4b17023SJohn Marino (1) both loads have 1 base register (PFREE_CANDIDATEs).
1926*e4b17023SJohn Marino (2) load_insn and load1 have a def-use dependence upon
1927*e4b17023SJohn Marino the same insn 'insn1'.
1928*e4b17023SJohn Marino (3) either load2 is in bb_trg, or:
1929*e4b17023SJohn Marino - there's only one split-block, and
1930*e4b17023SJohn Marino - load1 is on the escape path, and
1931*e4b17023SJohn Marino
1932*e4b17023SJohn Marino From all these we can conclude that the two loads access memory
1933*e4b17023SJohn Marino addresses that differ at most by a constant, and hence if moving
1934*e4b17023SJohn Marino load_insn would cause an exception, it would have been caused by
1935*e4b17023SJohn Marino load2 anyhow. */
1936*e4b17023SJohn Marino
1937*e4b17023SJohn Marino static int
is_pfree(rtx load_insn,int bb_src,int bb_trg)1938*e4b17023SJohn Marino is_pfree (rtx load_insn, int bb_src, int bb_trg)
1939*e4b17023SJohn Marino {
1940*e4b17023SJohn Marino sd_iterator_def back_sd_it;
1941*e4b17023SJohn Marino dep_t back_dep;
1942*e4b17023SJohn Marino candidate *candp = candidate_table + bb_src;
1943*e4b17023SJohn Marino
1944*e4b17023SJohn Marino if (candp->split_bbs.nr_members != 1)
1945*e4b17023SJohn Marino /* Must have exactly one escape block. */
1946*e4b17023SJohn Marino return 0;
1947*e4b17023SJohn Marino
1948*e4b17023SJohn Marino FOR_EACH_DEP (load_insn, SD_LIST_BACK, back_sd_it, back_dep)
1949*e4b17023SJohn Marino {
1950*e4b17023SJohn Marino rtx insn1 = DEP_PRO (back_dep);
1951*e4b17023SJohn Marino
1952*e4b17023SJohn Marino if (DEP_TYPE (back_dep) == REG_DEP_TRUE)
1953*e4b17023SJohn Marino /* Found a DEF-USE dependence (insn1, load_insn). */
1954*e4b17023SJohn Marino {
1955*e4b17023SJohn Marino sd_iterator_def fore_sd_it;
1956*e4b17023SJohn Marino dep_t fore_dep;
1957*e4b17023SJohn Marino
1958*e4b17023SJohn Marino FOR_EACH_DEP (insn1, SD_LIST_FORW, fore_sd_it, fore_dep)
1959*e4b17023SJohn Marino {
1960*e4b17023SJohn Marino rtx insn2 = DEP_CON (fore_dep);
1961*e4b17023SJohn Marino
1962*e4b17023SJohn Marino if (DEP_TYPE (fore_dep) == REG_DEP_TRUE)
1963*e4b17023SJohn Marino {
1964*e4b17023SJohn Marino /* Found a DEF-USE dependence (insn1, insn2). */
1965*e4b17023SJohn Marino if (haifa_classify_insn (insn2) != PFREE_CANDIDATE)
1966*e4b17023SJohn Marino /* insn2 not guaranteed to be a 1 base reg load. */
1967*e4b17023SJohn Marino continue;
1968*e4b17023SJohn Marino
1969*e4b17023SJohn Marino if (INSN_BB (insn2) == bb_trg)
1970*e4b17023SJohn Marino /* insn2 is the similar load, in the target block. */
1971*e4b17023SJohn Marino return 1;
1972*e4b17023SJohn Marino
1973*e4b17023SJohn Marino if (*(candp->split_bbs.first_member) == BLOCK_FOR_INSN (insn2))
1974*e4b17023SJohn Marino /* insn2 is a similar load, in a split-block. */
1975*e4b17023SJohn Marino return 1;
1976*e4b17023SJohn Marino }
1977*e4b17023SJohn Marino }
1978*e4b17023SJohn Marino }
1979*e4b17023SJohn Marino }
1980*e4b17023SJohn Marino
1981*e4b17023SJohn Marino /* Couldn't find a similar load. */
1982*e4b17023SJohn Marino return 0;
1983*e4b17023SJohn Marino } /* is_pfree */
1984*e4b17023SJohn Marino
1985*e4b17023SJohn Marino /* Return 1 if load_insn is prisky (i.e. if load_insn is fed by
1986*e4b17023SJohn Marino a load moved speculatively, or if load_insn is protected by
1987*e4b17023SJohn Marino a compare on load_insn's address). */
1988*e4b17023SJohn Marino
1989*e4b17023SJohn Marino static int
is_prisky(rtx load_insn,int bb_src,int bb_trg)1990*e4b17023SJohn Marino is_prisky (rtx load_insn, int bb_src, int bb_trg)
1991*e4b17023SJohn Marino {
1992*e4b17023SJohn Marino if (FED_BY_SPEC_LOAD (load_insn))
1993*e4b17023SJohn Marino return 1;
1994*e4b17023SJohn Marino
1995*e4b17023SJohn Marino if (sd_lists_empty_p (load_insn, SD_LIST_BACK))
1996*e4b17023SJohn Marino /* Dependence may 'hide' out of the region. */
1997*e4b17023SJohn Marino return 1;
1998*e4b17023SJohn Marino
1999*e4b17023SJohn Marino if (is_conditionally_protected (load_insn, bb_src, bb_trg))
2000*e4b17023SJohn Marino return 1;
2001*e4b17023SJohn Marino
2002*e4b17023SJohn Marino return 0;
2003*e4b17023SJohn Marino }
2004*e4b17023SJohn Marino
2005*e4b17023SJohn Marino /* Insn is a candidate to be moved speculatively from bb_src to bb_trg.
2006*e4b17023SJohn Marino Return 1 if insn is exception-free (and the motion is valid)
2007*e4b17023SJohn Marino and 0 otherwise. */
2008*e4b17023SJohn Marino
2009*e4b17023SJohn Marino static int
is_exception_free(rtx insn,int bb_src,int bb_trg)2010*e4b17023SJohn Marino is_exception_free (rtx insn, int bb_src, int bb_trg)
2011*e4b17023SJohn Marino {
2012*e4b17023SJohn Marino int insn_class = haifa_classify_insn (insn);
2013*e4b17023SJohn Marino
2014*e4b17023SJohn Marino /* Handle non-load insns. */
2015*e4b17023SJohn Marino switch (insn_class)
2016*e4b17023SJohn Marino {
2017*e4b17023SJohn Marino case TRAP_FREE:
2018*e4b17023SJohn Marino return 1;
2019*e4b17023SJohn Marino case TRAP_RISKY:
2020*e4b17023SJohn Marino return 0;
2021*e4b17023SJohn Marino default:;
2022*e4b17023SJohn Marino }
2023*e4b17023SJohn Marino
2024*e4b17023SJohn Marino /* Handle loads. */
2025*e4b17023SJohn Marino if (!flag_schedule_speculative_load)
2026*e4b17023SJohn Marino return 0;
2027*e4b17023SJohn Marino IS_LOAD_INSN (insn) = 1;
2028*e4b17023SJohn Marino switch (insn_class)
2029*e4b17023SJohn Marino {
2030*e4b17023SJohn Marino case IFREE:
2031*e4b17023SJohn Marino return (1);
2032*e4b17023SJohn Marino case IRISKY:
2033*e4b17023SJohn Marino return 0;
2034*e4b17023SJohn Marino case PFREE_CANDIDATE:
2035*e4b17023SJohn Marino if (is_pfree (insn, bb_src, bb_trg))
2036*e4b17023SJohn Marino return 1;
2037*e4b17023SJohn Marino /* Don't 'break' here: PFREE-candidate is also PRISKY-candidate. */
2038*e4b17023SJohn Marino case PRISKY_CANDIDATE:
2039*e4b17023SJohn Marino if (!flag_schedule_speculative_load_dangerous
2040*e4b17023SJohn Marino || is_prisky (insn, bb_src, bb_trg))
2041*e4b17023SJohn Marino return 0;
2042*e4b17023SJohn Marino break;
2043*e4b17023SJohn Marino default:;
2044*e4b17023SJohn Marino }
2045*e4b17023SJohn Marino
2046*e4b17023SJohn Marino return flag_schedule_speculative_load_dangerous;
2047*e4b17023SJohn Marino }
2048*e4b17023SJohn Marino
2049*e4b17023SJohn Marino /* The number of insns from the current block scheduled so far. */
2050*e4b17023SJohn Marino static int sched_target_n_insns;
2051*e4b17023SJohn Marino /* The number of insns from the current block to be scheduled in total. */
2052*e4b17023SJohn Marino static int target_n_insns;
2053*e4b17023SJohn Marino /* The number of insns from the entire region scheduled so far. */
2054*e4b17023SJohn Marino static int sched_n_insns;
2055*e4b17023SJohn Marino
2056*e4b17023SJohn Marino /* Implementations of the sched_info functions for region scheduling. */
2057*e4b17023SJohn Marino static void init_ready_list (void);
2058*e4b17023SJohn Marino static int can_schedule_ready_p (rtx);
2059*e4b17023SJohn Marino static void begin_schedule_ready (rtx);
2060*e4b17023SJohn Marino static ds_t new_ready (rtx, ds_t);
2061*e4b17023SJohn Marino static int schedule_more_p (void);
2062*e4b17023SJohn Marino static const char *rgn_print_insn (const_rtx, int);
2063*e4b17023SJohn Marino static int rgn_rank (rtx, rtx);
2064*e4b17023SJohn Marino static void compute_jump_reg_dependencies (rtx, regset);
2065*e4b17023SJohn Marino
2066*e4b17023SJohn Marino /* Functions for speculative scheduling. */
2067*e4b17023SJohn Marino static void rgn_add_remove_insn (rtx, int);
2068*e4b17023SJohn Marino static void rgn_add_block (basic_block, basic_block);
2069*e4b17023SJohn Marino static void rgn_fix_recovery_cfg (int, int, int);
2070*e4b17023SJohn Marino static basic_block advance_target_bb (basic_block, rtx);
2071*e4b17023SJohn Marino
2072*e4b17023SJohn Marino /* Return nonzero if there are more insns that should be scheduled. */
2073*e4b17023SJohn Marino
2074*e4b17023SJohn Marino static int
schedule_more_p(void)2075*e4b17023SJohn Marino schedule_more_p (void)
2076*e4b17023SJohn Marino {
2077*e4b17023SJohn Marino return sched_target_n_insns < target_n_insns;
2078*e4b17023SJohn Marino }
2079*e4b17023SJohn Marino
2080*e4b17023SJohn Marino /* Add all insns that are initially ready to the ready list READY. Called
2081*e4b17023SJohn Marino once before scheduling a set of insns. */
2082*e4b17023SJohn Marino
2083*e4b17023SJohn Marino static void
init_ready_list(void)2084*e4b17023SJohn Marino init_ready_list (void)
2085*e4b17023SJohn Marino {
2086*e4b17023SJohn Marino rtx prev_head = current_sched_info->prev_head;
2087*e4b17023SJohn Marino rtx next_tail = current_sched_info->next_tail;
2088*e4b17023SJohn Marino int bb_src;
2089*e4b17023SJohn Marino rtx insn;
2090*e4b17023SJohn Marino
2091*e4b17023SJohn Marino target_n_insns = 0;
2092*e4b17023SJohn Marino sched_target_n_insns = 0;
2093*e4b17023SJohn Marino sched_n_insns = 0;
2094*e4b17023SJohn Marino
2095*e4b17023SJohn Marino /* Print debugging information. */
2096*e4b17023SJohn Marino if (sched_verbose >= 5)
2097*e4b17023SJohn Marino debug_rgn_dependencies (target_bb);
2098*e4b17023SJohn Marino
2099*e4b17023SJohn Marino /* Prepare current target block info. */
2100*e4b17023SJohn Marino if (current_nr_blocks > 1)
2101*e4b17023SJohn Marino compute_trg_info (target_bb);
2102*e4b17023SJohn Marino
2103*e4b17023SJohn Marino /* Initialize ready list with all 'ready' insns in target block.
2104*e4b17023SJohn Marino Count number of insns in the target block being scheduled. */
2105*e4b17023SJohn Marino for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
2106*e4b17023SJohn Marino {
2107*e4b17023SJohn Marino try_ready (insn);
2108*e4b17023SJohn Marino target_n_insns++;
2109*e4b17023SJohn Marino
2110*e4b17023SJohn Marino gcc_assert (!(TODO_SPEC (insn) & BEGIN_CONTROL));
2111*e4b17023SJohn Marino }
2112*e4b17023SJohn Marino
2113*e4b17023SJohn Marino /* Add to ready list all 'ready' insns in valid source blocks.
2114*e4b17023SJohn Marino For speculative insns, check-live, exception-free, and
2115*e4b17023SJohn Marino issue-delay. */
2116*e4b17023SJohn Marino for (bb_src = target_bb + 1; bb_src < current_nr_blocks; bb_src++)
2117*e4b17023SJohn Marino if (IS_VALID (bb_src))
2118*e4b17023SJohn Marino {
2119*e4b17023SJohn Marino rtx src_head;
2120*e4b17023SJohn Marino rtx src_next_tail;
2121*e4b17023SJohn Marino rtx tail, head;
2122*e4b17023SJohn Marino
2123*e4b17023SJohn Marino get_ebb_head_tail (EBB_FIRST_BB (bb_src), EBB_LAST_BB (bb_src),
2124*e4b17023SJohn Marino &head, &tail);
2125*e4b17023SJohn Marino src_next_tail = NEXT_INSN (tail);
2126*e4b17023SJohn Marino src_head = head;
2127*e4b17023SJohn Marino
2128*e4b17023SJohn Marino for (insn = src_head; insn != src_next_tail; insn = NEXT_INSN (insn))
2129*e4b17023SJohn Marino if (INSN_P (insn))
2130*e4b17023SJohn Marino try_ready (insn);
2131*e4b17023SJohn Marino }
2132*e4b17023SJohn Marino }
2133*e4b17023SJohn Marino
2134*e4b17023SJohn Marino /* Called after taking INSN from the ready list. Returns nonzero if this
2135*e4b17023SJohn Marino insn can be scheduled, nonzero if we should silently discard it. */
2136*e4b17023SJohn Marino
2137*e4b17023SJohn Marino static int
can_schedule_ready_p(rtx insn)2138*e4b17023SJohn Marino can_schedule_ready_p (rtx insn)
2139*e4b17023SJohn Marino {
2140*e4b17023SJohn Marino /* An interblock motion? */
2141*e4b17023SJohn Marino if (INSN_BB (insn) != target_bb
2142*e4b17023SJohn Marino && IS_SPECULATIVE_INSN (insn)
2143*e4b17023SJohn Marino && !check_live (insn, INSN_BB (insn)))
2144*e4b17023SJohn Marino return 0;
2145*e4b17023SJohn Marino else
2146*e4b17023SJohn Marino return 1;
2147*e4b17023SJohn Marino }
2148*e4b17023SJohn Marino
2149*e4b17023SJohn Marino /* Updates counter and other information. Split from can_schedule_ready_p ()
2150*e4b17023SJohn Marino because when we schedule insn speculatively then insn passed to
2151*e4b17023SJohn Marino can_schedule_ready_p () differs from the one passed to
2152*e4b17023SJohn Marino begin_schedule_ready (). */
2153*e4b17023SJohn Marino static void
begin_schedule_ready(rtx insn)2154*e4b17023SJohn Marino begin_schedule_ready (rtx insn)
2155*e4b17023SJohn Marino {
2156*e4b17023SJohn Marino /* An interblock motion? */
2157*e4b17023SJohn Marino if (INSN_BB (insn) != target_bb)
2158*e4b17023SJohn Marino {
2159*e4b17023SJohn Marino if (IS_SPECULATIVE_INSN (insn))
2160*e4b17023SJohn Marino {
2161*e4b17023SJohn Marino gcc_assert (check_live (insn, INSN_BB (insn)));
2162*e4b17023SJohn Marino
2163*e4b17023SJohn Marino update_live (insn, INSN_BB (insn));
2164*e4b17023SJohn Marino
2165*e4b17023SJohn Marino /* For speculative load, mark insns fed by it. */
2166*e4b17023SJohn Marino if (IS_LOAD_INSN (insn) || FED_BY_SPEC_LOAD (insn))
2167*e4b17023SJohn Marino set_spec_fed (insn);
2168*e4b17023SJohn Marino
2169*e4b17023SJohn Marino nr_spec++;
2170*e4b17023SJohn Marino }
2171*e4b17023SJohn Marino nr_inter++;
2172*e4b17023SJohn Marino }
2173*e4b17023SJohn Marino else
2174*e4b17023SJohn Marino {
2175*e4b17023SJohn Marino /* In block motion. */
2176*e4b17023SJohn Marino sched_target_n_insns++;
2177*e4b17023SJohn Marino }
2178*e4b17023SJohn Marino sched_n_insns++;
2179*e4b17023SJohn Marino }
2180*e4b17023SJohn Marino
2181*e4b17023SJohn Marino /* Called after INSN has all its hard dependencies resolved and the speculation
2182*e4b17023SJohn Marino of type TS is enough to overcome them all.
2183*e4b17023SJohn Marino Return nonzero if it should be moved to the ready list or the queue, or zero
2184*e4b17023SJohn Marino if we should silently discard it. */
2185*e4b17023SJohn Marino static ds_t
new_ready(rtx next,ds_t ts)2186*e4b17023SJohn Marino new_ready (rtx next, ds_t ts)
2187*e4b17023SJohn Marino {
2188*e4b17023SJohn Marino if (INSN_BB (next) != target_bb)
2189*e4b17023SJohn Marino {
2190*e4b17023SJohn Marino int not_ex_free = 0;
2191*e4b17023SJohn Marino
2192*e4b17023SJohn Marino /* For speculative insns, before inserting to ready/queue,
2193*e4b17023SJohn Marino check live, exception-free, and issue-delay. */
2194*e4b17023SJohn Marino if (!IS_VALID (INSN_BB (next))
2195*e4b17023SJohn Marino || CANT_MOVE (next)
2196*e4b17023SJohn Marino || (IS_SPECULATIVE_INSN (next)
2197*e4b17023SJohn Marino && ((recog_memoized (next) >= 0
2198*e4b17023SJohn Marino && min_insn_conflict_delay (curr_state, next, next)
2199*e4b17023SJohn Marino > PARAM_VALUE (PARAM_MAX_SCHED_INSN_CONFLICT_DELAY))
2200*e4b17023SJohn Marino || IS_SPECULATION_CHECK_P (next)
2201*e4b17023SJohn Marino || !check_live (next, INSN_BB (next))
2202*e4b17023SJohn Marino || (not_ex_free = !is_exception_free (next, INSN_BB (next),
2203*e4b17023SJohn Marino target_bb)))))
2204*e4b17023SJohn Marino {
2205*e4b17023SJohn Marino if (not_ex_free
2206*e4b17023SJohn Marino /* We are here because is_exception_free () == false.
2207*e4b17023SJohn Marino But we possibly can handle that with control speculation. */
2208*e4b17023SJohn Marino && sched_deps_info->generate_spec_deps
2209*e4b17023SJohn Marino && spec_info->mask & BEGIN_CONTROL)
2210*e4b17023SJohn Marino {
2211*e4b17023SJohn Marino ds_t new_ds;
2212*e4b17023SJohn Marino
2213*e4b17023SJohn Marino /* Add control speculation to NEXT's dependency type. */
2214*e4b17023SJohn Marino new_ds = set_dep_weak (ts, BEGIN_CONTROL, MAX_DEP_WEAK);
2215*e4b17023SJohn Marino
2216*e4b17023SJohn Marino /* Check if NEXT can be speculated with new dependency type. */
2217*e4b17023SJohn Marino if (sched_insn_is_legitimate_for_speculation_p (next, new_ds))
2218*e4b17023SJohn Marino /* Here we got new control-speculative instruction. */
2219*e4b17023SJohn Marino ts = new_ds;
2220*e4b17023SJohn Marino else
2221*e4b17023SJohn Marino /* NEXT isn't ready yet. */
2222*e4b17023SJohn Marino ts = (ts & ~SPECULATIVE) | HARD_DEP;
2223*e4b17023SJohn Marino }
2224*e4b17023SJohn Marino else
2225*e4b17023SJohn Marino /* NEXT isn't ready yet. */
2226*e4b17023SJohn Marino ts = (ts & ~SPECULATIVE) | HARD_DEP;
2227*e4b17023SJohn Marino }
2228*e4b17023SJohn Marino }
2229*e4b17023SJohn Marino
2230*e4b17023SJohn Marino return ts;
2231*e4b17023SJohn Marino }
2232*e4b17023SJohn Marino
2233*e4b17023SJohn Marino /* Return a string that contains the insn uid and optionally anything else
2234*e4b17023SJohn Marino necessary to identify this insn in an output. It's valid to use a
2235*e4b17023SJohn Marino static buffer for this. The ALIGNED parameter should cause the string
2236*e4b17023SJohn Marino to be formatted so that multiple output lines will line up nicely. */
2237*e4b17023SJohn Marino
2238*e4b17023SJohn Marino static const char *
rgn_print_insn(const_rtx insn,int aligned)2239*e4b17023SJohn Marino rgn_print_insn (const_rtx insn, int aligned)
2240*e4b17023SJohn Marino {
2241*e4b17023SJohn Marino static char tmp[80];
2242*e4b17023SJohn Marino
2243*e4b17023SJohn Marino if (aligned)
2244*e4b17023SJohn Marino sprintf (tmp, "b%3d: i%4d", INSN_BB (insn), INSN_UID (insn));
2245*e4b17023SJohn Marino else
2246*e4b17023SJohn Marino {
2247*e4b17023SJohn Marino if (current_nr_blocks > 1 && INSN_BB (insn) != target_bb)
2248*e4b17023SJohn Marino sprintf (tmp, "%d/b%d", INSN_UID (insn), INSN_BB (insn));
2249*e4b17023SJohn Marino else
2250*e4b17023SJohn Marino sprintf (tmp, "%d", INSN_UID (insn));
2251*e4b17023SJohn Marino }
2252*e4b17023SJohn Marino return tmp;
2253*e4b17023SJohn Marino }
2254*e4b17023SJohn Marino
2255*e4b17023SJohn Marino /* Compare priority of two insns. Return a positive number if the second
2256*e4b17023SJohn Marino insn is to be preferred for scheduling, and a negative one if the first
2257*e4b17023SJohn Marino is to be preferred. Zero if they are equally good. */
2258*e4b17023SJohn Marino
2259*e4b17023SJohn Marino static int
rgn_rank(rtx insn1,rtx insn2)2260*e4b17023SJohn Marino rgn_rank (rtx insn1, rtx insn2)
2261*e4b17023SJohn Marino {
2262*e4b17023SJohn Marino /* Some comparison make sense in interblock scheduling only. */
2263*e4b17023SJohn Marino if (INSN_BB (insn1) != INSN_BB (insn2))
2264*e4b17023SJohn Marino {
2265*e4b17023SJohn Marino int spec_val, prob_val;
2266*e4b17023SJohn Marino
2267*e4b17023SJohn Marino /* Prefer an inblock motion on an interblock motion. */
2268*e4b17023SJohn Marino if ((INSN_BB (insn2) == target_bb) && (INSN_BB (insn1) != target_bb))
2269*e4b17023SJohn Marino return 1;
2270*e4b17023SJohn Marino if ((INSN_BB (insn1) == target_bb) && (INSN_BB (insn2) != target_bb))
2271*e4b17023SJohn Marino return -1;
2272*e4b17023SJohn Marino
2273*e4b17023SJohn Marino /* Prefer a useful motion on a speculative one. */
2274*e4b17023SJohn Marino spec_val = IS_SPECULATIVE_INSN (insn1) - IS_SPECULATIVE_INSN (insn2);
2275*e4b17023SJohn Marino if (spec_val)
2276*e4b17023SJohn Marino return spec_val;
2277*e4b17023SJohn Marino
2278*e4b17023SJohn Marino /* Prefer a more probable (speculative) insn. */
2279*e4b17023SJohn Marino prob_val = INSN_PROBABILITY (insn2) - INSN_PROBABILITY (insn1);
2280*e4b17023SJohn Marino if (prob_val)
2281*e4b17023SJohn Marino return prob_val;
2282*e4b17023SJohn Marino }
2283*e4b17023SJohn Marino return 0;
2284*e4b17023SJohn Marino }
2285*e4b17023SJohn Marino
2286*e4b17023SJohn Marino /* NEXT is an instruction that depends on INSN (a backward dependence);
2287*e4b17023SJohn Marino return nonzero if we should include this dependence in priority
2288*e4b17023SJohn Marino calculations. */
2289*e4b17023SJohn Marino
2290*e4b17023SJohn Marino int
contributes_to_priority(rtx next,rtx insn)2291*e4b17023SJohn Marino contributes_to_priority (rtx next, rtx insn)
2292*e4b17023SJohn Marino {
2293*e4b17023SJohn Marino /* NEXT and INSN reside in one ebb. */
2294*e4b17023SJohn Marino return BLOCK_TO_BB (BLOCK_NUM (next)) == BLOCK_TO_BB (BLOCK_NUM (insn));
2295*e4b17023SJohn Marino }
2296*e4b17023SJohn Marino
2297*e4b17023SJohn Marino /* INSN is a JUMP_INSN. Store the set of registers that must be
2298*e4b17023SJohn Marino considered as used by this jump in USED. */
2299*e4b17023SJohn Marino
2300*e4b17023SJohn Marino static void
compute_jump_reg_dependencies(rtx insn ATTRIBUTE_UNUSED,regset used ATTRIBUTE_UNUSED)2301*e4b17023SJohn Marino compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
2302*e4b17023SJohn Marino regset used ATTRIBUTE_UNUSED)
2303*e4b17023SJohn Marino {
2304*e4b17023SJohn Marino /* Nothing to do here, since we postprocess jumps in
2305*e4b17023SJohn Marino add_branch_dependences. */
2306*e4b17023SJohn Marino }
2307*e4b17023SJohn Marino
2308*e4b17023SJohn Marino /* This variable holds common_sched_info hooks and data relevant to
2309*e4b17023SJohn Marino the interblock scheduler. */
2310*e4b17023SJohn Marino static struct common_sched_info_def rgn_common_sched_info;
2311*e4b17023SJohn Marino
2312*e4b17023SJohn Marino
2313*e4b17023SJohn Marino /* This holds data for the dependence analysis relevant to
2314*e4b17023SJohn Marino the interblock scheduler. */
2315*e4b17023SJohn Marino static struct sched_deps_info_def rgn_sched_deps_info;
2316*e4b17023SJohn Marino
2317*e4b17023SJohn Marino /* This holds constant data used for initializing the above structure
2318*e4b17023SJohn Marino for the Haifa scheduler. */
2319*e4b17023SJohn Marino static const struct sched_deps_info_def rgn_const_sched_deps_info =
2320*e4b17023SJohn Marino {
2321*e4b17023SJohn Marino compute_jump_reg_dependencies,
2322*e4b17023SJohn Marino NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2323*e4b17023SJohn Marino 0, 0, 0
2324*e4b17023SJohn Marino };
2325*e4b17023SJohn Marino
2326*e4b17023SJohn Marino /* Same as above, but for the selective scheduler. */
2327*e4b17023SJohn Marino static const struct sched_deps_info_def rgn_const_sel_sched_deps_info =
2328*e4b17023SJohn Marino {
2329*e4b17023SJohn Marino compute_jump_reg_dependencies,
2330*e4b17023SJohn Marino NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2331*e4b17023SJohn Marino 0, 0, 0
2332*e4b17023SJohn Marino };
2333*e4b17023SJohn Marino
2334*e4b17023SJohn Marino /* Return true if scheduling INSN will trigger finish of scheduling
2335*e4b17023SJohn Marino current block. */
2336*e4b17023SJohn Marino static bool
rgn_insn_finishes_block_p(rtx insn)2337*e4b17023SJohn Marino rgn_insn_finishes_block_p (rtx insn)
2338*e4b17023SJohn Marino {
2339*e4b17023SJohn Marino if (INSN_BB (insn) == target_bb
2340*e4b17023SJohn Marino && sched_target_n_insns + 1 == target_n_insns)
2341*e4b17023SJohn Marino /* INSN is the last not-scheduled instruction in the current block. */
2342*e4b17023SJohn Marino return true;
2343*e4b17023SJohn Marino
2344*e4b17023SJohn Marino return false;
2345*e4b17023SJohn Marino }
2346*e4b17023SJohn Marino
2347*e4b17023SJohn Marino /* Used in schedule_insns to initialize current_sched_info for scheduling
2348*e4b17023SJohn Marino regions (or single basic blocks). */
2349*e4b17023SJohn Marino
2350*e4b17023SJohn Marino static const struct haifa_sched_info rgn_const_sched_info =
2351*e4b17023SJohn Marino {
2352*e4b17023SJohn Marino init_ready_list,
2353*e4b17023SJohn Marino can_schedule_ready_p,
2354*e4b17023SJohn Marino schedule_more_p,
2355*e4b17023SJohn Marino new_ready,
2356*e4b17023SJohn Marino rgn_rank,
2357*e4b17023SJohn Marino rgn_print_insn,
2358*e4b17023SJohn Marino contributes_to_priority,
2359*e4b17023SJohn Marino rgn_insn_finishes_block_p,
2360*e4b17023SJohn Marino
2361*e4b17023SJohn Marino NULL, NULL,
2362*e4b17023SJohn Marino NULL, NULL,
2363*e4b17023SJohn Marino 0, 0,
2364*e4b17023SJohn Marino
2365*e4b17023SJohn Marino rgn_add_remove_insn,
2366*e4b17023SJohn Marino begin_schedule_ready,
2367*e4b17023SJohn Marino NULL,
2368*e4b17023SJohn Marino advance_target_bb,
2369*e4b17023SJohn Marino NULL, NULL,
2370*e4b17023SJohn Marino SCHED_RGN
2371*e4b17023SJohn Marino };
2372*e4b17023SJohn Marino
2373*e4b17023SJohn Marino /* This variable holds the data and hooks needed to the Haifa scheduler backend
2374*e4b17023SJohn Marino for the interblock scheduler frontend. */
2375*e4b17023SJohn Marino static struct haifa_sched_info rgn_sched_info;
2376*e4b17023SJohn Marino
2377*e4b17023SJohn Marino /* Returns maximum priority that an insn was assigned to. */
2378*e4b17023SJohn Marino
2379*e4b17023SJohn Marino int
get_rgn_sched_max_insns_priority(void)2380*e4b17023SJohn Marino get_rgn_sched_max_insns_priority (void)
2381*e4b17023SJohn Marino {
2382*e4b17023SJohn Marino return rgn_sched_info.sched_max_insns_priority;
2383*e4b17023SJohn Marino }
2384*e4b17023SJohn Marino
2385*e4b17023SJohn Marino /* Determine if PAT sets a TARGET_CLASS_LIKELY_SPILLED_P register. */
2386*e4b17023SJohn Marino
2387*e4b17023SJohn Marino static bool
sets_likely_spilled(rtx pat)2388*e4b17023SJohn Marino sets_likely_spilled (rtx pat)
2389*e4b17023SJohn Marino {
2390*e4b17023SJohn Marino bool ret = false;
2391*e4b17023SJohn Marino note_stores (pat, sets_likely_spilled_1, &ret);
2392*e4b17023SJohn Marino return ret;
2393*e4b17023SJohn Marino }
2394*e4b17023SJohn Marino
2395*e4b17023SJohn Marino static void
sets_likely_spilled_1(rtx x,const_rtx pat,void * data)2396*e4b17023SJohn Marino sets_likely_spilled_1 (rtx x, const_rtx pat, void *data)
2397*e4b17023SJohn Marino {
2398*e4b17023SJohn Marino bool *ret = (bool *) data;
2399*e4b17023SJohn Marino
2400*e4b17023SJohn Marino if (GET_CODE (pat) == SET
2401*e4b17023SJohn Marino && REG_P (x)
2402*e4b17023SJohn Marino && HARD_REGISTER_P (x)
2403*e4b17023SJohn Marino && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (x))))
2404*e4b17023SJohn Marino *ret = true;
2405*e4b17023SJohn Marino }
2406*e4b17023SJohn Marino
2407*e4b17023SJohn Marino /* A bitmap to note insns that participate in any dependency. Used in
2408*e4b17023SJohn Marino add_branch_dependences. */
2409*e4b17023SJohn Marino static sbitmap insn_referenced;
2410*e4b17023SJohn Marino
2411*e4b17023SJohn Marino /* Add dependences so that branches are scheduled to run last in their
2412*e4b17023SJohn Marino block. */
2413*e4b17023SJohn Marino static void
add_branch_dependences(rtx head,rtx tail)2414*e4b17023SJohn Marino add_branch_dependences (rtx head, rtx tail)
2415*e4b17023SJohn Marino {
2416*e4b17023SJohn Marino rtx insn, last;
2417*e4b17023SJohn Marino
2418*e4b17023SJohn Marino /* For all branches, calls, uses, clobbers, cc0 setters, and instructions
2419*e4b17023SJohn Marino that can throw exceptions, force them to remain in order at the end of
2420*e4b17023SJohn Marino the block by adding dependencies and giving the last a high priority.
2421*e4b17023SJohn Marino There may be notes present, and prev_head may also be a note.
2422*e4b17023SJohn Marino
2423*e4b17023SJohn Marino Branches must obviously remain at the end. Calls should remain at the
2424*e4b17023SJohn Marino end since moving them results in worse register allocation. Uses remain
2425*e4b17023SJohn Marino at the end to ensure proper register allocation.
2426*e4b17023SJohn Marino
2427*e4b17023SJohn Marino cc0 setters remain at the end because they can't be moved away from
2428*e4b17023SJohn Marino their cc0 user.
2429*e4b17023SJohn Marino
2430*e4b17023SJohn Marino COND_EXEC insns cannot be moved past a branch (see e.g. PR17808).
2431*e4b17023SJohn Marino
2432*e4b17023SJohn Marino Insns setting TARGET_CLASS_LIKELY_SPILLED_P registers (usually return
2433*e4b17023SJohn Marino values) are not moved before reload because we can wind up with register
2434*e4b17023SJohn Marino allocation failures. */
2435*e4b17023SJohn Marino
2436*e4b17023SJohn Marino while (tail != head && DEBUG_INSN_P (tail))
2437*e4b17023SJohn Marino tail = PREV_INSN (tail);
2438*e4b17023SJohn Marino
2439*e4b17023SJohn Marino insn = tail;
2440*e4b17023SJohn Marino last = 0;
2441*e4b17023SJohn Marino while (CALL_P (insn)
2442*e4b17023SJohn Marino || JUMP_P (insn)
2443*e4b17023SJohn Marino || (NONJUMP_INSN_P (insn)
2444*e4b17023SJohn Marino && (GET_CODE (PATTERN (insn)) == USE
2445*e4b17023SJohn Marino || GET_CODE (PATTERN (insn)) == CLOBBER
2446*e4b17023SJohn Marino || can_throw_internal (insn)
2447*e4b17023SJohn Marino #ifdef HAVE_cc0
2448*e4b17023SJohn Marino || sets_cc0_p (PATTERN (insn))
2449*e4b17023SJohn Marino #endif
2450*e4b17023SJohn Marino || (!reload_completed
2451*e4b17023SJohn Marino && sets_likely_spilled (PATTERN (insn)))))
2452*e4b17023SJohn Marino || NOTE_P (insn))
2453*e4b17023SJohn Marino {
2454*e4b17023SJohn Marino if (!NOTE_P (insn))
2455*e4b17023SJohn Marino {
2456*e4b17023SJohn Marino if (last != 0
2457*e4b17023SJohn Marino && sd_find_dep_between (insn, last, false) == NULL)
2458*e4b17023SJohn Marino {
2459*e4b17023SJohn Marino if (! sched_insns_conditions_mutex_p (last, insn))
2460*e4b17023SJohn Marino add_dependence (last, insn, REG_DEP_ANTI);
2461*e4b17023SJohn Marino SET_BIT (insn_referenced, INSN_LUID (insn));
2462*e4b17023SJohn Marino }
2463*e4b17023SJohn Marino
2464*e4b17023SJohn Marino CANT_MOVE (insn) = 1;
2465*e4b17023SJohn Marino
2466*e4b17023SJohn Marino last = insn;
2467*e4b17023SJohn Marino }
2468*e4b17023SJohn Marino
2469*e4b17023SJohn Marino /* Don't overrun the bounds of the basic block. */
2470*e4b17023SJohn Marino if (insn == head)
2471*e4b17023SJohn Marino break;
2472*e4b17023SJohn Marino
2473*e4b17023SJohn Marino do
2474*e4b17023SJohn Marino insn = PREV_INSN (insn);
2475*e4b17023SJohn Marino while (insn != head && DEBUG_INSN_P (insn));
2476*e4b17023SJohn Marino }
2477*e4b17023SJohn Marino
2478*e4b17023SJohn Marino /* Make sure these insns are scheduled last in their block. */
2479*e4b17023SJohn Marino insn = last;
2480*e4b17023SJohn Marino if (insn != 0)
2481*e4b17023SJohn Marino while (insn != head)
2482*e4b17023SJohn Marino {
2483*e4b17023SJohn Marino insn = prev_nonnote_insn (insn);
2484*e4b17023SJohn Marino
2485*e4b17023SJohn Marino if (TEST_BIT (insn_referenced, INSN_LUID (insn))
2486*e4b17023SJohn Marino || DEBUG_INSN_P (insn))
2487*e4b17023SJohn Marino continue;
2488*e4b17023SJohn Marino
2489*e4b17023SJohn Marino if (! sched_insns_conditions_mutex_p (last, insn))
2490*e4b17023SJohn Marino add_dependence (last, insn, REG_DEP_ANTI);
2491*e4b17023SJohn Marino }
2492*e4b17023SJohn Marino
2493*e4b17023SJohn Marino if (!targetm.have_conditional_execution ())
2494*e4b17023SJohn Marino return;
2495*e4b17023SJohn Marino
2496*e4b17023SJohn Marino /* Finally, if the block ends in a jump, and we are doing intra-block
2497*e4b17023SJohn Marino scheduling, make sure that the branch depends on any COND_EXEC insns
2498*e4b17023SJohn Marino inside the block to avoid moving the COND_EXECs past the branch insn.
2499*e4b17023SJohn Marino
2500*e4b17023SJohn Marino We only have to do this after reload, because (1) before reload there
2501*e4b17023SJohn Marino are no COND_EXEC insns, and (2) the region scheduler is an intra-block
2502*e4b17023SJohn Marino scheduler after reload.
2503*e4b17023SJohn Marino
2504*e4b17023SJohn Marino FIXME: We could in some cases move COND_EXEC insns past the branch if
2505*e4b17023SJohn Marino this scheduler would be a little smarter. Consider this code:
2506*e4b17023SJohn Marino
2507*e4b17023SJohn Marino T = [addr]
2508*e4b17023SJohn Marino C ? addr += 4
2509*e4b17023SJohn Marino !C ? X += 12
2510*e4b17023SJohn Marino C ? T += 1
2511*e4b17023SJohn Marino C ? jump foo
2512*e4b17023SJohn Marino
2513*e4b17023SJohn Marino On a target with a one cycle stall on a memory access the optimal
2514*e4b17023SJohn Marino sequence would be:
2515*e4b17023SJohn Marino
2516*e4b17023SJohn Marino T = [addr]
2517*e4b17023SJohn Marino C ? addr += 4
2518*e4b17023SJohn Marino C ? T += 1
2519*e4b17023SJohn Marino C ? jump foo
2520*e4b17023SJohn Marino !C ? X += 12
2521*e4b17023SJohn Marino
2522*e4b17023SJohn Marino We don't want to put the 'X += 12' before the branch because it just
2523*e4b17023SJohn Marino wastes a cycle of execution time when the branch is taken.
2524*e4b17023SJohn Marino
2525*e4b17023SJohn Marino Note that in the example "!C" will always be true. That is another
2526*e4b17023SJohn Marino possible improvement for handling COND_EXECs in this scheduler: it
2527*e4b17023SJohn Marino could remove always-true predicates. */
2528*e4b17023SJohn Marino
2529*e4b17023SJohn Marino if (!reload_completed || ! JUMP_P (tail))
2530*e4b17023SJohn Marino return;
2531*e4b17023SJohn Marino
2532*e4b17023SJohn Marino insn = tail;
2533*e4b17023SJohn Marino while (insn != head)
2534*e4b17023SJohn Marino {
2535*e4b17023SJohn Marino insn = PREV_INSN (insn);
2536*e4b17023SJohn Marino
2537*e4b17023SJohn Marino /* Note that we want to add this dependency even when
2538*e4b17023SJohn Marino sched_insns_conditions_mutex_p returns true. The whole point
2539*e4b17023SJohn Marino is that we _want_ this dependency, even if these insns really
2540*e4b17023SJohn Marino are independent. */
2541*e4b17023SJohn Marino if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC)
2542*e4b17023SJohn Marino add_dependence (tail, insn, REG_DEP_ANTI);
2543*e4b17023SJohn Marino }
2544*e4b17023SJohn Marino }
2545*e4b17023SJohn Marino
2546*e4b17023SJohn Marino /* Data structures for the computation of data dependences in a regions. We
2547*e4b17023SJohn Marino keep one `deps' structure for every basic block. Before analyzing the
2548*e4b17023SJohn Marino data dependences for a bb, its variables are initialized as a function of
2549*e4b17023SJohn Marino the variables of its predecessors. When the analysis for a bb completes,
2550*e4b17023SJohn Marino we save the contents to the corresponding bb_deps[bb] variable. */
2551*e4b17023SJohn Marino
2552*e4b17023SJohn Marino static struct deps_desc *bb_deps;
2553*e4b17023SJohn Marino
2554*e4b17023SJohn Marino static void
concat_insn_mem_list(rtx copy_insns,rtx copy_mems,rtx * old_insns_p,rtx * old_mems_p)2555*e4b17023SJohn Marino concat_insn_mem_list (rtx copy_insns, rtx copy_mems, rtx *old_insns_p,
2556*e4b17023SJohn Marino rtx *old_mems_p)
2557*e4b17023SJohn Marino {
2558*e4b17023SJohn Marino rtx new_insns = *old_insns_p;
2559*e4b17023SJohn Marino rtx new_mems = *old_mems_p;
2560*e4b17023SJohn Marino
2561*e4b17023SJohn Marino while (copy_insns)
2562*e4b17023SJohn Marino {
2563*e4b17023SJohn Marino new_insns = alloc_INSN_LIST (XEXP (copy_insns, 0), new_insns);
2564*e4b17023SJohn Marino new_mems = alloc_EXPR_LIST (VOIDmode, XEXP (copy_mems, 0), new_mems);
2565*e4b17023SJohn Marino copy_insns = XEXP (copy_insns, 1);
2566*e4b17023SJohn Marino copy_mems = XEXP (copy_mems, 1);
2567*e4b17023SJohn Marino }
2568*e4b17023SJohn Marino
2569*e4b17023SJohn Marino *old_insns_p = new_insns;
2570*e4b17023SJohn Marino *old_mems_p = new_mems;
2571*e4b17023SJohn Marino }
2572*e4b17023SJohn Marino
2573*e4b17023SJohn Marino /* Join PRED_DEPS to the SUCC_DEPS. */
2574*e4b17023SJohn Marino void
deps_join(struct deps_desc * succ_deps,struct deps_desc * pred_deps)2575*e4b17023SJohn Marino deps_join (struct deps_desc *succ_deps, struct deps_desc *pred_deps)
2576*e4b17023SJohn Marino {
2577*e4b17023SJohn Marino unsigned reg;
2578*e4b17023SJohn Marino reg_set_iterator rsi;
2579*e4b17023SJohn Marino
2580*e4b17023SJohn Marino /* The reg_last lists are inherited by successor. */
2581*e4b17023SJohn Marino EXECUTE_IF_SET_IN_REG_SET (&pred_deps->reg_last_in_use, 0, reg, rsi)
2582*e4b17023SJohn Marino {
2583*e4b17023SJohn Marino struct deps_reg *pred_rl = &pred_deps->reg_last[reg];
2584*e4b17023SJohn Marino struct deps_reg *succ_rl = &succ_deps->reg_last[reg];
2585*e4b17023SJohn Marino
2586*e4b17023SJohn Marino succ_rl->uses = concat_INSN_LIST (pred_rl->uses, succ_rl->uses);
2587*e4b17023SJohn Marino succ_rl->sets = concat_INSN_LIST (pred_rl->sets, succ_rl->sets);
2588*e4b17023SJohn Marino succ_rl->implicit_sets
2589*e4b17023SJohn Marino = concat_INSN_LIST (pred_rl->implicit_sets, succ_rl->implicit_sets);
2590*e4b17023SJohn Marino succ_rl->clobbers = concat_INSN_LIST (pred_rl->clobbers,
2591*e4b17023SJohn Marino succ_rl->clobbers);
2592*e4b17023SJohn Marino succ_rl->uses_length += pred_rl->uses_length;
2593*e4b17023SJohn Marino succ_rl->clobbers_length += pred_rl->clobbers_length;
2594*e4b17023SJohn Marino }
2595*e4b17023SJohn Marino IOR_REG_SET (&succ_deps->reg_last_in_use, &pred_deps->reg_last_in_use);
2596*e4b17023SJohn Marino
2597*e4b17023SJohn Marino /* Mem read/write lists are inherited by successor. */
2598*e4b17023SJohn Marino concat_insn_mem_list (pred_deps->pending_read_insns,
2599*e4b17023SJohn Marino pred_deps->pending_read_mems,
2600*e4b17023SJohn Marino &succ_deps->pending_read_insns,
2601*e4b17023SJohn Marino &succ_deps->pending_read_mems);
2602*e4b17023SJohn Marino concat_insn_mem_list (pred_deps->pending_write_insns,
2603*e4b17023SJohn Marino pred_deps->pending_write_mems,
2604*e4b17023SJohn Marino &succ_deps->pending_write_insns,
2605*e4b17023SJohn Marino &succ_deps->pending_write_mems);
2606*e4b17023SJohn Marino
2607*e4b17023SJohn Marino succ_deps->pending_jump_insns
2608*e4b17023SJohn Marino = concat_INSN_LIST (pred_deps->pending_jump_insns,
2609*e4b17023SJohn Marino succ_deps->pending_jump_insns);
2610*e4b17023SJohn Marino succ_deps->last_pending_memory_flush
2611*e4b17023SJohn Marino = concat_INSN_LIST (pred_deps->last_pending_memory_flush,
2612*e4b17023SJohn Marino succ_deps->last_pending_memory_flush);
2613*e4b17023SJohn Marino
2614*e4b17023SJohn Marino succ_deps->pending_read_list_length += pred_deps->pending_read_list_length;
2615*e4b17023SJohn Marino succ_deps->pending_write_list_length += pred_deps->pending_write_list_length;
2616*e4b17023SJohn Marino succ_deps->pending_flush_length += pred_deps->pending_flush_length;
2617*e4b17023SJohn Marino
2618*e4b17023SJohn Marino /* last_function_call is inherited by successor. */
2619*e4b17023SJohn Marino succ_deps->last_function_call
2620*e4b17023SJohn Marino = concat_INSN_LIST (pred_deps->last_function_call,
2621*e4b17023SJohn Marino succ_deps->last_function_call);
2622*e4b17023SJohn Marino
2623*e4b17023SJohn Marino /* last_function_call_may_noreturn is inherited by successor. */
2624*e4b17023SJohn Marino succ_deps->last_function_call_may_noreturn
2625*e4b17023SJohn Marino = concat_INSN_LIST (pred_deps->last_function_call_may_noreturn,
2626*e4b17023SJohn Marino succ_deps->last_function_call_may_noreturn);
2627*e4b17023SJohn Marino
2628*e4b17023SJohn Marino /* sched_before_next_call is inherited by successor. */
2629*e4b17023SJohn Marino succ_deps->sched_before_next_call
2630*e4b17023SJohn Marino = concat_INSN_LIST (pred_deps->sched_before_next_call,
2631*e4b17023SJohn Marino succ_deps->sched_before_next_call);
2632*e4b17023SJohn Marino }
2633*e4b17023SJohn Marino
2634*e4b17023SJohn Marino /* After computing the dependencies for block BB, propagate the dependencies
2635*e4b17023SJohn Marino found in TMP_DEPS to the successors of the block. */
2636*e4b17023SJohn Marino static void
propagate_deps(int bb,struct deps_desc * pred_deps)2637*e4b17023SJohn Marino propagate_deps (int bb, struct deps_desc *pred_deps)
2638*e4b17023SJohn Marino {
2639*e4b17023SJohn Marino basic_block block = BASIC_BLOCK (BB_TO_BLOCK (bb));
2640*e4b17023SJohn Marino edge_iterator ei;
2641*e4b17023SJohn Marino edge e;
2642*e4b17023SJohn Marino
2643*e4b17023SJohn Marino /* bb's structures are inherited by its successors. */
2644*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, block->succs)
2645*e4b17023SJohn Marino {
2646*e4b17023SJohn Marino /* Only bbs "below" bb, in the same region, are interesting. */
2647*e4b17023SJohn Marino if (e->dest == EXIT_BLOCK_PTR
2648*e4b17023SJohn Marino || CONTAINING_RGN (block->index) != CONTAINING_RGN (e->dest->index)
2649*e4b17023SJohn Marino || BLOCK_TO_BB (e->dest->index) <= bb)
2650*e4b17023SJohn Marino continue;
2651*e4b17023SJohn Marino
2652*e4b17023SJohn Marino deps_join (bb_deps + BLOCK_TO_BB (e->dest->index), pred_deps);
2653*e4b17023SJohn Marino }
2654*e4b17023SJohn Marino
2655*e4b17023SJohn Marino /* These lists should point to the right place, for correct
2656*e4b17023SJohn Marino freeing later. */
2657*e4b17023SJohn Marino bb_deps[bb].pending_read_insns = pred_deps->pending_read_insns;
2658*e4b17023SJohn Marino bb_deps[bb].pending_read_mems = pred_deps->pending_read_mems;
2659*e4b17023SJohn Marino bb_deps[bb].pending_write_insns = pred_deps->pending_write_insns;
2660*e4b17023SJohn Marino bb_deps[bb].pending_write_mems = pred_deps->pending_write_mems;
2661*e4b17023SJohn Marino bb_deps[bb].pending_jump_insns = pred_deps->pending_jump_insns;
2662*e4b17023SJohn Marino
2663*e4b17023SJohn Marino /* Can't allow these to be freed twice. */
2664*e4b17023SJohn Marino pred_deps->pending_read_insns = 0;
2665*e4b17023SJohn Marino pred_deps->pending_read_mems = 0;
2666*e4b17023SJohn Marino pred_deps->pending_write_insns = 0;
2667*e4b17023SJohn Marino pred_deps->pending_write_mems = 0;
2668*e4b17023SJohn Marino pred_deps->pending_jump_insns = 0;
2669*e4b17023SJohn Marino }
2670*e4b17023SJohn Marino
2671*e4b17023SJohn Marino /* Compute dependences inside bb. In a multiple blocks region:
2672*e4b17023SJohn Marino (1) a bb is analyzed after its predecessors, and (2) the lists in
2673*e4b17023SJohn Marino effect at the end of bb (after analyzing for bb) are inherited by
2674*e4b17023SJohn Marino bb's successors.
2675*e4b17023SJohn Marino
2676*e4b17023SJohn Marino Specifically for reg-reg data dependences, the block insns are
2677*e4b17023SJohn Marino scanned by sched_analyze () top-to-bottom. Three lists are
2678*e4b17023SJohn Marino maintained by sched_analyze (): reg_last[].sets for register DEFs,
2679*e4b17023SJohn Marino reg_last[].implicit_sets for implicit hard register DEFs, and
2680*e4b17023SJohn Marino reg_last[].uses for register USEs.
2681*e4b17023SJohn Marino
2682*e4b17023SJohn Marino When analysis is completed for bb, we update for its successors:
2683*e4b17023SJohn Marino ; - DEFS[succ] = Union (DEFS [succ], DEFS [bb])
2684*e4b17023SJohn Marino ; - IMPLICIT_DEFS[succ] = Union (IMPLICIT_DEFS [succ], IMPLICIT_DEFS [bb])
2685*e4b17023SJohn Marino ; - USES[succ] = Union (USES [succ], DEFS [bb])
2686*e4b17023SJohn Marino
2687*e4b17023SJohn Marino The mechanism for computing mem-mem data dependence is very
2688*e4b17023SJohn Marino similar, and the result is interblock dependences in the region. */
2689*e4b17023SJohn Marino
2690*e4b17023SJohn Marino static void
compute_block_dependences(int bb)2691*e4b17023SJohn Marino compute_block_dependences (int bb)
2692*e4b17023SJohn Marino {
2693*e4b17023SJohn Marino rtx head, tail;
2694*e4b17023SJohn Marino struct deps_desc tmp_deps;
2695*e4b17023SJohn Marino
2696*e4b17023SJohn Marino tmp_deps = bb_deps[bb];
2697*e4b17023SJohn Marino
2698*e4b17023SJohn Marino /* Do the analysis for this block. */
2699*e4b17023SJohn Marino gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
2700*e4b17023SJohn Marino get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
2701*e4b17023SJohn Marino
2702*e4b17023SJohn Marino sched_analyze (&tmp_deps, head, tail);
2703*e4b17023SJohn Marino
2704*e4b17023SJohn Marino /* Selective scheduling handles control dependencies by itself. */
2705*e4b17023SJohn Marino if (!sel_sched_p ())
2706*e4b17023SJohn Marino add_branch_dependences (head, tail);
2707*e4b17023SJohn Marino
2708*e4b17023SJohn Marino if (current_nr_blocks > 1)
2709*e4b17023SJohn Marino propagate_deps (bb, &tmp_deps);
2710*e4b17023SJohn Marino
2711*e4b17023SJohn Marino /* Free up the INSN_LISTs. */
2712*e4b17023SJohn Marino free_deps (&tmp_deps);
2713*e4b17023SJohn Marino
2714*e4b17023SJohn Marino if (targetm.sched.dependencies_evaluation_hook)
2715*e4b17023SJohn Marino targetm.sched.dependencies_evaluation_hook (head, tail);
2716*e4b17023SJohn Marino }
2717*e4b17023SJohn Marino
2718*e4b17023SJohn Marino /* Free dependencies of instructions inside BB. */
2719*e4b17023SJohn Marino static void
free_block_dependencies(int bb)2720*e4b17023SJohn Marino free_block_dependencies (int bb)
2721*e4b17023SJohn Marino {
2722*e4b17023SJohn Marino rtx head;
2723*e4b17023SJohn Marino rtx tail;
2724*e4b17023SJohn Marino
2725*e4b17023SJohn Marino get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
2726*e4b17023SJohn Marino
2727*e4b17023SJohn Marino if (no_real_insns_p (head, tail))
2728*e4b17023SJohn Marino return;
2729*e4b17023SJohn Marino
2730*e4b17023SJohn Marino sched_free_deps (head, tail, true);
2731*e4b17023SJohn Marino }
2732*e4b17023SJohn Marino
2733*e4b17023SJohn Marino /* Remove all INSN_LISTs and EXPR_LISTs from the pending lists and add
2734*e4b17023SJohn Marino them to the unused_*_list variables, so that they can be reused. */
2735*e4b17023SJohn Marino
2736*e4b17023SJohn Marino static void
free_pending_lists(void)2737*e4b17023SJohn Marino free_pending_lists (void)
2738*e4b17023SJohn Marino {
2739*e4b17023SJohn Marino int bb;
2740*e4b17023SJohn Marino
2741*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
2742*e4b17023SJohn Marino {
2743*e4b17023SJohn Marino free_INSN_LIST_list (&bb_deps[bb].pending_read_insns);
2744*e4b17023SJohn Marino free_INSN_LIST_list (&bb_deps[bb].pending_write_insns);
2745*e4b17023SJohn Marino free_EXPR_LIST_list (&bb_deps[bb].pending_read_mems);
2746*e4b17023SJohn Marino free_EXPR_LIST_list (&bb_deps[bb].pending_write_mems);
2747*e4b17023SJohn Marino free_INSN_LIST_list (&bb_deps[bb].pending_jump_insns);
2748*e4b17023SJohn Marino }
2749*e4b17023SJohn Marino }
2750*e4b17023SJohn Marino
2751*e4b17023SJohn Marino /* Print dependences for debugging starting from FROM_BB.
2752*e4b17023SJohn Marino Callable from debugger. */
2753*e4b17023SJohn Marino /* Print dependences for debugging starting from FROM_BB.
2754*e4b17023SJohn Marino Callable from debugger. */
2755*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_rgn_dependencies(int from_bb)2756*e4b17023SJohn Marino debug_rgn_dependencies (int from_bb)
2757*e4b17023SJohn Marino {
2758*e4b17023SJohn Marino int bb;
2759*e4b17023SJohn Marino
2760*e4b17023SJohn Marino fprintf (sched_dump,
2761*e4b17023SJohn Marino ";; --------------- forward dependences: ------------ \n");
2762*e4b17023SJohn Marino
2763*e4b17023SJohn Marino for (bb = from_bb; bb < current_nr_blocks; bb++)
2764*e4b17023SJohn Marino {
2765*e4b17023SJohn Marino rtx head, tail;
2766*e4b17023SJohn Marino
2767*e4b17023SJohn Marino get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
2768*e4b17023SJohn Marino fprintf (sched_dump, "\n;; --- Region Dependences --- b %d bb %d \n",
2769*e4b17023SJohn Marino BB_TO_BLOCK (bb), bb);
2770*e4b17023SJohn Marino
2771*e4b17023SJohn Marino debug_dependencies (head, tail);
2772*e4b17023SJohn Marino }
2773*e4b17023SJohn Marino }
2774*e4b17023SJohn Marino
2775*e4b17023SJohn Marino /* Print dependencies information for instructions between HEAD and TAIL.
2776*e4b17023SJohn Marino ??? This function would probably fit best in haifa-sched.c. */
debug_dependencies(rtx head,rtx tail)2777*e4b17023SJohn Marino void debug_dependencies (rtx head, rtx tail)
2778*e4b17023SJohn Marino {
2779*e4b17023SJohn Marino rtx insn;
2780*e4b17023SJohn Marino rtx next_tail = NEXT_INSN (tail);
2781*e4b17023SJohn Marino
2782*e4b17023SJohn Marino fprintf (sched_dump, ";; %7s%6s%6s%6s%6s%6s%14s\n",
2783*e4b17023SJohn Marino "insn", "code", "bb", "dep", "prio", "cost",
2784*e4b17023SJohn Marino "reservation");
2785*e4b17023SJohn Marino fprintf (sched_dump, ";; %7s%6s%6s%6s%6s%6s%14s\n",
2786*e4b17023SJohn Marino "----", "----", "--", "---", "----", "----",
2787*e4b17023SJohn Marino "-----------");
2788*e4b17023SJohn Marino
2789*e4b17023SJohn Marino for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
2790*e4b17023SJohn Marino {
2791*e4b17023SJohn Marino if (! INSN_P (insn))
2792*e4b17023SJohn Marino {
2793*e4b17023SJohn Marino int n;
2794*e4b17023SJohn Marino fprintf (sched_dump, ";; %6d ", INSN_UID (insn));
2795*e4b17023SJohn Marino if (NOTE_P (insn))
2796*e4b17023SJohn Marino {
2797*e4b17023SJohn Marino n = NOTE_KIND (insn);
2798*e4b17023SJohn Marino fprintf (sched_dump, "%s\n", GET_NOTE_INSN_NAME (n));
2799*e4b17023SJohn Marino }
2800*e4b17023SJohn Marino else
2801*e4b17023SJohn Marino fprintf (sched_dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn)));
2802*e4b17023SJohn Marino continue;
2803*e4b17023SJohn Marino }
2804*e4b17023SJohn Marino
2805*e4b17023SJohn Marino fprintf (sched_dump,
2806*e4b17023SJohn Marino ";; %s%5d%6d%6d%6d%6d%6d ",
2807*e4b17023SJohn Marino (SCHED_GROUP_P (insn) ? "+" : " "),
2808*e4b17023SJohn Marino INSN_UID (insn),
2809*e4b17023SJohn Marino INSN_CODE (insn),
2810*e4b17023SJohn Marino BLOCK_NUM (insn),
2811*e4b17023SJohn Marino sched_emulate_haifa_p ? -1 : sd_lists_size (insn, SD_LIST_BACK),
2812*e4b17023SJohn Marino (sel_sched_p () ? (sched_emulate_haifa_p ? -1
2813*e4b17023SJohn Marino : INSN_PRIORITY (insn))
2814*e4b17023SJohn Marino : INSN_PRIORITY (insn)),
2815*e4b17023SJohn Marino (sel_sched_p () ? (sched_emulate_haifa_p ? -1
2816*e4b17023SJohn Marino : insn_cost (insn))
2817*e4b17023SJohn Marino : insn_cost (insn)));
2818*e4b17023SJohn Marino
2819*e4b17023SJohn Marino if (recog_memoized (insn) < 0)
2820*e4b17023SJohn Marino fprintf (sched_dump, "nothing");
2821*e4b17023SJohn Marino else
2822*e4b17023SJohn Marino print_reservation (sched_dump, insn);
2823*e4b17023SJohn Marino
2824*e4b17023SJohn Marino fprintf (sched_dump, "\t: ");
2825*e4b17023SJohn Marino {
2826*e4b17023SJohn Marino sd_iterator_def sd_it;
2827*e4b17023SJohn Marino dep_t dep;
2828*e4b17023SJohn Marino
2829*e4b17023SJohn Marino FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
2830*e4b17023SJohn Marino fprintf (sched_dump, "%d ", INSN_UID (DEP_CON (dep)));
2831*e4b17023SJohn Marino }
2832*e4b17023SJohn Marino fprintf (sched_dump, "\n");
2833*e4b17023SJohn Marino }
2834*e4b17023SJohn Marino
2835*e4b17023SJohn Marino fprintf (sched_dump, "\n");
2836*e4b17023SJohn Marino }
2837*e4b17023SJohn Marino
2838*e4b17023SJohn Marino /* Returns true if all the basic blocks of the current region have
2839*e4b17023SJohn Marino NOTE_DISABLE_SCHED_OF_BLOCK which means not to schedule that region. */
2840*e4b17023SJohn Marino bool
sched_is_disabled_for_current_region_p(void)2841*e4b17023SJohn Marino sched_is_disabled_for_current_region_p (void)
2842*e4b17023SJohn Marino {
2843*e4b17023SJohn Marino int bb;
2844*e4b17023SJohn Marino
2845*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
2846*e4b17023SJohn Marino if (!(BASIC_BLOCK (BB_TO_BLOCK (bb))->flags & BB_DISABLE_SCHEDULE))
2847*e4b17023SJohn Marino return false;
2848*e4b17023SJohn Marino
2849*e4b17023SJohn Marino return true;
2850*e4b17023SJohn Marino }
2851*e4b17023SJohn Marino
2852*e4b17023SJohn Marino /* Free all region dependencies saved in INSN_BACK_DEPS and
2853*e4b17023SJohn Marino INSN_RESOLVED_BACK_DEPS. The Haifa scheduler does this on the fly
2854*e4b17023SJohn Marino when scheduling, so this function is supposed to be called from
2855*e4b17023SJohn Marino the selective scheduling only. */
2856*e4b17023SJohn Marino void
free_rgn_deps(void)2857*e4b17023SJohn Marino free_rgn_deps (void)
2858*e4b17023SJohn Marino {
2859*e4b17023SJohn Marino int bb;
2860*e4b17023SJohn Marino
2861*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
2862*e4b17023SJohn Marino {
2863*e4b17023SJohn Marino rtx head, tail;
2864*e4b17023SJohn Marino
2865*e4b17023SJohn Marino gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
2866*e4b17023SJohn Marino get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
2867*e4b17023SJohn Marino
2868*e4b17023SJohn Marino sched_free_deps (head, tail, false);
2869*e4b17023SJohn Marino }
2870*e4b17023SJohn Marino }
2871*e4b17023SJohn Marino
2872*e4b17023SJohn Marino static int rgn_n_insns;
2873*e4b17023SJohn Marino
2874*e4b17023SJohn Marino /* Compute insn priority for a current region. */
2875*e4b17023SJohn Marino void
compute_priorities(void)2876*e4b17023SJohn Marino compute_priorities (void)
2877*e4b17023SJohn Marino {
2878*e4b17023SJohn Marino int bb;
2879*e4b17023SJohn Marino
2880*e4b17023SJohn Marino current_sched_info->sched_max_insns_priority = 0;
2881*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
2882*e4b17023SJohn Marino {
2883*e4b17023SJohn Marino rtx head, tail;
2884*e4b17023SJohn Marino
2885*e4b17023SJohn Marino gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
2886*e4b17023SJohn Marino get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
2887*e4b17023SJohn Marino
2888*e4b17023SJohn Marino if (no_real_insns_p (head, tail))
2889*e4b17023SJohn Marino continue;
2890*e4b17023SJohn Marino
2891*e4b17023SJohn Marino rgn_n_insns += set_priorities (head, tail);
2892*e4b17023SJohn Marino }
2893*e4b17023SJohn Marino current_sched_info->sched_max_insns_priority++;
2894*e4b17023SJohn Marino }
2895*e4b17023SJohn Marino
2896*e4b17023SJohn Marino /* Schedule a region. A region is either an inner loop, a loop-free
2897*e4b17023SJohn Marino subroutine, or a single basic block. Each bb in the region is
2898*e4b17023SJohn Marino scheduled after its flow predecessors. */
2899*e4b17023SJohn Marino
2900*e4b17023SJohn Marino static void
schedule_region(int rgn)2901*e4b17023SJohn Marino schedule_region (int rgn)
2902*e4b17023SJohn Marino {
2903*e4b17023SJohn Marino int bb;
2904*e4b17023SJohn Marino int sched_rgn_n_insns = 0;
2905*e4b17023SJohn Marino
2906*e4b17023SJohn Marino rgn_n_insns = 0;
2907*e4b17023SJohn Marino
2908*e4b17023SJohn Marino rgn_setup_region (rgn);
2909*e4b17023SJohn Marino
2910*e4b17023SJohn Marino /* Don't schedule region that is marked by
2911*e4b17023SJohn Marino NOTE_DISABLE_SCHED_OF_BLOCK. */
2912*e4b17023SJohn Marino if (sched_is_disabled_for_current_region_p ())
2913*e4b17023SJohn Marino return;
2914*e4b17023SJohn Marino
2915*e4b17023SJohn Marino sched_rgn_compute_dependencies (rgn);
2916*e4b17023SJohn Marino
2917*e4b17023SJohn Marino sched_rgn_local_init (rgn);
2918*e4b17023SJohn Marino
2919*e4b17023SJohn Marino /* Set priorities. */
2920*e4b17023SJohn Marino compute_priorities ();
2921*e4b17023SJohn Marino
2922*e4b17023SJohn Marino sched_extend_ready_list (rgn_n_insns);
2923*e4b17023SJohn Marino
2924*e4b17023SJohn Marino if (sched_pressure_p)
2925*e4b17023SJohn Marino {
2926*e4b17023SJohn Marino sched_init_region_reg_pressure_info ();
2927*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
2928*e4b17023SJohn Marino {
2929*e4b17023SJohn Marino basic_block first_bb, last_bb;
2930*e4b17023SJohn Marino rtx head, tail;
2931*e4b17023SJohn Marino
2932*e4b17023SJohn Marino first_bb = EBB_FIRST_BB (bb);
2933*e4b17023SJohn Marino last_bb = EBB_LAST_BB (bb);
2934*e4b17023SJohn Marino
2935*e4b17023SJohn Marino get_ebb_head_tail (first_bb, last_bb, &head, &tail);
2936*e4b17023SJohn Marino
2937*e4b17023SJohn Marino if (no_real_insns_p (head, tail))
2938*e4b17023SJohn Marino {
2939*e4b17023SJohn Marino gcc_assert (first_bb == last_bb);
2940*e4b17023SJohn Marino continue;
2941*e4b17023SJohn Marino }
2942*e4b17023SJohn Marino sched_setup_bb_reg_pressure_info (first_bb, PREV_INSN (head));
2943*e4b17023SJohn Marino }
2944*e4b17023SJohn Marino }
2945*e4b17023SJohn Marino
2946*e4b17023SJohn Marino /* Now we can schedule all blocks. */
2947*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
2948*e4b17023SJohn Marino {
2949*e4b17023SJohn Marino basic_block first_bb, last_bb, curr_bb;
2950*e4b17023SJohn Marino rtx head, tail;
2951*e4b17023SJohn Marino
2952*e4b17023SJohn Marino first_bb = EBB_FIRST_BB (bb);
2953*e4b17023SJohn Marino last_bb = EBB_LAST_BB (bb);
2954*e4b17023SJohn Marino
2955*e4b17023SJohn Marino get_ebb_head_tail (first_bb, last_bb, &head, &tail);
2956*e4b17023SJohn Marino
2957*e4b17023SJohn Marino if (no_real_insns_p (head, tail))
2958*e4b17023SJohn Marino {
2959*e4b17023SJohn Marino gcc_assert (first_bb == last_bb);
2960*e4b17023SJohn Marino continue;
2961*e4b17023SJohn Marino }
2962*e4b17023SJohn Marino
2963*e4b17023SJohn Marino current_sched_info->prev_head = PREV_INSN (head);
2964*e4b17023SJohn Marino current_sched_info->next_tail = NEXT_INSN (tail);
2965*e4b17023SJohn Marino
2966*e4b17023SJohn Marino remove_notes (head, tail);
2967*e4b17023SJohn Marino
2968*e4b17023SJohn Marino unlink_bb_notes (first_bb, last_bb);
2969*e4b17023SJohn Marino
2970*e4b17023SJohn Marino target_bb = bb;
2971*e4b17023SJohn Marino
2972*e4b17023SJohn Marino gcc_assert (flag_schedule_interblock || current_nr_blocks == 1);
2973*e4b17023SJohn Marino current_sched_info->queue_must_finish_empty = current_nr_blocks == 1;
2974*e4b17023SJohn Marino
2975*e4b17023SJohn Marino curr_bb = first_bb;
2976*e4b17023SJohn Marino if (dbg_cnt (sched_block))
2977*e4b17023SJohn Marino {
2978*e4b17023SJohn Marino schedule_block (&curr_bb);
2979*e4b17023SJohn Marino gcc_assert (EBB_FIRST_BB (bb) == first_bb);
2980*e4b17023SJohn Marino sched_rgn_n_insns += sched_n_insns;
2981*e4b17023SJohn Marino }
2982*e4b17023SJohn Marino else
2983*e4b17023SJohn Marino {
2984*e4b17023SJohn Marino sched_rgn_n_insns += rgn_n_insns;
2985*e4b17023SJohn Marino }
2986*e4b17023SJohn Marino
2987*e4b17023SJohn Marino /* Clean up. */
2988*e4b17023SJohn Marino if (current_nr_blocks > 1)
2989*e4b17023SJohn Marino free_trg_info ();
2990*e4b17023SJohn Marino }
2991*e4b17023SJohn Marino
2992*e4b17023SJohn Marino /* Sanity check: verify that all region insns were scheduled. */
2993*e4b17023SJohn Marino gcc_assert (sched_rgn_n_insns == rgn_n_insns);
2994*e4b17023SJohn Marino
2995*e4b17023SJohn Marino sched_finish_ready_list ();
2996*e4b17023SJohn Marino
2997*e4b17023SJohn Marino /* Done with this region. */
2998*e4b17023SJohn Marino sched_rgn_local_finish ();
2999*e4b17023SJohn Marino
3000*e4b17023SJohn Marino /* Free dependencies. */
3001*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; ++bb)
3002*e4b17023SJohn Marino free_block_dependencies (bb);
3003*e4b17023SJohn Marino
3004*e4b17023SJohn Marino gcc_assert (haifa_recovery_bb_ever_added_p
3005*e4b17023SJohn Marino || deps_pools_are_empty_p ());
3006*e4b17023SJohn Marino }
3007*e4b17023SJohn Marino
3008*e4b17023SJohn Marino /* Initialize data structures for region scheduling. */
3009*e4b17023SJohn Marino
3010*e4b17023SJohn Marino void
sched_rgn_init(bool single_blocks_p)3011*e4b17023SJohn Marino sched_rgn_init (bool single_blocks_p)
3012*e4b17023SJohn Marino {
3013*e4b17023SJohn Marino min_spec_prob = ((PARAM_VALUE (PARAM_MIN_SPEC_PROB) * REG_BR_PROB_BASE)
3014*e4b17023SJohn Marino / 100);
3015*e4b17023SJohn Marino
3016*e4b17023SJohn Marino nr_inter = 0;
3017*e4b17023SJohn Marino nr_spec = 0;
3018*e4b17023SJohn Marino
3019*e4b17023SJohn Marino extend_regions ();
3020*e4b17023SJohn Marino
3021*e4b17023SJohn Marino CONTAINING_RGN (ENTRY_BLOCK) = -1;
3022*e4b17023SJohn Marino CONTAINING_RGN (EXIT_BLOCK) = -1;
3023*e4b17023SJohn Marino
3024*e4b17023SJohn Marino /* Compute regions for scheduling. */
3025*e4b17023SJohn Marino if (single_blocks_p
3026*e4b17023SJohn Marino || n_basic_blocks == NUM_FIXED_BLOCKS + 1
3027*e4b17023SJohn Marino || !flag_schedule_interblock
3028*e4b17023SJohn Marino || is_cfg_nonregular ())
3029*e4b17023SJohn Marino {
3030*e4b17023SJohn Marino find_single_block_region (sel_sched_p ());
3031*e4b17023SJohn Marino }
3032*e4b17023SJohn Marino else
3033*e4b17023SJohn Marino {
3034*e4b17023SJohn Marino /* Compute the dominators and post dominators. */
3035*e4b17023SJohn Marino if (!sel_sched_p ())
3036*e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
3037*e4b17023SJohn Marino
3038*e4b17023SJohn Marino /* Find regions. */
3039*e4b17023SJohn Marino find_rgns ();
3040*e4b17023SJohn Marino
3041*e4b17023SJohn Marino if (sched_verbose >= 3)
3042*e4b17023SJohn Marino debug_regions ();
3043*e4b17023SJohn Marino
3044*e4b17023SJohn Marino /* For now. This will move as more and more of haifa is converted
3045*e4b17023SJohn Marino to using the cfg code. */
3046*e4b17023SJohn Marino if (!sel_sched_p ())
3047*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS);
3048*e4b17023SJohn Marino }
3049*e4b17023SJohn Marino
3050*e4b17023SJohn Marino gcc_assert (0 < nr_regions && nr_regions <= n_basic_blocks);
3051*e4b17023SJohn Marino
3052*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = (RGN_BLOCKS (nr_regions - 1) +
3053*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions - 1));
3054*e4b17023SJohn Marino }
3055*e4b17023SJohn Marino
3056*e4b17023SJohn Marino /* Free data structures for region scheduling. */
3057*e4b17023SJohn Marino void
sched_rgn_finish(void)3058*e4b17023SJohn Marino sched_rgn_finish (void)
3059*e4b17023SJohn Marino {
3060*e4b17023SJohn Marino /* Reposition the prologue and epilogue notes in case we moved the
3061*e4b17023SJohn Marino prologue/epilogue insns. */
3062*e4b17023SJohn Marino if (reload_completed)
3063*e4b17023SJohn Marino reposition_prologue_and_epilogue_notes ();
3064*e4b17023SJohn Marino
3065*e4b17023SJohn Marino if (sched_verbose)
3066*e4b17023SJohn Marino {
3067*e4b17023SJohn Marino if (reload_completed == 0
3068*e4b17023SJohn Marino && flag_schedule_interblock)
3069*e4b17023SJohn Marino {
3070*e4b17023SJohn Marino fprintf (sched_dump,
3071*e4b17023SJohn Marino "\n;; Procedure interblock/speculative motions == %d/%d \n",
3072*e4b17023SJohn Marino nr_inter, nr_spec);
3073*e4b17023SJohn Marino }
3074*e4b17023SJohn Marino else
3075*e4b17023SJohn Marino gcc_assert (nr_inter <= 0);
3076*e4b17023SJohn Marino fprintf (sched_dump, "\n\n");
3077*e4b17023SJohn Marino }
3078*e4b17023SJohn Marino
3079*e4b17023SJohn Marino nr_regions = 0;
3080*e4b17023SJohn Marino
3081*e4b17023SJohn Marino free (rgn_table);
3082*e4b17023SJohn Marino rgn_table = NULL;
3083*e4b17023SJohn Marino
3084*e4b17023SJohn Marino free (rgn_bb_table);
3085*e4b17023SJohn Marino rgn_bb_table = NULL;
3086*e4b17023SJohn Marino
3087*e4b17023SJohn Marino free (block_to_bb);
3088*e4b17023SJohn Marino block_to_bb = NULL;
3089*e4b17023SJohn Marino
3090*e4b17023SJohn Marino free (containing_rgn);
3091*e4b17023SJohn Marino containing_rgn = NULL;
3092*e4b17023SJohn Marino
3093*e4b17023SJohn Marino free (ebb_head);
3094*e4b17023SJohn Marino ebb_head = NULL;
3095*e4b17023SJohn Marino }
3096*e4b17023SJohn Marino
3097*e4b17023SJohn Marino /* Setup global variables like CURRENT_BLOCKS and CURRENT_NR_BLOCK to
3098*e4b17023SJohn Marino point to the region RGN. */
3099*e4b17023SJohn Marino void
rgn_setup_region(int rgn)3100*e4b17023SJohn Marino rgn_setup_region (int rgn)
3101*e4b17023SJohn Marino {
3102*e4b17023SJohn Marino int bb;
3103*e4b17023SJohn Marino
3104*e4b17023SJohn Marino /* Set variables for the current region. */
3105*e4b17023SJohn Marino current_nr_blocks = RGN_NR_BLOCKS (rgn);
3106*e4b17023SJohn Marino current_blocks = RGN_BLOCKS (rgn);
3107*e4b17023SJohn Marino
3108*e4b17023SJohn Marino /* EBB_HEAD is a region-scope structure. But we realloc it for
3109*e4b17023SJohn Marino each region to save time/memory/something else.
3110*e4b17023SJohn Marino See comments in add_block1, for what reasons we allocate +1 element. */
3111*e4b17023SJohn Marino ebb_head = XRESIZEVEC (int, ebb_head, current_nr_blocks + 1);
3112*e4b17023SJohn Marino for (bb = 0; bb <= current_nr_blocks; bb++)
3113*e4b17023SJohn Marino ebb_head[bb] = current_blocks + bb;
3114*e4b17023SJohn Marino }
3115*e4b17023SJohn Marino
3116*e4b17023SJohn Marino /* Compute instruction dependencies in region RGN. */
3117*e4b17023SJohn Marino void
sched_rgn_compute_dependencies(int rgn)3118*e4b17023SJohn Marino sched_rgn_compute_dependencies (int rgn)
3119*e4b17023SJohn Marino {
3120*e4b17023SJohn Marino if (!RGN_DONT_CALC_DEPS (rgn))
3121*e4b17023SJohn Marino {
3122*e4b17023SJohn Marino int bb;
3123*e4b17023SJohn Marino
3124*e4b17023SJohn Marino if (sel_sched_p ())
3125*e4b17023SJohn Marino sched_emulate_haifa_p = 1;
3126*e4b17023SJohn Marino
3127*e4b17023SJohn Marino init_deps_global ();
3128*e4b17023SJohn Marino
3129*e4b17023SJohn Marino /* Initializations for region data dependence analysis. */
3130*e4b17023SJohn Marino bb_deps = XNEWVEC (struct deps_desc, current_nr_blocks);
3131*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
3132*e4b17023SJohn Marino init_deps (bb_deps + bb, false);
3133*e4b17023SJohn Marino
3134*e4b17023SJohn Marino /* Initialize bitmap used in add_branch_dependences. */
3135*e4b17023SJohn Marino insn_referenced = sbitmap_alloc (sched_max_luid);
3136*e4b17023SJohn Marino sbitmap_zero (insn_referenced);
3137*e4b17023SJohn Marino
3138*e4b17023SJohn Marino /* Compute backward dependencies. */
3139*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
3140*e4b17023SJohn Marino compute_block_dependences (bb);
3141*e4b17023SJohn Marino
3142*e4b17023SJohn Marino sbitmap_free (insn_referenced);
3143*e4b17023SJohn Marino free_pending_lists ();
3144*e4b17023SJohn Marino finish_deps_global ();
3145*e4b17023SJohn Marino free (bb_deps);
3146*e4b17023SJohn Marino
3147*e4b17023SJohn Marino /* We don't want to recalculate this twice. */
3148*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (rgn) = 1;
3149*e4b17023SJohn Marino
3150*e4b17023SJohn Marino if (sel_sched_p ())
3151*e4b17023SJohn Marino sched_emulate_haifa_p = 0;
3152*e4b17023SJohn Marino }
3153*e4b17023SJohn Marino else
3154*e4b17023SJohn Marino /* (This is a recovery block. It is always a single block region.)
3155*e4b17023SJohn Marino OR (We use selective scheduling.) */
3156*e4b17023SJohn Marino gcc_assert (current_nr_blocks == 1 || sel_sched_p ());
3157*e4b17023SJohn Marino }
3158*e4b17023SJohn Marino
3159*e4b17023SJohn Marino /* Init region data structures. Returns true if this region should
3160*e4b17023SJohn Marino not be scheduled. */
3161*e4b17023SJohn Marino void
sched_rgn_local_init(int rgn)3162*e4b17023SJohn Marino sched_rgn_local_init (int rgn)
3163*e4b17023SJohn Marino {
3164*e4b17023SJohn Marino int bb;
3165*e4b17023SJohn Marino
3166*e4b17023SJohn Marino /* Compute interblock info: probabilities, split-edges, dominators, etc. */
3167*e4b17023SJohn Marino if (current_nr_blocks > 1)
3168*e4b17023SJohn Marino {
3169*e4b17023SJohn Marino basic_block block;
3170*e4b17023SJohn Marino edge e;
3171*e4b17023SJohn Marino edge_iterator ei;
3172*e4b17023SJohn Marino
3173*e4b17023SJohn Marino prob = XNEWVEC (int, current_nr_blocks);
3174*e4b17023SJohn Marino
3175*e4b17023SJohn Marino dom = sbitmap_vector_alloc (current_nr_blocks, current_nr_blocks);
3176*e4b17023SJohn Marino sbitmap_vector_zero (dom, current_nr_blocks);
3177*e4b17023SJohn Marino
3178*e4b17023SJohn Marino /* Use ->aux to implement EDGE_TO_BIT mapping. */
3179*e4b17023SJohn Marino rgn_nr_edges = 0;
3180*e4b17023SJohn Marino FOR_EACH_BB (block)
3181*e4b17023SJohn Marino {
3182*e4b17023SJohn Marino if (CONTAINING_RGN (block->index) != rgn)
3183*e4b17023SJohn Marino continue;
3184*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, block->succs)
3185*e4b17023SJohn Marino SET_EDGE_TO_BIT (e, rgn_nr_edges++);
3186*e4b17023SJohn Marino }
3187*e4b17023SJohn Marino
3188*e4b17023SJohn Marino rgn_edges = XNEWVEC (edge, rgn_nr_edges);
3189*e4b17023SJohn Marino rgn_nr_edges = 0;
3190*e4b17023SJohn Marino FOR_EACH_BB (block)
3191*e4b17023SJohn Marino {
3192*e4b17023SJohn Marino if (CONTAINING_RGN (block->index) != rgn)
3193*e4b17023SJohn Marino continue;
3194*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, block->succs)
3195*e4b17023SJohn Marino rgn_edges[rgn_nr_edges++] = e;
3196*e4b17023SJohn Marino }
3197*e4b17023SJohn Marino
3198*e4b17023SJohn Marino /* Split edges. */
3199*e4b17023SJohn Marino pot_split = sbitmap_vector_alloc (current_nr_blocks, rgn_nr_edges);
3200*e4b17023SJohn Marino sbitmap_vector_zero (pot_split, current_nr_blocks);
3201*e4b17023SJohn Marino ancestor_edges = sbitmap_vector_alloc (current_nr_blocks, rgn_nr_edges);
3202*e4b17023SJohn Marino sbitmap_vector_zero (ancestor_edges, current_nr_blocks);
3203*e4b17023SJohn Marino
3204*e4b17023SJohn Marino /* Compute probabilities, dominators, split_edges. */
3205*e4b17023SJohn Marino for (bb = 0; bb < current_nr_blocks; bb++)
3206*e4b17023SJohn Marino compute_dom_prob_ps (bb);
3207*e4b17023SJohn Marino
3208*e4b17023SJohn Marino /* Cleanup ->aux used for EDGE_TO_BIT mapping. */
3209*e4b17023SJohn Marino /* We don't need them anymore. But we want to avoid duplication of
3210*e4b17023SJohn Marino aux fields in the newly created edges. */
3211*e4b17023SJohn Marino FOR_EACH_BB (block)
3212*e4b17023SJohn Marino {
3213*e4b17023SJohn Marino if (CONTAINING_RGN (block->index) != rgn)
3214*e4b17023SJohn Marino continue;
3215*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, block->succs)
3216*e4b17023SJohn Marino e->aux = NULL;
3217*e4b17023SJohn Marino }
3218*e4b17023SJohn Marino }
3219*e4b17023SJohn Marino }
3220*e4b17023SJohn Marino
3221*e4b17023SJohn Marino /* Free data computed for the finished region. */
3222*e4b17023SJohn Marino void
sched_rgn_local_free(void)3223*e4b17023SJohn Marino sched_rgn_local_free (void)
3224*e4b17023SJohn Marino {
3225*e4b17023SJohn Marino free (prob);
3226*e4b17023SJohn Marino sbitmap_vector_free (dom);
3227*e4b17023SJohn Marino sbitmap_vector_free (pot_split);
3228*e4b17023SJohn Marino sbitmap_vector_free (ancestor_edges);
3229*e4b17023SJohn Marino free (rgn_edges);
3230*e4b17023SJohn Marino }
3231*e4b17023SJohn Marino
3232*e4b17023SJohn Marino /* Free data computed for the finished region. */
3233*e4b17023SJohn Marino void
sched_rgn_local_finish(void)3234*e4b17023SJohn Marino sched_rgn_local_finish (void)
3235*e4b17023SJohn Marino {
3236*e4b17023SJohn Marino if (current_nr_blocks > 1 && !sel_sched_p ())
3237*e4b17023SJohn Marino {
3238*e4b17023SJohn Marino sched_rgn_local_free ();
3239*e4b17023SJohn Marino }
3240*e4b17023SJohn Marino }
3241*e4b17023SJohn Marino
3242*e4b17023SJohn Marino /* Setup scheduler infos. */
3243*e4b17023SJohn Marino void
rgn_setup_common_sched_info(void)3244*e4b17023SJohn Marino rgn_setup_common_sched_info (void)
3245*e4b17023SJohn Marino {
3246*e4b17023SJohn Marino memcpy (&rgn_common_sched_info, &haifa_common_sched_info,
3247*e4b17023SJohn Marino sizeof (rgn_common_sched_info));
3248*e4b17023SJohn Marino
3249*e4b17023SJohn Marino rgn_common_sched_info.fix_recovery_cfg = rgn_fix_recovery_cfg;
3250*e4b17023SJohn Marino rgn_common_sched_info.add_block = rgn_add_block;
3251*e4b17023SJohn Marino rgn_common_sched_info.estimate_number_of_insns
3252*e4b17023SJohn Marino = rgn_estimate_number_of_insns;
3253*e4b17023SJohn Marino rgn_common_sched_info.sched_pass_id = SCHED_RGN_PASS;
3254*e4b17023SJohn Marino
3255*e4b17023SJohn Marino common_sched_info = &rgn_common_sched_info;
3256*e4b17023SJohn Marino }
3257*e4b17023SJohn Marino
3258*e4b17023SJohn Marino /* Setup all *_sched_info structures (for the Haifa frontend
3259*e4b17023SJohn Marino and for the dependence analysis) in the interblock scheduler. */
3260*e4b17023SJohn Marino void
rgn_setup_sched_infos(void)3261*e4b17023SJohn Marino rgn_setup_sched_infos (void)
3262*e4b17023SJohn Marino {
3263*e4b17023SJohn Marino if (!sel_sched_p ())
3264*e4b17023SJohn Marino memcpy (&rgn_sched_deps_info, &rgn_const_sched_deps_info,
3265*e4b17023SJohn Marino sizeof (rgn_sched_deps_info));
3266*e4b17023SJohn Marino else
3267*e4b17023SJohn Marino memcpy (&rgn_sched_deps_info, &rgn_const_sel_sched_deps_info,
3268*e4b17023SJohn Marino sizeof (rgn_sched_deps_info));
3269*e4b17023SJohn Marino
3270*e4b17023SJohn Marino sched_deps_info = &rgn_sched_deps_info;
3271*e4b17023SJohn Marino
3272*e4b17023SJohn Marino memcpy (&rgn_sched_info, &rgn_const_sched_info, sizeof (rgn_sched_info));
3273*e4b17023SJohn Marino current_sched_info = &rgn_sched_info;
3274*e4b17023SJohn Marino }
3275*e4b17023SJohn Marino
3276*e4b17023SJohn Marino /* The one entry point in this file. */
3277*e4b17023SJohn Marino void
schedule_insns(void)3278*e4b17023SJohn Marino schedule_insns (void)
3279*e4b17023SJohn Marino {
3280*e4b17023SJohn Marino int rgn;
3281*e4b17023SJohn Marino
3282*e4b17023SJohn Marino /* Taking care of this degenerate case makes the rest of
3283*e4b17023SJohn Marino this code simpler. */
3284*e4b17023SJohn Marino if (n_basic_blocks == NUM_FIXED_BLOCKS)
3285*e4b17023SJohn Marino return;
3286*e4b17023SJohn Marino
3287*e4b17023SJohn Marino rgn_setup_common_sched_info ();
3288*e4b17023SJohn Marino rgn_setup_sched_infos ();
3289*e4b17023SJohn Marino
3290*e4b17023SJohn Marino haifa_sched_init ();
3291*e4b17023SJohn Marino sched_rgn_init (reload_completed);
3292*e4b17023SJohn Marino
3293*e4b17023SJohn Marino bitmap_initialize (¬_in_df, 0);
3294*e4b17023SJohn Marino bitmap_clear (¬_in_df);
3295*e4b17023SJohn Marino
3296*e4b17023SJohn Marino /* Schedule every region in the subroutine. */
3297*e4b17023SJohn Marino for (rgn = 0; rgn < nr_regions; rgn++)
3298*e4b17023SJohn Marino if (dbg_cnt (sched_region))
3299*e4b17023SJohn Marino schedule_region (rgn);
3300*e4b17023SJohn Marino
3301*e4b17023SJohn Marino /* Clean up. */
3302*e4b17023SJohn Marino sched_rgn_finish ();
3303*e4b17023SJohn Marino bitmap_clear (¬_in_df);
3304*e4b17023SJohn Marino
3305*e4b17023SJohn Marino haifa_sched_finish ();
3306*e4b17023SJohn Marino }
3307*e4b17023SJohn Marino
3308*e4b17023SJohn Marino /* INSN has been added to/removed from current region. */
3309*e4b17023SJohn Marino static void
rgn_add_remove_insn(rtx insn,int remove_p)3310*e4b17023SJohn Marino rgn_add_remove_insn (rtx insn, int remove_p)
3311*e4b17023SJohn Marino {
3312*e4b17023SJohn Marino if (!remove_p)
3313*e4b17023SJohn Marino rgn_n_insns++;
3314*e4b17023SJohn Marino else
3315*e4b17023SJohn Marino rgn_n_insns--;
3316*e4b17023SJohn Marino
3317*e4b17023SJohn Marino if (INSN_BB (insn) == target_bb)
3318*e4b17023SJohn Marino {
3319*e4b17023SJohn Marino if (!remove_p)
3320*e4b17023SJohn Marino target_n_insns++;
3321*e4b17023SJohn Marino else
3322*e4b17023SJohn Marino target_n_insns--;
3323*e4b17023SJohn Marino }
3324*e4b17023SJohn Marino }
3325*e4b17023SJohn Marino
3326*e4b17023SJohn Marino /* Extend internal data structures. */
3327*e4b17023SJohn Marino void
extend_regions(void)3328*e4b17023SJohn Marino extend_regions (void)
3329*e4b17023SJohn Marino {
3330*e4b17023SJohn Marino rgn_table = XRESIZEVEC (region, rgn_table, n_basic_blocks);
3331*e4b17023SJohn Marino rgn_bb_table = XRESIZEVEC (int, rgn_bb_table, n_basic_blocks);
3332*e4b17023SJohn Marino block_to_bb = XRESIZEVEC (int, block_to_bb, last_basic_block);
3333*e4b17023SJohn Marino containing_rgn = XRESIZEVEC (int, containing_rgn, last_basic_block);
3334*e4b17023SJohn Marino }
3335*e4b17023SJohn Marino
3336*e4b17023SJohn Marino void
rgn_make_new_region_out_of_new_block(basic_block bb)3337*e4b17023SJohn Marino rgn_make_new_region_out_of_new_block (basic_block bb)
3338*e4b17023SJohn Marino {
3339*e4b17023SJohn Marino int i;
3340*e4b17023SJohn Marino
3341*e4b17023SJohn Marino i = RGN_BLOCKS (nr_regions);
3342*e4b17023SJohn Marino /* I - first free position in rgn_bb_table. */
3343*e4b17023SJohn Marino
3344*e4b17023SJohn Marino rgn_bb_table[i] = bb->index;
3345*e4b17023SJohn Marino RGN_NR_BLOCKS (nr_regions) = 1;
3346*e4b17023SJohn Marino RGN_HAS_REAL_EBB (nr_regions) = 0;
3347*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions) = 0;
3348*e4b17023SJohn Marino CONTAINING_RGN (bb->index) = nr_regions;
3349*e4b17023SJohn Marino BLOCK_TO_BB (bb->index) = 0;
3350*e4b17023SJohn Marino
3351*e4b17023SJohn Marino nr_regions++;
3352*e4b17023SJohn Marino
3353*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) = i + 1;
3354*e4b17023SJohn Marino }
3355*e4b17023SJohn Marino
3356*e4b17023SJohn Marino /* BB was added to ebb after AFTER. */
3357*e4b17023SJohn Marino static void
rgn_add_block(basic_block bb,basic_block after)3358*e4b17023SJohn Marino rgn_add_block (basic_block bb, basic_block after)
3359*e4b17023SJohn Marino {
3360*e4b17023SJohn Marino extend_regions ();
3361*e4b17023SJohn Marino bitmap_set_bit (¬_in_df, bb->index);
3362*e4b17023SJohn Marino
3363*e4b17023SJohn Marino if (after == 0 || after == EXIT_BLOCK_PTR)
3364*e4b17023SJohn Marino {
3365*e4b17023SJohn Marino rgn_make_new_region_out_of_new_block (bb);
3366*e4b17023SJohn Marino RGN_DONT_CALC_DEPS (nr_regions - 1) = (after == EXIT_BLOCK_PTR);
3367*e4b17023SJohn Marino }
3368*e4b17023SJohn Marino else
3369*e4b17023SJohn Marino {
3370*e4b17023SJohn Marino int i, pos;
3371*e4b17023SJohn Marino
3372*e4b17023SJohn Marino /* We need to fix rgn_table, block_to_bb, containing_rgn
3373*e4b17023SJohn Marino and ebb_head. */
3374*e4b17023SJohn Marino
3375*e4b17023SJohn Marino BLOCK_TO_BB (bb->index) = BLOCK_TO_BB (after->index);
3376*e4b17023SJohn Marino
3377*e4b17023SJohn Marino /* We extend ebb_head to one more position to
3378*e4b17023SJohn Marino easily find the last position of the last ebb in
3379*e4b17023SJohn Marino the current region. Thus, ebb_head[BLOCK_TO_BB (after) + 1]
3380*e4b17023SJohn Marino is _always_ valid for access. */
3381*e4b17023SJohn Marino
3382*e4b17023SJohn Marino i = BLOCK_TO_BB (after->index) + 1;
3383*e4b17023SJohn Marino pos = ebb_head[i] - 1;
3384*e4b17023SJohn Marino /* Now POS is the index of the last block in the region. */
3385*e4b17023SJohn Marino
3386*e4b17023SJohn Marino /* Find index of basic block AFTER. */
3387*e4b17023SJohn Marino for (; rgn_bb_table[pos] != after->index; pos--)
3388*e4b17023SJohn Marino ;
3389*e4b17023SJohn Marino
3390*e4b17023SJohn Marino pos++;
3391*e4b17023SJohn Marino gcc_assert (pos > ebb_head[i - 1]);
3392*e4b17023SJohn Marino
3393*e4b17023SJohn Marino /* i - ebb right after "AFTER". */
3394*e4b17023SJohn Marino /* ebb_head[i] - VALID. */
3395*e4b17023SJohn Marino
3396*e4b17023SJohn Marino /* Source position: ebb_head[i]
3397*e4b17023SJohn Marino Destination position: ebb_head[i] + 1
3398*e4b17023SJohn Marino Last position:
3399*e4b17023SJohn Marino RGN_BLOCKS (nr_regions) - 1
3400*e4b17023SJohn Marino Number of elements to copy: (last_position) - (source_position) + 1
3401*e4b17023SJohn Marino */
3402*e4b17023SJohn Marino
3403*e4b17023SJohn Marino memmove (rgn_bb_table + pos + 1,
3404*e4b17023SJohn Marino rgn_bb_table + pos,
3405*e4b17023SJohn Marino ((RGN_BLOCKS (nr_regions) - 1) - (pos) + 1)
3406*e4b17023SJohn Marino * sizeof (*rgn_bb_table));
3407*e4b17023SJohn Marino
3408*e4b17023SJohn Marino rgn_bb_table[pos] = bb->index;
3409*e4b17023SJohn Marino
3410*e4b17023SJohn Marino for (; i <= current_nr_blocks; i++)
3411*e4b17023SJohn Marino ebb_head [i]++;
3412*e4b17023SJohn Marino
3413*e4b17023SJohn Marino i = CONTAINING_RGN (after->index);
3414*e4b17023SJohn Marino CONTAINING_RGN (bb->index) = i;
3415*e4b17023SJohn Marino
3416*e4b17023SJohn Marino RGN_HAS_REAL_EBB (i) = 1;
3417*e4b17023SJohn Marino
3418*e4b17023SJohn Marino for (++i; i <= nr_regions; i++)
3419*e4b17023SJohn Marino RGN_BLOCKS (i)++;
3420*e4b17023SJohn Marino }
3421*e4b17023SJohn Marino }
3422*e4b17023SJohn Marino
3423*e4b17023SJohn Marino /* Fix internal data after interblock movement of jump instruction.
3424*e4b17023SJohn Marino For parameter meaning please refer to
3425*e4b17023SJohn Marino sched-int.h: struct sched_info: fix_recovery_cfg. */
3426*e4b17023SJohn Marino static void
rgn_fix_recovery_cfg(int bbi,int check_bbi,int check_bb_nexti)3427*e4b17023SJohn Marino rgn_fix_recovery_cfg (int bbi, int check_bbi, int check_bb_nexti)
3428*e4b17023SJohn Marino {
3429*e4b17023SJohn Marino int old_pos, new_pos, i;
3430*e4b17023SJohn Marino
3431*e4b17023SJohn Marino BLOCK_TO_BB (check_bb_nexti) = BLOCK_TO_BB (bbi);
3432*e4b17023SJohn Marino
3433*e4b17023SJohn Marino for (old_pos = ebb_head[BLOCK_TO_BB (check_bbi) + 1] - 1;
3434*e4b17023SJohn Marino rgn_bb_table[old_pos] != check_bb_nexti;
3435*e4b17023SJohn Marino old_pos--)
3436*e4b17023SJohn Marino ;
3437*e4b17023SJohn Marino gcc_assert (old_pos > ebb_head[BLOCK_TO_BB (check_bbi)]);
3438*e4b17023SJohn Marino
3439*e4b17023SJohn Marino for (new_pos = ebb_head[BLOCK_TO_BB (bbi) + 1] - 1;
3440*e4b17023SJohn Marino rgn_bb_table[new_pos] != bbi;
3441*e4b17023SJohn Marino new_pos--)
3442*e4b17023SJohn Marino ;
3443*e4b17023SJohn Marino new_pos++;
3444*e4b17023SJohn Marino gcc_assert (new_pos > ebb_head[BLOCK_TO_BB (bbi)]);
3445*e4b17023SJohn Marino
3446*e4b17023SJohn Marino gcc_assert (new_pos < old_pos);
3447*e4b17023SJohn Marino
3448*e4b17023SJohn Marino memmove (rgn_bb_table + new_pos + 1,
3449*e4b17023SJohn Marino rgn_bb_table + new_pos,
3450*e4b17023SJohn Marino (old_pos - new_pos) * sizeof (*rgn_bb_table));
3451*e4b17023SJohn Marino
3452*e4b17023SJohn Marino rgn_bb_table[new_pos] = check_bb_nexti;
3453*e4b17023SJohn Marino
3454*e4b17023SJohn Marino for (i = BLOCK_TO_BB (bbi) + 1; i <= BLOCK_TO_BB (check_bbi); i++)
3455*e4b17023SJohn Marino ebb_head[i]++;
3456*e4b17023SJohn Marino }
3457*e4b17023SJohn Marino
3458*e4b17023SJohn Marino /* Return next block in ebb chain. For parameter meaning please refer to
3459*e4b17023SJohn Marino sched-int.h: struct sched_info: advance_target_bb. */
3460*e4b17023SJohn Marino static basic_block
advance_target_bb(basic_block bb,rtx insn)3461*e4b17023SJohn Marino advance_target_bb (basic_block bb, rtx insn)
3462*e4b17023SJohn Marino {
3463*e4b17023SJohn Marino if (insn)
3464*e4b17023SJohn Marino return 0;
3465*e4b17023SJohn Marino
3466*e4b17023SJohn Marino gcc_assert (BLOCK_TO_BB (bb->index) == target_bb
3467*e4b17023SJohn Marino && BLOCK_TO_BB (bb->next_bb->index) == target_bb);
3468*e4b17023SJohn Marino return bb->next_bb;
3469*e4b17023SJohn Marino }
3470*e4b17023SJohn Marino
3471*e4b17023SJohn Marino #endif
3472*e4b17023SJohn Marino
3473*e4b17023SJohn Marino static bool
gate_handle_sched(void)3474*e4b17023SJohn Marino gate_handle_sched (void)
3475*e4b17023SJohn Marino {
3476*e4b17023SJohn Marino #ifdef INSN_SCHEDULING
3477*e4b17023SJohn Marino return flag_schedule_insns && dbg_cnt (sched_func);
3478*e4b17023SJohn Marino #else
3479*e4b17023SJohn Marino return 0;
3480*e4b17023SJohn Marino #endif
3481*e4b17023SJohn Marino }
3482*e4b17023SJohn Marino
3483*e4b17023SJohn Marino /* Run instruction scheduler. */
3484*e4b17023SJohn Marino static unsigned int
rest_of_handle_sched(void)3485*e4b17023SJohn Marino rest_of_handle_sched (void)
3486*e4b17023SJohn Marino {
3487*e4b17023SJohn Marino #ifdef INSN_SCHEDULING
3488*e4b17023SJohn Marino if (flag_selective_scheduling
3489*e4b17023SJohn Marino && ! maybe_skip_selective_scheduling ())
3490*e4b17023SJohn Marino run_selective_scheduling ();
3491*e4b17023SJohn Marino else
3492*e4b17023SJohn Marino schedule_insns ();
3493*e4b17023SJohn Marino #endif
3494*e4b17023SJohn Marino return 0;
3495*e4b17023SJohn Marino }
3496*e4b17023SJohn Marino
3497*e4b17023SJohn Marino static bool
gate_handle_sched2(void)3498*e4b17023SJohn Marino gate_handle_sched2 (void)
3499*e4b17023SJohn Marino {
3500*e4b17023SJohn Marino #ifdef INSN_SCHEDULING
3501*e4b17023SJohn Marino return optimize > 0 && flag_schedule_insns_after_reload
3502*e4b17023SJohn Marino && !targetm.delay_sched2 && dbg_cnt (sched2_func);
3503*e4b17023SJohn Marino #else
3504*e4b17023SJohn Marino return 0;
3505*e4b17023SJohn Marino #endif
3506*e4b17023SJohn Marino }
3507*e4b17023SJohn Marino
3508*e4b17023SJohn Marino /* Run second scheduling pass after reload. */
3509*e4b17023SJohn Marino static unsigned int
rest_of_handle_sched2(void)3510*e4b17023SJohn Marino rest_of_handle_sched2 (void)
3511*e4b17023SJohn Marino {
3512*e4b17023SJohn Marino #ifdef INSN_SCHEDULING
3513*e4b17023SJohn Marino if (flag_selective_scheduling2
3514*e4b17023SJohn Marino && ! maybe_skip_selective_scheduling ())
3515*e4b17023SJohn Marino run_selective_scheduling ();
3516*e4b17023SJohn Marino else
3517*e4b17023SJohn Marino {
3518*e4b17023SJohn Marino /* Do control and data sched analysis again,
3519*e4b17023SJohn Marino and write some more of the results to dump file. */
3520*e4b17023SJohn Marino if (flag_sched2_use_superblocks)
3521*e4b17023SJohn Marino schedule_ebbs ();
3522*e4b17023SJohn Marino else
3523*e4b17023SJohn Marino schedule_insns ();
3524*e4b17023SJohn Marino }
3525*e4b17023SJohn Marino #endif
3526*e4b17023SJohn Marino return 0;
3527*e4b17023SJohn Marino }
3528*e4b17023SJohn Marino
3529*e4b17023SJohn Marino struct rtl_opt_pass pass_sched =
3530*e4b17023SJohn Marino {
3531*e4b17023SJohn Marino {
3532*e4b17023SJohn Marino RTL_PASS,
3533*e4b17023SJohn Marino "sched1", /* name */
3534*e4b17023SJohn Marino gate_handle_sched, /* gate */
3535*e4b17023SJohn Marino rest_of_handle_sched, /* execute */
3536*e4b17023SJohn Marino NULL, /* sub */
3537*e4b17023SJohn Marino NULL, /* next */
3538*e4b17023SJohn Marino 0, /* static_pass_number */
3539*e4b17023SJohn Marino TV_SCHED, /* tv_id */
3540*e4b17023SJohn Marino 0, /* properties_required */
3541*e4b17023SJohn Marino 0, /* properties_provided */
3542*e4b17023SJohn Marino 0, /* properties_destroyed */
3543*e4b17023SJohn Marino 0, /* todo_flags_start */
3544*e4b17023SJohn Marino TODO_df_finish | TODO_verify_rtl_sharing |
3545*e4b17023SJohn Marino TODO_verify_flow |
3546*e4b17023SJohn Marino TODO_ggc_collect /* todo_flags_finish */
3547*e4b17023SJohn Marino }
3548*e4b17023SJohn Marino };
3549*e4b17023SJohn Marino
3550*e4b17023SJohn Marino struct rtl_opt_pass pass_sched2 =
3551*e4b17023SJohn Marino {
3552*e4b17023SJohn Marino {
3553*e4b17023SJohn Marino RTL_PASS,
3554*e4b17023SJohn Marino "sched2", /* name */
3555*e4b17023SJohn Marino gate_handle_sched2, /* gate */
3556*e4b17023SJohn Marino rest_of_handle_sched2, /* execute */
3557*e4b17023SJohn Marino NULL, /* sub */
3558*e4b17023SJohn Marino NULL, /* next */
3559*e4b17023SJohn Marino 0, /* static_pass_number */
3560*e4b17023SJohn Marino TV_SCHED2, /* tv_id */
3561*e4b17023SJohn Marino 0, /* properties_required */
3562*e4b17023SJohn Marino 0, /* properties_provided */
3563*e4b17023SJohn Marino 0, /* properties_destroyed */
3564*e4b17023SJohn Marino 0, /* todo_flags_start */
3565*e4b17023SJohn Marino TODO_df_finish | TODO_verify_rtl_sharing |
3566*e4b17023SJohn Marino TODO_verify_flow |
3567*e4b17023SJohn Marino TODO_ggc_collect /* todo_flags_finish */
3568*e4b17023SJohn Marino }
3569*e4b17023SJohn Marino };
3570