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