1*38fd1498Szrj /* Control flow graph manipulation code for GNU compiler.
2*38fd1498Szrj Copyright (C) 1987-2018 Free Software Foundation, Inc.
3*38fd1498Szrj
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*38fd1498Szrj for more details.
15*38fd1498Szrj
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3. If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>. */
19*38fd1498Szrj
20*38fd1498Szrj /* This file contains low level functions to manipulate the CFG and
21*38fd1498Szrj analyze it. All other modules should not transform the data structure
22*38fd1498Szrj directly and use abstraction instead. The file is supposed to be
23*38fd1498Szrj ordered bottom-up and should not contain any code dependent on a
24*38fd1498Szrj particular intermediate language (RTL or trees).
25*38fd1498Szrj
26*38fd1498Szrj Available functionality:
27*38fd1498Szrj - Initialization/deallocation
28*38fd1498Szrj init_flow, clear_edges
29*38fd1498Szrj - Low level basic block manipulation
30*38fd1498Szrj alloc_block, expunge_block
31*38fd1498Szrj - Edge manipulation
32*38fd1498Szrj make_edge, make_single_succ_edge, cached_make_edge, remove_edge
33*38fd1498Szrj - Low level edge redirection (without updating instruction chain)
34*38fd1498Szrj redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
35*38fd1498Szrj - Dumping and debugging
36*38fd1498Szrj dump_flow_info, debug_flow_info, dump_edge_info
37*38fd1498Szrj - Allocation of AUX fields for basic blocks
38*38fd1498Szrj alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
39*38fd1498Szrj - clear_bb_flags
40*38fd1498Szrj - Consistency checking
41*38fd1498Szrj verify_flow_info
42*38fd1498Szrj - Dumping and debugging
43*38fd1498Szrj print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
44*38fd1498Szrj
45*38fd1498Szrj TODO: Document these "Available functionality" functions in the files
46*38fd1498Szrj that implement them.
47*38fd1498Szrj */
48*38fd1498Szrj
49*38fd1498Szrj #include "config.h"
50*38fd1498Szrj #include "system.h"
51*38fd1498Szrj #include "coretypes.h"
52*38fd1498Szrj #include "backend.h"
53*38fd1498Szrj #include "hard-reg-set.h"
54*38fd1498Szrj #include "tree.h"
55*38fd1498Szrj #include "cfghooks.h"
56*38fd1498Szrj #include "df.h"
57*38fd1498Szrj #include "cfganal.h"
58*38fd1498Szrj #include "cfgloop.h" /* FIXME: For struct loop. */
59*38fd1498Szrj #include "dumpfile.h"
60*38fd1498Szrj
61*38fd1498Szrj
62*38fd1498Szrj
63*38fd1498Szrj /* Called once at initialization time. */
64*38fd1498Szrj
65*38fd1498Szrj void
init_flow(struct function * the_fun)66*38fd1498Szrj init_flow (struct function *the_fun)
67*38fd1498Szrj {
68*38fd1498Szrj if (!the_fun->cfg)
69*38fd1498Szrj the_fun->cfg = ggc_cleared_alloc<control_flow_graph> ();
70*38fd1498Szrj n_edges_for_fn (the_fun) = 0;
71*38fd1498Szrj the_fun->cfg->count_max = profile_count::uninitialized ();
72*38fd1498Szrj ENTRY_BLOCK_PTR_FOR_FN (the_fun)
73*38fd1498Szrj = alloc_block ();
74*38fd1498Szrj ENTRY_BLOCK_PTR_FOR_FN (the_fun)->index = ENTRY_BLOCK;
75*38fd1498Szrj EXIT_BLOCK_PTR_FOR_FN (the_fun)
76*38fd1498Szrj = alloc_block ();
77*38fd1498Szrj EXIT_BLOCK_PTR_FOR_FN (the_fun)->index = EXIT_BLOCK;
78*38fd1498Szrj ENTRY_BLOCK_PTR_FOR_FN (the_fun)->next_bb
79*38fd1498Szrj = EXIT_BLOCK_PTR_FOR_FN (the_fun);
80*38fd1498Szrj EXIT_BLOCK_PTR_FOR_FN (the_fun)->prev_bb
81*38fd1498Szrj = ENTRY_BLOCK_PTR_FOR_FN (the_fun);
82*38fd1498Szrj }
83*38fd1498Szrj
84*38fd1498Szrj /* Helper function for remove_edge and clear_edges. Frees edge structure
85*38fd1498Szrj without actually removing it from the pred/succ arrays. */
86*38fd1498Szrj
87*38fd1498Szrj static void
free_edge(function * fn,edge e)88*38fd1498Szrj free_edge (function *fn, edge e)
89*38fd1498Szrj {
90*38fd1498Szrj n_edges_for_fn (fn)--;
91*38fd1498Szrj ggc_free (e);
92*38fd1498Szrj }
93*38fd1498Szrj
94*38fd1498Szrj /* Free the memory associated with the edge structures. */
95*38fd1498Szrj
96*38fd1498Szrj void
clear_edges(struct function * fn)97*38fd1498Szrj clear_edges (struct function *fn)
98*38fd1498Szrj {
99*38fd1498Szrj basic_block bb;
100*38fd1498Szrj edge e;
101*38fd1498Szrj edge_iterator ei;
102*38fd1498Szrj
103*38fd1498Szrj FOR_EACH_BB_FN (bb, fn)
104*38fd1498Szrj {
105*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs)
106*38fd1498Szrj free_edge (fn, e);
107*38fd1498Szrj vec_safe_truncate (bb->succs, 0);
108*38fd1498Szrj vec_safe_truncate (bb->preds, 0);
109*38fd1498Szrj }
110*38fd1498Szrj
111*38fd1498Szrj FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fn)->succs)
112*38fd1498Szrj free_edge (fn, e);
113*38fd1498Szrj vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (fn)->preds, 0);
114*38fd1498Szrj vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (fn)->succs, 0);
115*38fd1498Szrj
116*38fd1498Szrj gcc_assert (!n_edges_for_fn (fn));
117*38fd1498Szrj }
118*38fd1498Szrj
119*38fd1498Szrj /* Allocate memory for basic_block. */
120*38fd1498Szrj
121*38fd1498Szrj basic_block
alloc_block(void)122*38fd1498Szrj alloc_block (void)
123*38fd1498Szrj {
124*38fd1498Szrj basic_block bb;
125*38fd1498Szrj bb = ggc_cleared_alloc<basic_block_def> ();
126*38fd1498Szrj bb->count = profile_count::uninitialized ();
127*38fd1498Szrj return bb;
128*38fd1498Szrj }
129*38fd1498Szrj
130*38fd1498Szrj /* Link block B to chain after AFTER. */
131*38fd1498Szrj void
link_block(basic_block b,basic_block after)132*38fd1498Szrj link_block (basic_block b, basic_block after)
133*38fd1498Szrj {
134*38fd1498Szrj b->next_bb = after->next_bb;
135*38fd1498Szrj b->prev_bb = after;
136*38fd1498Szrj after->next_bb = b;
137*38fd1498Szrj b->next_bb->prev_bb = b;
138*38fd1498Szrj }
139*38fd1498Szrj
140*38fd1498Szrj /* Unlink block B from chain. */
141*38fd1498Szrj void
unlink_block(basic_block b)142*38fd1498Szrj unlink_block (basic_block b)
143*38fd1498Szrj {
144*38fd1498Szrj b->next_bb->prev_bb = b->prev_bb;
145*38fd1498Szrj b->prev_bb->next_bb = b->next_bb;
146*38fd1498Szrj b->prev_bb = NULL;
147*38fd1498Szrj b->next_bb = NULL;
148*38fd1498Szrj }
149*38fd1498Szrj
150*38fd1498Szrj /* Sequentially order blocks and compact the arrays. */
151*38fd1498Szrj void
compact_blocks(void)152*38fd1498Szrj compact_blocks (void)
153*38fd1498Szrj {
154*38fd1498Szrj int i;
155*38fd1498Szrj
156*38fd1498Szrj SET_BASIC_BLOCK_FOR_FN (cfun, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (cfun));
157*38fd1498Szrj SET_BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (cfun));
158*38fd1498Szrj
159*38fd1498Szrj if (df)
160*38fd1498Szrj df_compact_blocks ();
161*38fd1498Szrj else
162*38fd1498Szrj {
163*38fd1498Szrj basic_block bb;
164*38fd1498Szrj
165*38fd1498Szrj i = NUM_FIXED_BLOCKS;
166*38fd1498Szrj FOR_EACH_BB_FN (bb, cfun)
167*38fd1498Szrj {
168*38fd1498Szrj SET_BASIC_BLOCK_FOR_FN (cfun, i, bb);
169*38fd1498Szrj bb->index = i;
170*38fd1498Szrj i++;
171*38fd1498Szrj }
172*38fd1498Szrj gcc_assert (i == n_basic_blocks_for_fn (cfun));
173*38fd1498Szrj
174*38fd1498Szrj for (; i < last_basic_block_for_fn (cfun); i++)
175*38fd1498Szrj SET_BASIC_BLOCK_FOR_FN (cfun, i, NULL);
176*38fd1498Szrj }
177*38fd1498Szrj last_basic_block_for_fn (cfun) = n_basic_blocks_for_fn (cfun);
178*38fd1498Szrj }
179*38fd1498Szrj
180*38fd1498Szrj /* Remove block B from the basic block array. */
181*38fd1498Szrj
182*38fd1498Szrj void
expunge_block(basic_block b)183*38fd1498Szrj expunge_block (basic_block b)
184*38fd1498Szrj {
185*38fd1498Szrj unlink_block (b);
186*38fd1498Szrj SET_BASIC_BLOCK_FOR_FN (cfun, b->index, NULL);
187*38fd1498Szrj n_basic_blocks_for_fn (cfun)--;
188*38fd1498Szrj /* We should be able to ggc_free here, but we are not.
189*38fd1498Szrj The dead SSA_NAMES are left pointing to dead statements that are pointing
190*38fd1498Szrj to dead basic blocks making garbage collector to die.
191*38fd1498Szrj We should be able to release all dead SSA_NAMES and at the same time we should
192*38fd1498Szrj clear out BB pointer of dead statements consistently. */
193*38fd1498Szrj }
194*38fd1498Szrj
195*38fd1498Szrj /* Connect E to E->src. */
196*38fd1498Szrj
197*38fd1498Szrj static inline void
connect_src(edge e)198*38fd1498Szrj connect_src (edge e)
199*38fd1498Szrj {
200*38fd1498Szrj vec_safe_push (e->src->succs, e);
201*38fd1498Szrj df_mark_solutions_dirty ();
202*38fd1498Szrj }
203*38fd1498Szrj
204*38fd1498Szrj /* Connect E to E->dest. */
205*38fd1498Szrj
206*38fd1498Szrj static inline void
connect_dest(edge e)207*38fd1498Szrj connect_dest (edge e)
208*38fd1498Szrj {
209*38fd1498Szrj basic_block dest = e->dest;
210*38fd1498Szrj vec_safe_push (dest->preds, e);
211*38fd1498Szrj e->dest_idx = EDGE_COUNT (dest->preds) - 1;
212*38fd1498Szrj df_mark_solutions_dirty ();
213*38fd1498Szrj }
214*38fd1498Szrj
215*38fd1498Szrj /* Disconnect edge E from E->src. */
216*38fd1498Szrj
217*38fd1498Szrj static inline void
disconnect_src(edge e)218*38fd1498Szrj disconnect_src (edge e)
219*38fd1498Szrj {
220*38fd1498Szrj basic_block src = e->src;
221*38fd1498Szrj edge_iterator ei;
222*38fd1498Szrj edge tmp;
223*38fd1498Szrj
224*38fd1498Szrj for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
225*38fd1498Szrj {
226*38fd1498Szrj if (tmp == e)
227*38fd1498Szrj {
228*38fd1498Szrj src->succs->unordered_remove (ei.index);
229*38fd1498Szrj df_mark_solutions_dirty ();
230*38fd1498Szrj return;
231*38fd1498Szrj }
232*38fd1498Szrj else
233*38fd1498Szrj ei_next (&ei);
234*38fd1498Szrj }
235*38fd1498Szrj
236*38fd1498Szrj gcc_unreachable ();
237*38fd1498Szrj }
238*38fd1498Szrj
239*38fd1498Szrj /* Disconnect edge E from E->dest. */
240*38fd1498Szrj
241*38fd1498Szrj static inline void
disconnect_dest(edge e)242*38fd1498Szrj disconnect_dest (edge e)
243*38fd1498Szrj {
244*38fd1498Szrj basic_block dest = e->dest;
245*38fd1498Szrj unsigned int dest_idx = e->dest_idx;
246*38fd1498Szrj
247*38fd1498Szrj dest->preds->unordered_remove (dest_idx);
248*38fd1498Szrj
249*38fd1498Szrj /* If we removed an edge in the middle of the edge vector, we need
250*38fd1498Szrj to update dest_idx of the edge that moved into the "hole". */
251*38fd1498Szrj if (dest_idx < EDGE_COUNT (dest->preds))
252*38fd1498Szrj EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
253*38fd1498Szrj df_mark_solutions_dirty ();
254*38fd1498Szrj }
255*38fd1498Szrj
256*38fd1498Szrj /* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
257*38fd1498Szrj created edge. Use this only if you are sure that this edge can't
258*38fd1498Szrj possibly already exist. */
259*38fd1498Szrj
260*38fd1498Szrj edge
unchecked_make_edge(basic_block src,basic_block dst,int flags)261*38fd1498Szrj unchecked_make_edge (basic_block src, basic_block dst, int flags)
262*38fd1498Szrj {
263*38fd1498Szrj edge e;
264*38fd1498Szrj e = ggc_cleared_alloc<edge_def> ();
265*38fd1498Szrj n_edges_for_fn (cfun)++;
266*38fd1498Szrj
267*38fd1498Szrj e->probability = profile_probability::uninitialized ();
268*38fd1498Szrj e->src = src;
269*38fd1498Szrj e->dest = dst;
270*38fd1498Szrj e->flags = flags;
271*38fd1498Szrj
272*38fd1498Szrj connect_src (e);
273*38fd1498Szrj connect_dest (e);
274*38fd1498Szrj
275*38fd1498Szrj execute_on_growing_pred (e);
276*38fd1498Szrj return e;
277*38fd1498Szrj }
278*38fd1498Szrj
279*38fd1498Szrj /* Create an edge connecting SRC and DST with FLAGS optionally using
280*38fd1498Szrj edge cache CACHE. Return the new edge, NULL if already exist. */
281*38fd1498Szrj
282*38fd1498Szrj edge
cached_make_edge(sbitmap edge_cache,basic_block src,basic_block dst,int flags)283*38fd1498Szrj cached_make_edge (sbitmap edge_cache, basic_block src, basic_block dst, int flags)
284*38fd1498Szrj {
285*38fd1498Szrj if (edge_cache == NULL
286*38fd1498Szrj || src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
287*38fd1498Szrj || dst == EXIT_BLOCK_PTR_FOR_FN (cfun))
288*38fd1498Szrj return make_edge (src, dst, flags);
289*38fd1498Szrj
290*38fd1498Szrj /* Does the requested edge already exist? */
291*38fd1498Szrj if (! bitmap_bit_p (edge_cache, dst->index))
292*38fd1498Szrj {
293*38fd1498Szrj /* The edge does not exist. Create one and update the
294*38fd1498Szrj cache. */
295*38fd1498Szrj bitmap_set_bit (edge_cache, dst->index);
296*38fd1498Szrj return unchecked_make_edge (src, dst, flags);
297*38fd1498Szrj }
298*38fd1498Szrj
299*38fd1498Szrj /* At this point, we know that the requested edge exists. Adjust
300*38fd1498Szrj flags if necessary. */
301*38fd1498Szrj if (flags)
302*38fd1498Szrj {
303*38fd1498Szrj edge e = find_edge (src, dst);
304*38fd1498Szrj e->flags |= flags;
305*38fd1498Szrj }
306*38fd1498Szrj
307*38fd1498Szrj return NULL;
308*38fd1498Szrj }
309*38fd1498Szrj
310*38fd1498Szrj /* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
311*38fd1498Szrj created edge or NULL if already exist. */
312*38fd1498Szrj
313*38fd1498Szrj edge
make_edge(basic_block src,basic_block dest,int flags)314*38fd1498Szrj make_edge (basic_block src, basic_block dest, int flags)
315*38fd1498Szrj {
316*38fd1498Szrj edge e = find_edge (src, dest);
317*38fd1498Szrj
318*38fd1498Szrj /* Make sure we don't add duplicate edges. */
319*38fd1498Szrj if (e)
320*38fd1498Szrj {
321*38fd1498Szrj e->flags |= flags;
322*38fd1498Szrj return NULL;
323*38fd1498Szrj }
324*38fd1498Szrj
325*38fd1498Szrj return unchecked_make_edge (src, dest, flags);
326*38fd1498Szrj }
327*38fd1498Szrj
328*38fd1498Szrj /* Create an edge connecting SRC to DEST and set probability by knowing
329*38fd1498Szrj that it is the single edge leaving SRC. */
330*38fd1498Szrj
331*38fd1498Szrj edge
make_single_succ_edge(basic_block src,basic_block dest,int flags)332*38fd1498Szrj make_single_succ_edge (basic_block src, basic_block dest, int flags)
333*38fd1498Szrj {
334*38fd1498Szrj edge e = make_edge (src, dest, flags);
335*38fd1498Szrj
336*38fd1498Szrj e->probability = profile_probability::always ();
337*38fd1498Szrj return e;
338*38fd1498Szrj }
339*38fd1498Szrj
340*38fd1498Szrj /* This function will remove an edge from the flow graph. */
341*38fd1498Szrj
342*38fd1498Szrj void
remove_edge_raw(edge e)343*38fd1498Szrj remove_edge_raw (edge e)
344*38fd1498Szrj {
345*38fd1498Szrj remove_predictions_associated_with_edge (e);
346*38fd1498Szrj execute_on_shrinking_pred (e);
347*38fd1498Szrj
348*38fd1498Szrj disconnect_src (e);
349*38fd1498Szrj disconnect_dest (e);
350*38fd1498Szrj
351*38fd1498Szrj free_edge (cfun, e);
352*38fd1498Szrj }
353*38fd1498Szrj
354*38fd1498Szrj /* Redirect an edge's successor from one block to another. */
355*38fd1498Szrj
356*38fd1498Szrj void
redirect_edge_succ(edge e,basic_block new_succ)357*38fd1498Szrj redirect_edge_succ (edge e, basic_block new_succ)
358*38fd1498Szrj {
359*38fd1498Szrj execute_on_shrinking_pred (e);
360*38fd1498Szrj
361*38fd1498Szrj disconnect_dest (e);
362*38fd1498Szrj
363*38fd1498Szrj e->dest = new_succ;
364*38fd1498Szrj
365*38fd1498Szrj /* Reconnect the edge to the new successor block. */
366*38fd1498Szrj connect_dest (e);
367*38fd1498Szrj
368*38fd1498Szrj execute_on_growing_pred (e);
369*38fd1498Szrj }
370*38fd1498Szrj
371*38fd1498Szrj /* Redirect an edge's predecessor from one block to another. */
372*38fd1498Szrj
373*38fd1498Szrj void
redirect_edge_pred(edge e,basic_block new_pred)374*38fd1498Szrj redirect_edge_pred (edge e, basic_block new_pred)
375*38fd1498Szrj {
376*38fd1498Szrj disconnect_src (e);
377*38fd1498Szrj
378*38fd1498Szrj e->src = new_pred;
379*38fd1498Szrj
380*38fd1498Szrj /* Reconnect the edge to the new predecessor block. */
381*38fd1498Szrj connect_src (e);
382*38fd1498Szrj }
383*38fd1498Szrj
384*38fd1498Szrj /* Clear all basic block flags that do not have to be preserved. */
385*38fd1498Szrj void
clear_bb_flags(void)386*38fd1498Szrj clear_bb_flags (void)
387*38fd1498Szrj {
388*38fd1498Szrj basic_block bb;
389*38fd1498Szrj int flags_to_preserve = BB_FLAGS_TO_PRESERVE;
390*38fd1498Szrj if (current_loops
391*38fd1498Szrj && loops_state_satisfies_p (cfun, LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
392*38fd1498Szrj flags_to_preserve |= BB_IRREDUCIBLE_LOOP;
393*38fd1498Szrj
394*38fd1498Szrj FOR_ALL_BB_FN (bb, cfun)
395*38fd1498Szrj bb->flags &= flags_to_preserve;
396*38fd1498Szrj }
397*38fd1498Szrj
398*38fd1498Szrj /* Check the consistency of profile information. We can't do that
399*38fd1498Szrj in verify_flow_info, as the counts may get invalid for incompletely
400*38fd1498Szrj solved graphs, later eliminating of conditionals or roundoff errors.
401*38fd1498Szrj It is still practical to have them reported for debugging of simple
402*38fd1498Szrj testcases. */
403*38fd1498Szrj static void
check_bb_profile(basic_block bb,FILE * file,int indent)404*38fd1498Szrj check_bb_profile (basic_block bb, FILE * file, int indent)
405*38fd1498Szrj {
406*38fd1498Szrj edge e;
407*38fd1498Szrj edge_iterator ei;
408*38fd1498Szrj struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl);
409*38fd1498Szrj char *s_indent = (char *) alloca ((size_t) indent + 1);
410*38fd1498Szrj memset ((void *) s_indent, ' ', (size_t) indent);
411*38fd1498Szrj s_indent[indent] = '\0';
412*38fd1498Szrj
413*38fd1498Szrj if (profile_status_for_fn (fun) == PROFILE_ABSENT)
414*38fd1498Szrj return;
415*38fd1498Szrj
416*38fd1498Szrj if (bb != EXIT_BLOCK_PTR_FOR_FN (fun))
417*38fd1498Szrj {
418*38fd1498Szrj bool found = false;
419*38fd1498Szrj profile_probability sum = profile_probability::never ();
420*38fd1498Szrj int isum = 0;
421*38fd1498Szrj
422*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs)
423*38fd1498Szrj {
424*38fd1498Szrj if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
425*38fd1498Szrj found = true;
426*38fd1498Szrj sum += e->probability;
427*38fd1498Szrj if (e->probability.initialized_p ())
428*38fd1498Szrj isum += e->probability.to_reg_br_prob_base ();
429*38fd1498Szrj }
430*38fd1498Szrj /* Only report mismatches for non-EH control flow. If there are only EH
431*38fd1498Szrj edges it means that the BB ends by noreturn call. Here the control
432*38fd1498Szrj flow may just terminate. */
433*38fd1498Szrj if (found)
434*38fd1498Szrj {
435*38fd1498Szrj if (sum.differs_from_p (profile_probability::always ()))
436*38fd1498Szrj {
437*38fd1498Szrj fprintf (file,
438*38fd1498Szrj ";; %sInvalid sum of outgoing probabilities ",
439*38fd1498Szrj s_indent);
440*38fd1498Szrj sum.dump (file);
441*38fd1498Szrj fprintf (file, "\n");
442*38fd1498Szrj }
443*38fd1498Szrj /* Probabilities caps to 100% and thus the previous test will never
444*38fd1498Szrj fire if the sum of probabilities is too large. */
445*38fd1498Szrj else if (isum > REG_BR_PROB_BASE + 100)
446*38fd1498Szrj {
447*38fd1498Szrj fprintf (file,
448*38fd1498Szrj ";; %sInvalid sum of outgoing probabilities %.1f%%\n",
449*38fd1498Szrj s_indent, isum * 100.0 / REG_BR_PROB_BASE);
450*38fd1498Szrj }
451*38fd1498Szrj }
452*38fd1498Szrj }
453*38fd1498Szrj if (bb != ENTRY_BLOCK_PTR_FOR_FN (fun))
454*38fd1498Szrj {
455*38fd1498Szrj profile_count sum = profile_count::zero ();
456*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->preds)
457*38fd1498Szrj sum += e->count ();
458*38fd1498Szrj if (sum.differs_from_p (bb->count))
459*38fd1498Szrj {
460*38fd1498Szrj fprintf (file, ";; %sInvalid sum of incoming counts ",
461*38fd1498Szrj s_indent);
462*38fd1498Szrj sum.dump (file);
463*38fd1498Szrj fprintf (file, ", should be ");
464*38fd1498Szrj bb->count.dump (file);
465*38fd1498Szrj fprintf (file, "\n");
466*38fd1498Szrj }
467*38fd1498Szrj }
468*38fd1498Szrj if (BB_PARTITION (bb) == BB_COLD_PARTITION)
469*38fd1498Szrj {
470*38fd1498Szrj /* Warn about inconsistencies in the partitioning that are
471*38fd1498Szrj currently caused by profile insanities created via optimization. */
472*38fd1498Szrj if (!probably_never_executed_bb_p (fun, bb))
473*38fd1498Szrj fprintf (file, ";; %sBlock in cold partition with hot count\n",
474*38fd1498Szrj s_indent);
475*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->preds)
476*38fd1498Szrj {
477*38fd1498Szrj if (!probably_never_executed_edge_p (fun, e))
478*38fd1498Szrj fprintf (file,
479*38fd1498Szrj ";; %sBlock in cold partition with incoming hot edge\n",
480*38fd1498Szrj s_indent);
481*38fd1498Szrj }
482*38fd1498Szrj }
483*38fd1498Szrj }
484*38fd1498Szrj
485*38fd1498Szrj void
dump_edge_info(FILE * file,edge e,dump_flags_t flags,int do_succ)486*38fd1498Szrj dump_edge_info (FILE *file, edge e, dump_flags_t flags, int do_succ)
487*38fd1498Szrj {
488*38fd1498Szrj basic_block side = (do_succ ? e->dest : e->src);
489*38fd1498Szrj bool do_details = false;
490*38fd1498Szrj
491*38fd1498Szrj if ((flags & TDF_DETAILS) != 0
492*38fd1498Szrj && (flags & TDF_SLIM) == 0)
493*38fd1498Szrj do_details = true;
494*38fd1498Szrj
495*38fd1498Szrj if (side->index == ENTRY_BLOCK)
496*38fd1498Szrj fputs (" ENTRY", file);
497*38fd1498Szrj else if (side->index == EXIT_BLOCK)
498*38fd1498Szrj fputs (" EXIT", file);
499*38fd1498Szrj else
500*38fd1498Szrj fprintf (file, " %d", side->index);
501*38fd1498Szrj
502*38fd1498Szrj if (e->probability.initialized_p () && do_details)
503*38fd1498Szrj {
504*38fd1498Szrj fprintf (file, " [");
505*38fd1498Szrj e->probability.dump (file);
506*38fd1498Szrj fprintf (file, "] ");
507*38fd1498Szrj }
508*38fd1498Szrj
509*38fd1498Szrj if (e->count ().initialized_p () && do_details)
510*38fd1498Szrj {
511*38fd1498Szrj fputs (" count:", file);
512*38fd1498Szrj e->count ().dump (file);
513*38fd1498Szrj }
514*38fd1498Szrj
515*38fd1498Szrj if (e->flags && do_details)
516*38fd1498Szrj {
517*38fd1498Szrj static const char * const bitnames[] =
518*38fd1498Szrj {
519*38fd1498Szrj #define DEF_EDGE_FLAG(NAME,IDX) #NAME ,
520*38fd1498Szrj #include "cfg-flags.def"
521*38fd1498Szrj NULL
522*38fd1498Szrj #undef DEF_EDGE_FLAG
523*38fd1498Szrj };
524*38fd1498Szrj bool comma = false;
525*38fd1498Szrj int i, flags = e->flags;
526*38fd1498Szrj
527*38fd1498Szrj gcc_assert (e->flags <= EDGE_ALL_FLAGS);
528*38fd1498Szrj fputs (" (", file);
529*38fd1498Szrj for (i = 0; flags; i++)
530*38fd1498Szrj if (flags & (1 << i))
531*38fd1498Szrj {
532*38fd1498Szrj flags &= ~(1 << i);
533*38fd1498Szrj
534*38fd1498Szrj if (comma)
535*38fd1498Szrj fputc (',', file);
536*38fd1498Szrj fputs (bitnames[i], file);
537*38fd1498Szrj comma = true;
538*38fd1498Szrj }
539*38fd1498Szrj
540*38fd1498Szrj fputc (')', file);
541*38fd1498Szrj }
542*38fd1498Szrj }
543*38fd1498Szrj
544*38fd1498Szrj DEBUG_FUNCTION void
debug(edge_def & ref)545*38fd1498Szrj debug (edge_def &ref)
546*38fd1498Szrj {
547*38fd1498Szrj /* FIXME (crowl): Is this desireable? */
548*38fd1498Szrj dump_edge_info (stderr, &ref, 0, false);
549*38fd1498Szrj dump_edge_info (stderr, &ref, 0, true);
550*38fd1498Szrj }
551*38fd1498Szrj
552*38fd1498Szrj DEBUG_FUNCTION void
debug(edge_def * ptr)553*38fd1498Szrj debug (edge_def *ptr)
554*38fd1498Szrj {
555*38fd1498Szrj if (ptr)
556*38fd1498Szrj debug (*ptr);
557*38fd1498Szrj else
558*38fd1498Szrj fprintf (stderr, "<nil>\n");
559*38fd1498Szrj }
560*38fd1498Szrj
561*38fd1498Szrj static void
debug_slim(edge e)562*38fd1498Szrj debug_slim (edge e)
563*38fd1498Szrj {
564*38fd1498Szrj fprintf (stderr, "<edge 0x%p (%d -> %d)>", (void *) e,
565*38fd1498Szrj e->src->index, e->dest->index);
566*38fd1498Szrj }
567*38fd1498Szrj
568*38fd1498Szrj DEFINE_DEBUG_VEC (edge)
569*38fd1498Szrj DEFINE_DEBUG_HASH_SET (edge)
570*38fd1498Szrj
571*38fd1498Szrj /* Simple routines to easily allocate AUX fields of basic blocks. */
572*38fd1498Szrj
573*38fd1498Szrj static struct obstack block_aux_obstack;
574*38fd1498Szrj static void *first_block_aux_obj = 0;
575*38fd1498Szrj static struct obstack edge_aux_obstack;
576*38fd1498Szrj static void *first_edge_aux_obj = 0;
577*38fd1498Szrj
578*38fd1498Szrj /* Allocate a memory block of SIZE as BB->aux. The obstack must
579*38fd1498Szrj be first initialized by alloc_aux_for_blocks. */
580*38fd1498Szrj
581*38fd1498Szrj static void
alloc_aux_for_block(basic_block bb,int size)582*38fd1498Szrj alloc_aux_for_block (basic_block bb, int size)
583*38fd1498Szrj {
584*38fd1498Szrj /* Verify that aux field is clear. */
585*38fd1498Szrj gcc_assert (!bb->aux && first_block_aux_obj);
586*38fd1498Szrj bb->aux = obstack_alloc (&block_aux_obstack, size);
587*38fd1498Szrj memset (bb->aux, 0, size);
588*38fd1498Szrj }
589*38fd1498Szrj
590*38fd1498Szrj /* Initialize the block_aux_obstack and if SIZE is nonzero, call
591*38fd1498Szrj alloc_aux_for_block for each basic block. */
592*38fd1498Szrj
593*38fd1498Szrj void
alloc_aux_for_blocks(int size)594*38fd1498Szrj alloc_aux_for_blocks (int size)
595*38fd1498Szrj {
596*38fd1498Szrj static int initialized;
597*38fd1498Szrj
598*38fd1498Szrj if (!initialized)
599*38fd1498Szrj {
600*38fd1498Szrj gcc_obstack_init (&block_aux_obstack);
601*38fd1498Szrj initialized = 1;
602*38fd1498Szrj }
603*38fd1498Szrj else
604*38fd1498Szrj /* Check whether AUX data are still allocated. */
605*38fd1498Szrj gcc_assert (!first_block_aux_obj);
606*38fd1498Szrj
607*38fd1498Szrj first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
608*38fd1498Szrj if (size)
609*38fd1498Szrj {
610*38fd1498Szrj basic_block bb;
611*38fd1498Szrj
612*38fd1498Szrj FOR_ALL_BB_FN (bb, cfun)
613*38fd1498Szrj alloc_aux_for_block (bb, size);
614*38fd1498Szrj }
615*38fd1498Szrj }
616*38fd1498Szrj
617*38fd1498Szrj /* Clear AUX pointers of all blocks. */
618*38fd1498Szrj
619*38fd1498Szrj void
clear_aux_for_blocks(void)620*38fd1498Szrj clear_aux_for_blocks (void)
621*38fd1498Szrj {
622*38fd1498Szrj basic_block bb;
623*38fd1498Szrj
624*38fd1498Szrj FOR_ALL_BB_FN (bb, cfun)
625*38fd1498Szrj bb->aux = NULL;
626*38fd1498Szrj }
627*38fd1498Szrj
628*38fd1498Szrj /* Free data allocated in block_aux_obstack and clear AUX pointers
629*38fd1498Szrj of all blocks. */
630*38fd1498Szrj
631*38fd1498Szrj void
free_aux_for_blocks(void)632*38fd1498Szrj free_aux_for_blocks (void)
633*38fd1498Szrj {
634*38fd1498Szrj gcc_assert (first_block_aux_obj);
635*38fd1498Szrj obstack_free (&block_aux_obstack, first_block_aux_obj);
636*38fd1498Szrj first_block_aux_obj = NULL;
637*38fd1498Szrj
638*38fd1498Szrj clear_aux_for_blocks ();
639*38fd1498Szrj }
640*38fd1498Szrj
641*38fd1498Szrj /* Allocate a memory edge of SIZE as E->aux. The obstack must
642*38fd1498Szrj be first initialized by alloc_aux_for_edges. */
643*38fd1498Szrj
644*38fd1498Szrj void
alloc_aux_for_edge(edge e,int size)645*38fd1498Szrj alloc_aux_for_edge (edge e, int size)
646*38fd1498Szrj {
647*38fd1498Szrj /* Verify that aux field is clear. */
648*38fd1498Szrj gcc_assert (!e->aux && first_edge_aux_obj);
649*38fd1498Szrj e->aux = obstack_alloc (&edge_aux_obstack, size);
650*38fd1498Szrj memset (e->aux, 0, size);
651*38fd1498Szrj }
652*38fd1498Szrj
653*38fd1498Szrj /* Initialize the edge_aux_obstack and if SIZE is nonzero, call
654*38fd1498Szrj alloc_aux_for_edge for each basic edge. */
655*38fd1498Szrj
656*38fd1498Szrj void
alloc_aux_for_edges(int size)657*38fd1498Szrj alloc_aux_for_edges (int size)
658*38fd1498Szrj {
659*38fd1498Szrj static int initialized;
660*38fd1498Szrj
661*38fd1498Szrj if (!initialized)
662*38fd1498Szrj {
663*38fd1498Szrj gcc_obstack_init (&edge_aux_obstack);
664*38fd1498Szrj initialized = 1;
665*38fd1498Szrj }
666*38fd1498Szrj else
667*38fd1498Szrj /* Check whether AUX data are still allocated. */
668*38fd1498Szrj gcc_assert (!first_edge_aux_obj);
669*38fd1498Szrj
670*38fd1498Szrj first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
671*38fd1498Szrj if (size)
672*38fd1498Szrj {
673*38fd1498Szrj basic_block bb;
674*38fd1498Szrj
675*38fd1498Szrj FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
676*38fd1498Szrj EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
677*38fd1498Szrj {
678*38fd1498Szrj edge e;
679*38fd1498Szrj edge_iterator ei;
680*38fd1498Szrj
681*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs)
682*38fd1498Szrj alloc_aux_for_edge (e, size);
683*38fd1498Szrj }
684*38fd1498Szrj }
685*38fd1498Szrj }
686*38fd1498Szrj
687*38fd1498Szrj /* Clear AUX pointers of all edges. */
688*38fd1498Szrj
689*38fd1498Szrj void
clear_aux_for_edges(void)690*38fd1498Szrj clear_aux_for_edges (void)
691*38fd1498Szrj {
692*38fd1498Szrj basic_block bb;
693*38fd1498Szrj edge e;
694*38fd1498Szrj
695*38fd1498Szrj FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
696*38fd1498Szrj EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
697*38fd1498Szrj {
698*38fd1498Szrj edge_iterator ei;
699*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs)
700*38fd1498Szrj e->aux = NULL;
701*38fd1498Szrj }
702*38fd1498Szrj }
703*38fd1498Szrj
704*38fd1498Szrj /* Free data allocated in edge_aux_obstack and clear AUX pointers
705*38fd1498Szrj of all edges. */
706*38fd1498Szrj
707*38fd1498Szrj void
free_aux_for_edges(void)708*38fd1498Szrj free_aux_for_edges (void)
709*38fd1498Szrj {
710*38fd1498Szrj gcc_assert (first_edge_aux_obj);
711*38fd1498Szrj obstack_free (&edge_aux_obstack, first_edge_aux_obj);
712*38fd1498Szrj first_edge_aux_obj = NULL;
713*38fd1498Szrj
714*38fd1498Szrj clear_aux_for_edges ();
715*38fd1498Szrj }
716*38fd1498Szrj
717*38fd1498Szrj DEBUG_FUNCTION void
debug_bb(basic_block bb)718*38fd1498Szrj debug_bb (basic_block bb)
719*38fd1498Szrj {
720*38fd1498Szrj dump_bb (stderr, bb, 0, dump_flags);
721*38fd1498Szrj }
722*38fd1498Szrj
723*38fd1498Szrj DEBUG_FUNCTION basic_block
debug_bb_n(int n)724*38fd1498Szrj debug_bb_n (int n)
725*38fd1498Szrj {
726*38fd1498Szrj basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
727*38fd1498Szrj debug_bb (bb);
728*38fd1498Szrj return bb;
729*38fd1498Szrj }
730*38fd1498Szrj
731*38fd1498Szrj /* Dumps cfg related information about basic block BB to OUTF.
732*38fd1498Szrj If HEADER is true, dump things that appear before the instructions
733*38fd1498Szrj contained in BB. If FOOTER is true, dump things that appear after.
734*38fd1498Szrj Flags are the TDF_* masks as documented in dumpfile.h.
735*38fd1498Szrj NB: With TDF_DETAILS, it is assumed that cfun is available, so
736*38fd1498Szrj that maybe_hot_bb_p and probably_never_executed_bb_p don't ICE. */
737*38fd1498Szrj
738*38fd1498Szrj void
dump_bb_info(FILE * outf,basic_block bb,int indent,dump_flags_t flags,bool do_header,bool do_footer)739*38fd1498Szrj dump_bb_info (FILE *outf, basic_block bb, int indent, dump_flags_t flags,
740*38fd1498Szrj bool do_header, bool do_footer)
741*38fd1498Szrj {
742*38fd1498Szrj edge_iterator ei;
743*38fd1498Szrj edge e;
744*38fd1498Szrj static const char * const bb_bitnames[] =
745*38fd1498Szrj {
746*38fd1498Szrj #define DEF_BASIC_BLOCK_FLAG(NAME,IDX) #NAME ,
747*38fd1498Szrj #include "cfg-flags.def"
748*38fd1498Szrj NULL
749*38fd1498Szrj #undef DEF_BASIC_BLOCK_FLAG
750*38fd1498Szrj };
751*38fd1498Szrj const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *);
752*38fd1498Szrj bool first;
753*38fd1498Szrj char *s_indent = (char *) alloca ((size_t) indent + 1);
754*38fd1498Szrj memset ((void *) s_indent, ' ', (size_t) indent);
755*38fd1498Szrj s_indent[indent] = '\0';
756*38fd1498Szrj
757*38fd1498Szrj gcc_assert (bb->flags <= BB_ALL_FLAGS);
758*38fd1498Szrj
759*38fd1498Szrj if (do_header)
760*38fd1498Szrj {
761*38fd1498Szrj unsigned i;
762*38fd1498Szrj
763*38fd1498Szrj fputs (";; ", outf);
764*38fd1498Szrj fprintf (outf, "%sbasic block %d, loop depth %d",
765*38fd1498Szrj s_indent, bb->index, bb_loop_depth (bb));
766*38fd1498Szrj if (flags & TDF_DETAILS)
767*38fd1498Szrj {
768*38fd1498Szrj struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl);
769*38fd1498Szrj if (bb->count.initialized_p ())
770*38fd1498Szrj {
771*38fd1498Szrj fputs (", count ", outf);
772*38fd1498Szrj bb->count.dump (outf);
773*38fd1498Szrj }
774*38fd1498Szrj if (maybe_hot_bb_p (fun, bb))
775*38fd1498Szrj fputs (", maybe hot", outf);
776*38fd1498Szrj if (probably_never_executed_bb_p (fun, bb))
777*38fd1498Szrj fputs (", probably never executed", outf);
778*38fd1498Szrj }
779*38fd1498Szrj fputc ('\n', outf);
780*38fd1498Szrj
781*38fd1498Szrj if (flags & TDF_DETAILS)
782*38fd1498Szrj {
783*38fd1498Szrj check_bb_profile (bb, outf, indent);
784*38fd1498Szrj fputs (";; ", outf);
785*38fd1498Szrj fprintf (outf, "%s prev block ", s_indent);
786*38fd1498Szrj if (bb->prev_bb)
787*38fd1498Szrj fprintf (outf, "%d", bb->prev_bb->index);
788*38fd1498Szrj else
789*38fd1498Szrj fprintf (outf, "(nil)");
790*38fd1498Szrj fprintf (outf, ", next block ");
791*38fd1498Szrj if (bb->next_bb)
792*38fd1498Szrj fprintf (outf, "%d", bb->next_bb->index);
793*38fd1498Szrj else
794*38fd1498Szrj fprintf (outf, "(nil)");
795*38fd1498Szrj
796*38fd1498Szrj fputs (", flags:", outf);
797*38fd1498Szrj first = true;
798*38fd1498Szrj for (i = 0; i < n_bitnames; i++)
799*38fd1498Szrj if (bb->flags & (1 << i))
800*38fd1498Szrj {
801*38fd1498Szrj if (first)
802*38fd1498Szrj fputs (" (", outf);
803*38fd1498Szrj else
804*38fd1498Szrj fputs (", ", outf);
805*38fd1498Szrj first = false;
806*38fd1498Szrj fputs (bb_bitnames[i], outf);
807*38fd1498Szrj }
808*38fd1498Szrj if (!first)
809*38fd1498Szrj fputc (')', outf);
810*38fd1498Szrj fputc ('\n', outf);
811*38fd1498Szrj }
812*38fd1498Szrj
813*38fd1498Szrj fputs (";; ", outf);
814*38fd1498Szrj fprintf (outf, "%s pred: ", s_indent);
815*38fd1498Szrj first = true;
816*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->preds)
817*38fd1498Szrj {
818*38fd1498Szrj if (! first)
819*38fd1498Szrj {
820*38fd1498Szrj fputs (";; ", outf);
821*38fd1498Szrj fprintf (outf, "%s ", s_indent);
822*38fd1498Szrj }
823*38fd1498Szrj first = false;
824*38fd1498Szrj dump_edge_info (outf, e, flags, 0);
825*38fd1498Szrj fputc ('\n', outf);
826*38fd1498Szrj }
827*38fd1498Szrj if (first)
828*38fd1498Szrj fputc ('\n', outf);
829*38fd1498Szrj }
830*38fd1498Szrj
831*38fd1498Szrj if (do_footer)
832*38fd1498Szrj {
833*38fd1498Szrj fputs (";; ", outf);
834*38fd1498Szrj fprintf (outf, "%s succ: ", s_indent);
835*38fd1498Szrj first = true;
836*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs)
837*38fd1498Szrj {
838*38fd1498Szrj if (! first)
839*38fd1498Szrj {
840*38fd1498Szrj fputs (";; ", outf);
841*38fd1498Szrj fprintf (outf, "%s ", s_indent);
842*38fd1498Szrj }
843*38fd1498Szrj first = false;
844*38fd1498Szrj dump_edge_info (outf, e, flags, 1);
845*38fd1498Szrj fputc ('\n', outf);
846*38fd1498Szrj }
847*38fd1498Szrj if (first)
848*38fd1498Szrj fputc ('\n', outf);
849*38fd1498Szrj }
850*38fd1498Szrj }
851*38fd1498Szrj
852*38fd1498Szrj /* Dumps a brief description of cfg to FILE. */
853*38fd1498Szrj
854*38fd1498Szrj void
brief_dump_cfg(FILE * file,dump_flags_t flags)855*38fd1498Szrj brief_dump_cfg (FILE *file, dump_flags_t flags)
856*38fd1498Szrj {
857*38fd1498Szrj basic_block bb;
858*38fd1498Szrj
859*38fd1498Szrj FOR_EACH_BB_FN (bb, cfun)
860*38fd1498Szrj {
861*38fd1498Szrj dump_bb_info (file, bb, 0, flags & TDF_DETAILS, true, true);
862*38fd1498Szrj }
863*38fd1498Szrj }
864*38fd1498Szrj
865*38fd1498Szrj /* An edge originally destinating BB of COUNT has been proved to
866*38fd1498Szrj leave the block by TAKEN_EDGE. Update profile of BB such that edge E can be
867*38fd1498Szrj redirected to destination of TAKEN_EDGE.
868*38fd1498Szrj
869*38fd1498Szrj This function may leave the profile inconsistent in the case TAKEN_EDGE
870*38fd1498Szrj frequency or count is believed to be lower than COUNT
871*38fd1498Szrj respectively. */
872*38fd1498Szrj void
update_bb_profile_for_threading(basic_block bb,profile_count count,edge taken_edge)873*38fd1498Szrj update_bb_profile_for_threading (basic_block bb,
874*38fd1498Szrj profile_count count, edge taken_edge)
875*38fd1498Szrj {
876*38fd1498Szrj edge c;
877*38fd1498Szrj profile_probability prob;
878*38fd1498Szrj edge_iterator ei;
879*38fd1498Szrj
880*38fd1498Szrj if (bb->count < count)
881*38fd1498Szrj {
882*38fd1498Szrj if (dump_file)
883*38fd1498Szrj fprintf (dump_file, "bb %i count became negative after threading",
884*38fd1498Szrj bb->index);
885*38fd1498Szrj }
886*38fd1498Szrj bb->count -= count;
887*38fd1498Szrj
888*38fd1498Szrj /* Compute the probability of TAKEN_EDGE being reached via threaded edge.
889*38fd1498Szrj Watch for overflows. */
890*38fd1498Szrj if (bb->count.nonzero_p ())
891*38fd1498Szrj prob = count.probability_in (bb->count);
892*38fd1498Szrj else
893*38fd1498Szrj prob = profile_probability::never ();
894*38fd1498Szrj if (prob > taken_edge->probability)
895*38fd1498Szrj {
896*38fd1498Szrj if (dump_file)
897*38fd1498Szrj {
898*38fd1498Szrj fprintf (dump_file, "Jump threading proved probability of edge "
899*38fd1498Szrj "%i->%i too small (it is ",
900*38fd1498Szrj taken_edge->src->index, taken_edge->dest->index);
901*38fd1498Szrj taken_edge->probability.dump (dump_file);
902*38fd1498Szrj fprintf (dump_file, " should be ");
903*38fd1498Szrj prob.dump (dump_file);
904*38fd1498Szrj fprintf (dump_file, ")\n");
905*38fd1498Szrj }
906*38fd1498Szrj prob = taken_edge->probability.apply_scale (6, 8);
907*38fd1498Szrj }
908*38fd1498Szrj
909*38fd1498Szrj /* Now rescale the probabilities. */
910*38fd1498Szrj taken_edge->probability -= prob;
911*38fd1498Szrj prob = prob.invert ();
912*38fd1498Szrj if (prob == profile_probability::never ())
913*38fd1498Szrj {
914*38fd1498Szrj if (dump_file)
915*38fd1498Szrj fprintf (dump_file, "Edge probabilities of bb %i has been reset, "
916*38fd1498Szrj "count of block should end up being 0, it is non-zero\n",
917*38fd1498Szrj bb->index);
918*38fd1498Szrj EDGE_SUCC (bb, 0)->probability = profile_probability::guessed_always ();
919*38fd1498Szrj ei = ei_start (bb->succs);
920*38fd1498Szrj ei_next (&ei);
921*38fd1498Szrj for (; (c = ei_safe_edge (ei)); ei_next (&ei))
922*38fd1498Szrj c->probability = profile_probability::guessed_never ();
923*38fd1498Szrj }
924*38fd1498Szrj else if (!(prob == profile_probability::always ()))
925*38fd1498Szrj {
926*38fd1498Szrj FOR_EACH_EDGE (c, ei, bb->succs)
927*38fd1498Szrj c->probability /= prob;
928*38fd1498Szrj }
929*38fd1498Szrj
930*38fd1498Szrj gcc_assert (bb == taken_edge->src);
931*38fd1498Szrj }
932*38fd1498Szrj
933*38fd1498Szrj /* Multiply all frequencies of basic blocks in array BBS of length NBBS
934*38fd1498Szrj by NUM/DEN, in profile_count arithmetic. More accurate than previous
935*38fd1498Szrj function but considerably slower. */
936*38fd1498Szrj void
scale_bbs_frequencies_profile_count(basic_block * bbs,int nbbs,profile_count num,profile_count den)937*38fd1498Szrj scale_bbs_frequencies_profile_count (basic_block *bbs, int nbbs,
938*38fd1498Szrj profile_count num, profile_count den)
939*38fd1498Szrj {
940*38fd1498Szrj int i;
941*38fd1498Szrj if (num == profile_count::zero () || den.nonzero_p ())
942*38fd1498Szrj for (i = 0; i < nbbs; i++)
943*38fd1498Szrj bbs[i]->count = bbs[i]->count.apply_scale (num, den);
944*38fd1498Szrj }
945*38fd1498Szrj
946*38fd1498Szrj /* Multiply all frequencies of basic blocks in array BBS of length NBBS
947*38fd1498Szrj by NUM/DEN, in profile_count arithmetic. More accurate than previous
948*38fd1498Szrj function but considerably slower. */
949*38fd1498Szrj void
scale_bbs_frequencies(basic_block * bbs,int nbbs,profile_probability p)950*38fd1498Szrj scale_bbs_frequencies (basic_block *bbs, int nbbs,
951*38fd1498Szrj profile_probability p)
952*38fd1498Szrj {
953*38fd1498Szrj int i;
954*38fd1498Szrj
955*38fd1498Szrj for (i = 0; i < nbbs; i++)
956*38fd1498Szrj bbs[i]->count = bbs[i]->count.apply_probability (p);
957*38fd1498Szrj }
958*38fd1498Szrj
959*38fd1498Szrj /* Helper types for hash tables. */
960*38fd1498Szrj
961*38fd1498Szrj struct htab_bb_copy_original_entry
962*38fd1498Szrj {
963*38fd1498Szrj /* Block we are attaching info to. */
964*38fd1498Szrj int index1;
965*38fd1498Szrj /* Index of original or copy (depending on the hashtable) */
966*38fd1498Szrj int index2;
967*38fd1498Szrj };
968*38fd1498Szrj
969*38fd1498Szrj struct bb_copy_hasher : nofree_ptr_hash <htab_bb_copy_original_entry>
970*38fd1498Szrj {
971*38fd1498Szrj static inline hashval_t hash (const htab_bb_copy_original_entry *);
972*38fd1498Szrj static inline bool equal (const htab_bb_copy_original_entry *existing,
973*38fd1498Szrj const htab_bb_copy_original_entry * candidate);
974*38fd1498Szrj };
975*38fd1498Szrj
976*38fd1498Szrj inline hashval_t
hash(const htab_bb_copy_original_entry * data)977*38fd1498Szrj bb_copy_hasher::hash (const htab_bb_copy_original_entry *data)
978*38fd1498Szrj {
979*38fd1498Szrj return data->index1;
980*38fd1498Szrj }
981*38fd1498Szrj
982*38fd1498Szrj inline bool
equal(const htab_bb_copy_original_entry * data,const htab_bb_copy_original_entry * data2)983*38fd1498Szrj bb_copy_hasher::equal (const htab_bb_copy_original_entry *data,
984*38fd1498Szrj const htab_bb_copy_original_entry *data2)
985*38fd1498Szrj {
986*38fd1498Szrj return data->index1 == data2->index1;
987*38fd1498Szrj }
988*38fd1498Szrj
989*38fd1498Szrj /* Data structures used to maintain mapping between basic blocks and
990*38fd1498Szrj copies. */
991*38fd1498Szrj static hash_table<bb_copy_hasher> *bb_original;
992*38fd1498Szrj static hash_table<bb_copy_hasher> *bb_copy;
993*38fd1498Szrj
994*38fd1498Szrj /* And between loops and copies. */
995*38fd1498Szrj static hash_table<bb_copy_hasher> *loop_copy;
996*38fd1498Szrj static object_allocator<htab_bb_copy_original_entry> *original_copy_bb_pool;
997*38fd1498Szrj
998*38fd1498Szrj /* Initialize the data structures to maintain mapping between blocks
999*38fd1498Szrj and its copies. */
1000*38fd1498Szrj void
initialize_original_copy_tables(void)1001*38fd1498Szrj initialize_original_copy_tables (void)
1002*38fd1498Szrj {
1003*38fd1498Szrj original_copy_bb_pool = new object_allocator<htab_bb_copy_original_entry>
1004*38fd1498Szrj ("original_copy");
1005*38fd1498Szrj bb_original = new hash_table<bb_copy_hasher> (10);
1006*38fd1498Szrj bb_copy = new hash_table<bb_copy_hasher> (10);
1007*38fd1498Szrj loop_copy = new hash_table<bb_copy_hasher> (10);
1008*38fd1498Szrj }
1009*38fd1498Szrj
1010*38fd1498Szrj /* Reset the data structures to maintain mapping between blocks and
1011*38fd1498Szrj its copies. */
1012*38fd1498Szrj
1013*38fd1498Szrj void
reset_original_copy_tables(void)1014*38fd1498Szrj reset_original_copy_tables (void)
1015*38fd1498Szrj {
1016*38fd1498Szrj gcc_assert (original_copy_bb_pool);
1017*38fd1498Szrj bb_original->empty ();
1018*38fd1498Szrj bb_copy->empty ();
1019*38fd1498Szrj loop_copy->empty ();
1020*38fd1498Szrj }
1021*38fd1498Szrj
1022*38fd1498Szrj /* Free the data structures to maintain mapping between blocks and
1023*38fd1498Szrj its copies. */
1024*38fd1498Szrj void
free_original_copy_tables(void)1025*38fd1498Szrj free_original_copy_tables (void)
1026*38fd1498Szrj {
1027*38fd1498Szrj gcc_assert (original_copy_bb_pool);
1028*38fd1498Szrj delete bb_copy;
1029*38fd1498Szrj bb_copy = NULL;
1030*38fd1498Szrj delete bb_original;
1031*38fd1498Szrj bb_original = NULL;
1032*38fd1498Szrj delete loop_copy;
1033*38fd1498Szrj loop_copy = NULL;
1034*38fd1498Szrj delete original_copy_bb_pool;
1035*38fd1498Szrj original_copy_bb_pool = NULL;
1036*38fd1498Szrj }
1037*38fd1498Szrj
1038*38fd1498Szrj /* Return true iff we have had a call to initialize_original_copy_tables
1039*38fd1498Szrj without a corresponding call to free_original_copy_tables. */
1040*38fd1498Szrj
1041*38fd1498Szrj bool
original_copy_tables_initialized_p(void)1042*38fd1498Szrj original_copy_tables_initialized_p (void)
1043*38fd1498Szrj {
1044*38fd1498Szrj return original_copy_bb_pool != NULL;
1045*38fd1498Szrj }
1046*38fd1498Szrj
1047*38fd1498Szrj /* Removes the value associated with OBJ from table TAB. */
1048*38fd1498Szrj
1049*38fd1498Szrj static void
copy_original_table_clear(hash_table<bb_copy_hasher> * tab,unsigned obj)1050*38fd1498Szrj copy_original_table_clear (hash_table<bb_copy_hasher> *tab, unsigned obj)
1051*38fd1498Szrj {
1052*38fd1498Szrj htab_bb_copy_original_entry **slot;
1053*38fd1498Szrj struct htab_bb_copy_original_entry key, *elt;
1054*38fd1498Szrj
1055*38fd1498Szrj if (!original_copy_bb_pool)
1056*38fd1498Szrj return;
1057*38fd1498Szrj
1058*38fd1498Szrj key.index1 = obj;
1059*38fd1498Szrj slot = tab->find_slot (&key, NO_INSERT);
1060*38fd1498Szrj if (!slot)
1061*38fd1498Szrj return;
1062*38fd1498Szrj
1063*38fd1498Szrj elt = *slot;
1064*38fd1498Szrj tab->clear_slot (slot);
1065*38fd1498Szrj original_copy_bb_pool->remove (elt);
1066*38fd1498Szrj }
1067*38fd1498Szrj
1068*38fd1498Szrj /* Sets the value associated with OBJ in table TAB to VAL.
1069*38fd1498Szrj Do nothing when data structures are not initialized. */
1070*38fd1498Szrj
1071*38fd1498Szrj static void
copy_original_table_set(hash_table<bb_copy_hasher> * tab,unsigned obj,unsigned val)1072*38fd1498Szrj copy_original_table_set (hash_table<bb_copy_hasher> *tab,
1073*38fd1498Szrj unsigned obj, unsigned val)
1074*38fd1498Szrj {
1075*38fd1498Szrj struct htab_bb_copy_original_entry **slot;
1076*38fd1498Szrj struct htab_bb_copy_original_entry key;
1077*38fd1498Szrj
1078*38fd1498Szrj if (!original_copy_bb_pool)
1079*38fd1498Szrj return;
1080*38fd1498Szrj
1081*38fd1498Szrj key.index1 = obj;
1082*38fd1498Szrj slot = tab->find_slot (&key, INSERT);
1083*38fd1498Szrj if (!*slot)
1084*38fd1498Szrj {
1085*38fd1498Szrj *slot = original_copy_bb_pool->allocate ();
1086*38fd1498Szrj (*slot)->index1 = obj;
1087*38fd1498Szrj }
1088*38fd1498Szrj (*slot)->index2 = val;
1089*38fd1498Szrj }
1090*38fd1498Szrj
1091*38fd1498Szrj /* Set original for basic block. Do nothing when data structures are not
1092*38fd1498Szrj initialized so passes not needing this don't need to care. */
1093*38fd1498Szrj void
set_bb_original(basic_block bb,basic_block original)1094*38fd1498Szrj set_bb_original (basic_block bb, basic_block original)
1095*38fd1498Szrj {
1096*38fd1498Szrj copy_original_table_set (bb_original, bb->index, original->index);
1097*38fd1498Szrj }
1098*38fd1498Szrj
1099*38fd1498Szrj /* Get the original basic block. */
1100*38fd1498Szrj basic_block
get_bb_original(basic_block bb)1101*38fd1498Szrj get_bb_original (basic_block bb)
1102*38fd1498Szrj {
1103*38fd1498Szrj struct htab_bb_copy_original_entry *entry;
1104*38fd1498Szrj struct htab_bb_copy_original_entry key;
1105*38fd1498Szrj
1106*38fd1498Szrj gcc_assert (original_copy_bb_pool);
1107*38fd1498Szrj
1108*38fd1498Szrj key.index1 = bb->index;
1109*38fd1498Szrj entry = bb_original->find (&key);
1110*38fd1498Szrj if (entry)
1111*38fd1498Szrj return BASIC_BLOCK_FOR_FN (cfun, entry->index2);
1112*38fd1498Szrj else
1113*38fd1498Szrj return NULL;
1114*38fd1498Szrj }
1115*38fd1498Szrj
1116*38fd1498Szrj /* Set copy for basic block. Do nothing when data structures are not
1117*38fd1498Szrj initialized so passes not needing this don't need to care. */
1118*38fd1498Szrj void
set_bb_copy(basic_block bb,basic_block copy)1119*38fd1498Szrj set_bb_copy (basic_block bb, basic_block copy)
1120*38fd1498Szrj {
1121*38fd1498Szrj copy_original_table_set (bb_copy, bb->index, copy->index);
1122*38fd1498Szrj }
1123*38fd1498Szrj
1124*38fd1498Szrj /* Get the copy of basic block. */
1125*38fd1498Szrj basic_block
get_bb_copy(basic_block bb)1126*38fd1498Szrj get_bb_copy (basic_block bb)
1127*38fd1498Szrj {
1128*38fd1498Szrj struct htab_bb_copy_original_entry *entry;
1129*38fd1498Szrj struct htab_bb_copy_original_entry key;
1130*38fd1498Szrj
1131*38fd1498Szrj gcc_assert (original_copy_bb_pool);
1132*38fd1498Szrj
1133*38fd1498Szrj key.index1 = bb->index;
1134*38fd1498Szrj entry = bb_copy->find (&key);
1135*38fd1498Szrj if (entry)
1136*38fd1498Szrj return BASIC_BLOCK_FOR_FN (cfun, entry->index2);
1137*38fd1498Szrj else
1138*38fd1498Szrj return NULL;
1139*38fd1498Szrj }
1140*38fd1498Szrj
1141*38fd1498Szrj /* Set copy for LOOP to COPY. Do nothing when data structures are not
1142*38fd1498Szrj initialized so passes not needing this don't need to care. */
1143*38fd1498Szrj
1144*38fd1498Szrj void
set_loop_copy(struct loop * loop,struct loop * copy)1145*38fd1498Szrj set_loop_copy (struct loop *loop, struct loop *copy)
1146*38fd1498Szrj {
1147*38fd1498Szrj if (!copy)
1148*38fd1498Szrj copy_original_table_clear (loop_copy, loop->num);
1149*38fd1498Szrj else
1150*38fd1498Szrj copy_original_table_set (loop_copy, loop->num, copy->num);
1151*38fd1498Szrj }
1152*38fd1498Szrj
1153*38fd1498Szrj /* Get the copy of LOOP. */
1154*38fd1498Szrj
1155*38fd1498Szrj struct loop *
get_loop_copy(struct loop * loop)1156*38fd1498Szrj get_loop_copy (struct loop *loop)
1157*38fd1498Szrj {
1158*38fd1498Szrj struct htab_bb_copy_original_entry *entry;
1159*38fd1498Szrj struct htab_bb_copy_original_entry key;
1160*38fd1498Szrj
1161*38fd1498Szrj gcc_assert (original_copy_bb_pool);
1162*38fd1498Szrj
1163*38fd1498Szrj key.index1 = loop->num;
1164*38fd1498Szrj entry = loop_copy->find (&key);
1165*38fd1498Szrj if (entry)
1166*38fd1498Szrj return get_loop (cfun, entry->index2);
1167*38fd1498Szrj else
1168*38fd1498Szrj return NULL;
1169*38fd1498Szrj }
1170