xref: /dflybsd-src/contrib/gcc-8.0/gcc/cfg.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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