190075Sobrien/* Control flow graph manipulation code for GNU compiler.
290075Sobrien   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005
4169689Skan   Free Software Foundation, Inc.
590075Sobrien
690075SobrienThis file is part of GCC.
790075Sobrien
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1290075Sobrien
1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690075Sobrienfor more details.
1790075Sobrien
1890075SobrienYou should have received a copy of the GNU General Public License
1990075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169689Skan02110-1301, USA.  */
2290075Sobrien
2390075Sobrien/* This file contains low level functions to manipulate the CFG and
24132718Skan   analyze it.  All other modules should not transform the data structure
2590075Sobrien   directly and use abstraction instead.  The file is supposed to be
2690075Sobrien   ordered bottom-up and should not contain any code dependent on a
2790075Sobrien   particular intermediate language (RTL or trees).
2890075Sobrien
2990075Sobrien   Available functionality:
3090075Sobrien     - Initialization/deallocation
3190075Sobrien	 init_flow, clear_edges
3290075Sobrien     - Low level basic block manipulation
3390075Sobrien	 alloc_block, expunge_block
3490075Sobrien     - Edge manipulation
3590075Sobrien	 make_edge, make_single_succ_edge, cached_make_edge, remove_edge
3690075Sobrien	 - Low level edge redirection (without updating instruction chain)
3790075Sobrien	     redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
3890075Sobrien     - Dumping and debugging
3990075Sobrien	 dump_flow_info, debug_flow_info, dump_edge_info
4090075Sobrien     - Allocation of AUX fields for basic blocks
4190075Sobrien	 alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
42117395Skan     - clear_bb_flags
43132718Skan     - Consistency checking
44132718Skan	 verify_flow_info
45132718Skan     - Dumping and debugging
46132718Skan	 print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
4790075Sobrien */
4890075Sobrien
4990075Sobrien#include "config.h"
5090075Sobrien#include "system.h"
51132718Skan#include "coretypes.h"
52132718Skan#include "tm.h"
5390075Sobrien#include "tree.h"
5490075Sobrien#include "rtl.h"
5590075Sobrien#include "hard-reg-set.h"
5690075Sobrien#include "regs.h"
5790075Sobrien#include "flags.h"
5890075Sobrien#include "output.h"
5990075Sobrien#include "function.h"
6090075Sobrien#include "except.h"
6190075Sobrien#include "toplev.h"
6290075Sobrien#include "tm_p.h"
6390075Sobrien#include "obstack.h"
64169689Skan#include "timevar.h"
65169689Skan#include "tree-pass.h"
66169689Skan#include "ggc.h"
67169689Skan#include "hashtab.h"
68132718Skan#include "alloc-pool.h"
6990075Sobrien
7090075Sobrien/* The obstack on which the flow graph components are allocated.  */
7190075Sobrien
72169689Skanstruct bitmap_obstack reg_obstack;
7390075Sobrien
74132718Skanvoid debug_flow_info (void);
75132718Skanstatic void free_edge (edge);
7690075Sobrien
77169689Skan#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
78169689Skan
7990075Sobrien/* Called once at initialization time.  */
8090075Sobrien
8190075Sobrienvoid
82132718Skaninit_flow (void)
8390075Sobrien{
84169689Skan  if (!cfun->cfg)
85169689Skan    cfun->cfg = ggc_alloc_cleared (sizeof (struct control_flow_graph));
8690075Sobrien  n_edges = 0;
87169689Skan  ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (struct basic_block_def));
88169689Skan  ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
89169689Skan  EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (struct basic_block_def));
90169689Skan  EXIT_BLOCK_PTR->index = EXIT_BLOCK;
91169689Skan  ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
92169689Skan  EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
9390075Sobrien}
9490075Sobrien
9590075Sobrien/* Helper function for remove_edge and clear_edges.  Frees edge structure
9690075Sobrien   without actually unlinking it from the pred/succ lists.  */
9790075Sobrien
9890075Sobrienstatic void
99169689Skanfree_edge (edge e ATTRIBUTE_UNUSED)
10090075Sobrien{
10190075Sobrien  n_edges--;
102169689Skan  ggc_free (e);
10390075Sobrien}
10490075Sobrien
10590075Sobrien/* Free the memory associated with the edge structures.  */
10690075Sobrien
10790075Sobrienvoid
108132718Skanclear_edges (void)
10990075Sobrien{
110117395Skan  basic_block bb;
11190075Sobrien  edge e;
112169689Skan  edge_iterator ei;
11390075Sobrien
114117395Skan  FOR_EACH_BB (bb)
11590075Sobrien    {
116169689Skan      FOR_EACH_EDGE (e, ei, bb->succs)
117169689Skan	free_edge (e);
118169689Skan      VEC_truncate (edge, bb->succs, 0);
119169689Skan      VEC_truncate (edge, bb->preds, 0);
12090075Sobrien    }
12190075Sobrien
122169689Skan  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
123169689Skan    free_edge (e);
124169689Skan  VEC_truncate (edge, EXIT_BLOCK_PTR->preds, 0);
125169689Skan  VEC_truncate (edge, ENTRY_BLOCK_PTR->succs, 0);
12690075Sobrien
127169689Skan  gcc_assert (!n_edges);
12890075Sobrien}
12990075Sobrien
13090075Sobrien/* Allocate memory for basic_block.  */
13190075Sobrien
13290075Sobrienbasic_block
133132718Skanalloc_block (void)
13490075Sobrien{
13590075Sobrien  basic_block bb;
136169689Skan  bb = ggc_alloc_cleared (sizeof (*bb));
13790075Sobrien  return bb;
13890075Sobrien}
13990075Sobrien
140117395Skan/* Link block B to chain after AFTER.  */
141117395Skanvoid
142132718Skanlink_block (basic_block b, basic_block after)
143117395Skan{
144117395Skan  b->next_bb = after->next_bb;
145117395Skan  b->prev_bb = after;
146117395Skan  after->next_bb = b;
147117395Skan  b->next_bb->prev_bb = b;
148117395Skan}
14990075Sobrien
150117395Skan/* Unlink block B from chain.  */
15190075Sobrienvoid
152132718Skanunlink_block (basic_block b)
15396263Sobrien{
154117395Skan  b->next_bb->prev_bb = b->prev_bb;
155117395Skan  b->prev_bb->next_bb = b->next_bb;
156169689Skan  b->prev_bb = NULL;
157169689Skan  b->next_bb = NULL;
158117395Skan}
159117395Skan
160117395Skan/* Sequentially order blocks and compact the arrays.  */
161117395Skanvoid
162132718Skancompact_blocks (void)
163117395Skan{
164117395Skan  int i;
165117395Skan  basic_block bb;
166132718Skan
167169689Skan  SET_BASIC_BLOCK (ENTRY_BLOCK, ENTRY_BLOCK_PTR);
168169689Skan  SET_BASIC_BLOCK (EXIT_BLOCK, EXIT_BLOCK_PTR);
169169689Skan
170169689Skan  i = NUM_FIXED_BLOCKS;
171169689Skan  FOR_EACH_BB (bb)
172117395Skan    {
173169689Skan      SET_BASIC_BLOCK (i, bb);
174117395Skan      bb->index = i;
175117395Skan      i++;
176117395Skan    }
177117395Skan
178169689Skan  gcc_assert (i == n_basic_blocks);
179117395Skan
180169689Skan  for (; i < last_basic_block; i++)
181169689Skan    SET_BASIC_BLOCK (i, NULL);
182169689Skan
183117395Skan  last_basic_block = n_basic_blocks;
184117395Skan}
185117395Skan
186117395Skan/* Remove block B from the basic block array.  */
187117395Skan
188117395Skanvoid
189132718Skanexpunge_block (basic_block b)
190117395Skan{
191117395Skan  unlink_block (b);
192169689Skan  SET_BASIC_BLOCK (b->index, NULL);
193117395Skan  n_basic_blocks--;
194169689Skan  /* We should be able to ggc_free here, but we are not.
195169689Skan     The dead SSA_NAMES are left pointing to dead statements that are pointing
196169689Skan     to dead basic blocks making garbage collector to die.
197169689Skan     We should be able to release all dead SSA_NAMES and at the same time we should
198169689Skan     clear out BB pointer of dead statements consistently.  */
19996263Sobrien}
200117395Skan
201169689Skan/* Connect E to E->src.  */
202169689Skan
203169689Skanstatic inline void
204169689Skanconnect_src (edge e)
205169689Skan{
206169689Skan  VEC_safe_push (edge, gc, e->src->succs, e);
207169689Skan}
208169689Skan
209169689Skan/* Connect E to E->dest.  */
210169689Skan
211169689Skanstatic inline void
212169689Skanconnect_dest (edge e)
213169689Skan{
214169689Skan  basic_block dest = e->dest;
215169689Skan  VEC_safe_push (edge, gc, dest->preds, e);
216169689Skan  e->dest_idx = EDGE_COUNT (dest->preds) - 1;
217169689Skan}
218169689Skan
219169689Skan/* Disconnect edge E from E->src.  */
220169689Skan
221169689Skanstatic inline void
222169689Skandisconnect_src (edge e)
223169689Skan{
224169689Skan  basic_block src = e->src;
225169689Skan  edge_iterator ei;
226169689Skan  edge tmp;
227169689Skan
228169689Skan  for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
229169689Skan    {
230169689Skan      if (tmp == e)
231169689Skan	{
232169689Skan	  VEC_unordered_remove (edge, src->succs, ei.index);
233169689Skan	  return;
234169689Skan	}
235169689Skan      else
236169689Skan	ei_next (&ei);
237169689Skan    }
238169689Skan
239169689Skan  gcc_unreachable ();
240169689Skan}
241169689Skan
242169689Skan/* Disconnect edge E from E->dest.  */
243169689Skan
244169689Skanstatic inline void
245169689Skandisconnect_dest (edge e)
246169689Skan{
247169689Skan  basic_block dest = e->dest;
248169689Skan  unsigned int dest_idx = e->dest_idx;
249169689Skan
250169689Skan  VEC_unordered_remove (edge, dest->preds, dest_idx);
251169689Skan
252169689Skan  /* If we removed an edge in the middle of the edge vector, we need
253169689Skan     to update dest_idx of the edge that moved into the "hole".  */
254169689Skan  if (dest_idx < EDGE_COUNT (dest->preds))
255169689Skan    EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
256169689Skan}
257169689Skan
258117395Skan/* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
259117395Skan   created edge.  Use this only if you are sure that this edge can't
260117395Skan   possibly already exist.  */
26196263Sobrien
262117395Skanedge
263132718Skanunchecked_make_edge (basic_block src, basic_block dst, int flags)
26490075Sobrien{
265117395Skan  edge e;
266169689Skan  e = ggc_alloc_cleared (sizeof (*e));
267117395Skan  n_edges++;
26890075Sobrien
269117395Skan  e->src = src;
270117395Skan  e->dest = dst;
271117395Skan  e->flags = flags;
27296263Sobrien
273169689Skan  connect_src (e);
274169689Skan  connect_dest (e);
275117395Skan
276169689Skan  execute_on_growing_pred (e);
277169689Skan
278117395Skan  return e;
27990075Sobrien}
280132718Skan
28190075Sobrien/* Create an edge connecting SRC and DST with FLAGS optionally using
28290075Sobrien   edge cache CACHE.  Return the new edge, NULL if already exist.  */
28390075Sobrien
28490075Sobrienedge
285169689Skancached_make_edge (sbitmap edge_cache, basic_block src, basic_block dst, int flags)
28690075Sobrien{
287169689Skan  if (edge_cache == NULL
288169689Skan      || src == ENTRY_BLOCK_PTR
289169689Skan      || dst == EXIT_BLOCK_PTR)
290169689Skan    return make_edge (src, dst, flags);
29190075Sobrien
292169689Skan  /* Does the requested edge already exist?  */
293169689Skan  if (! TEST_BIT (edge_cache, dst->index))
294169689Skan    {
295169689Skan      /* The edge does not exist.  Create one and update the
296169689Skan	 cache.  */
297169689Skan      SET_BIT (edge_cache, dst->index);
298169689Skan      return unchecked_make_edge (src, dst, flags);
299169689Skan    }
30090075Sobrien
301169689Skan  /* At this point, we know that the requested edge exists.  Adjust
302169689Skan     flags if necessary.  */
303169689Skan  if (flags)
30490075Sobrien    {
305169689Skan      edge e = find_edge (src, dst);
306169689Skan      e->flags |= flags;
30790075Sobrien    }
30890075Sobrien
309169689Skan  return NULL;
31090075Sobrien}
31190075Sobrien
31290075Sobrien/* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
31390075Sobrien   created edge or NULL if already exist.  */
31490075Sobrien
31590075Sobrienedge
316132718Skanmake_edge (basic_block src, basic_block dest, int flags)
31790075Sobrien{
318169689Skan  edge e = find_edge (src, dest);
319169689Skan
320169689Skan  /* Make sure we don't add duplicate edges.  */
321169689Skan  if (e)
322169689Skan    {
323169689Skan      e->flags |= flags;
324169689Skan      return NULL;
325169689Skan    }
326169689Skan
327169689Skan  return unchecked_make_edge (src, dest, flags);
32890075Sobrien}
32990075Sobrien
33090075Sobrien/* Create an edge connecting SRC to DEST and set probability by knowing
33190075Sobrien   that it is the single edge leaving SRC.  */
33290075Sobrien
33390075Sobrienedge
334132718Skanmake_single_succ_edge (basic_block src, basic_block dest, int flags)
33590075Sobrien{
33690075Sobrien  edge e = make_edge (src, dest, flags);
33790075Sobrien
33890075Sobrien  e->probability = REG_BR_PROB_BASE;
33990075Sobrien  e->count = src->count;
34090075Sobrien  return e;
34190075Sobrien}
34290075Sobrien
34390075Sobrien/* This function will remove an edge from the flow graph.  */
34490075Sobrien
34590075Sobrienvoid
346132718Skanremove_edge (edge e)
34790075Sobrien{
348169689Skan  remove_predictions_associated_with_edge (e);
349169689Skan  execute_on_shrinking_pred (e);
35090075Sobrien
351169689Skan  disconnect_src (e);
352169689Skan  disconnect_dest (e);
35390075Sobrien
35490075Sobrien  free_edge (e);
35590075Sobrien}
35690075Sobrien
35790075Sobrien/* Redirect an edge's successor from one block to another.  */
35890075Sobrien
35990075Sobrienvoid
360132718Skanredirect_edge_succ (edge e, basic_block new_succ)
36190075Sobrien{
362169689Skan  execute_on_shrinking_pred (e);
36390075Sobrien
364169689Skan  disconnect_dest (e);
36590075Sobrien
366169689Skan  e->dest = new_succ;
367169689Skan
36890075Sobrien  /* Reconnect the edge to the new successor block.  */
369169689Skan  connect_dest (e);
370169689Skan
371169689Skan  execute_on_growing_pred (e);
37290075Sobrien}
37390075Sobrien
37490075Sobrien/* Like previous but avoid possible duplicate edge.  */
37590075Sobrien
37690075Sobrienedge
377132718Skanredirect_edge_succ_nodup (edge e, basic_block new_succ)
37890075Sobrien{
37990075Sobrien  edge s;
38090075Sobrien
381169689Skan  s = find_edge (e->src, new_succ);
382169689Skan  if (s && s != e)
38390075Sobrien    {
38490075Sobrien      s->flags |= e->flags;
38590075Sobrien      s->probability += e->probability;
386117395Skan      if (s->probability > REG_BR_PROB_BASE)
387117395Skan	s->probability = REG_BR_PROB_BASE;
38890075Sobrien      s->count += e->count;
38990075Sobrien      remove_edge (e);
39090075Sobrien      e = s;
39190075Sobrien    }
39290075Sobrien  else
39390075Sobrien    redirect_edge_succ (e, new_succ);
39490075Sobrien
39590075Sobrien  return e;
39690075Sobrien}
39790075Sobrien
39890075Sobrien/* Redirect an edge's predecessor from one block to another.  */
39990075Sobrien
40090075Sobrienvoid
401132718Skanredirect_edge_pred (edge e, basic_block new_pred)
40290075Sobrien{
403169689Skan  disconnect_src (e);
40490075Sobrien
405169689Skan  e->src = new_pred;
40690075Sobrien
40790075Sobrien  /* Reconnect the edge to the new predecessor block.  */
408169689Skan  connect_src (e);
40990075Sobrien}
410117395Skan
411169689Skan/* Clear all basic block flags, with the exception of partitioning.  */
412117395Skanvoid
413132718Skanclear_bb_flags (void)
414117395Skan{
415117395Skan  basic_block bb;
416117395Skan
417117395Skan  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
418169689Skan    bb->flags = (BB_PARTITION (bb)  | (bb->flags & BB_DISABLE_SCHEDULE)
419169689Skan		 | (bb->flags & BB_RTL));
420117395Skan}
42190075Sobrien
422169689Skan/* Check the consistency of profile information.  We can't do that
423169689Skan   in verify_flow_info, as the counts may get invalid for incompletely
424169689Skan   solved graphs, later eliminating of conditionals or roundoff errors.
425169689Skan   It is still practical to have them reported for debugging of simple
426169689Skan   testcases.  */
42790075Sobrienvoid
428169689Skancheck_bb_profile (basic_block bb, FILE * file)
42990075Sobrien{
430169689Skan  edge e;
431169689Skan  int sum = 0;
432169689Skan  gcov_type lsum;
433169689Skan  edge_iterator ei;
43490075Sobrien
435169689Skan  if (profile_status == PROFILE_ABSENT)
436169689Skan    return;
43790075Sobrien
438169689Skan  if (bb != EXIT_BLOCK_PTR)
439169689Skan    {
440169689Skan      FOR_EACH_EDGE (e, ei, bb->succs)
441169689Skan	sum += e->probability;
442169689Skan      if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
443169689Skan	fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
444169689Skan		 sum * 100.0 / REG_BR_PROB_BASE);
445169689Skan      lsum = 0;
446169689Skan      FOR_EACH_EDGE (e, ei, bb->succs)
447169689Skan	lsum += e->count;
448169689Skan      if (EDGE_COUNT (bb->succs)
449169689Skan	  && (lsum - bb->count > 100 || lsum - bb->count < -100))
450169689Skan	fprintf (file, "Invalid sum of outgoing counts %i, should be %i\n",
451169689Skan		 (int) lsum, (int) bb->count);
452169689Skan    }
453169689Skan  if (bb != ENTRY_BLOCK_PTR)
454169689Skan    {
455169689Skan      sum = 0;
456169689Skan      FOR_EACH_EDGE (e, ei, bb->preds)
457169689Skan	sum += EDGE_FREQUENCY (e);
458169689Skan      if (abs (sum - bb->frequency) > 100)
459169689Skan	fprintf (file,
460169689Skan		 "Invalid sum of incoming frequencies %i, should be %i\n",
461169689Skan		 sum, bb->frequency);
462169689Skan      lsum = 0;
463169689Skan      FOR_EACH_EDGE (e, ei, bb->preds)
464169689Skan	lsum += e->count;
465169689Skan      if (lsum - bb->count > 100 || lsum - bb->count < -100)
466169689Skan	fprintf (file, "Invalid sum of incoming counts %i, should be %i\n",
467169689Skan		 (int) lsum, (int) bb->count);
468169689Skan    }
469169689Skan}
470169689Skan
471169689Skan/* Emit basic block information for BB.  HEADER is true if the user wants
472169689Skan   the generic information and the predecessors, FOOTER is true if they want
473169689Skan   the successors.  FLAGS is the dump flags of interest; TDF_DETAILS emit
474169689Skan   global register liveness information.  PREFIX is put in front of every
475169689Skan   line.  The output is emitted to FILE.  */
476169689Skanvoid
477169689Skandump_bb_info (basic_block bb, bool header, bool footer, int flags,
478169689Skan	      const char *prefix, FILE *file)
479169689Skan{
480169689Skan  edge e;
481169689Skan  edge_iterator ei;
48290075Sobrien
483169689Skan  if (header)
48490075Sobrien    {
485169689Skan      fprintf (file, "\n%sBasic block %d ", prefix, bb->index);
486169689Skan      if (bb->prev_bb)
487169689Skan        fprintf (file, ", prev %d", bb->prev_bb->index);
488169689Skan      if (bb->next_bb)
489169689Skan        fprintf (file, ", next %d", bb->next_bb->index);
490169689Skan      fprintf (file, ", loop_depth %d, count ", bb->loop_depth);
49190075Sobrien      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
492117395Skan      fprintf (file, ", freq %i", bb->frequency);
493117395Skan      if (maybe_hot_bb_p (bb))
494117395Skan	fprintf (file, ", maybe hot");
495117395Skan      if (probably_never_executed_bb_p (bb))
496117395Skan	fprintf (file, ", probably never executed");
497117395Skan      fprintf (file, ".\n");
49890075Sobrien
499169689Skan      fprintf (file, "%sPredecessors: ", prefix);
500169689Skan      FOR_EACH_EDGE (e, ei, bb->preds)
50190075Sobrien	dump_edge_info (file, e, 0);
502169689Skan   }
50390075Sobrien
504169689Skan  if (footer)
505169689Skan    {
506169689Skan      fprintf (file, "\n%sSuccessors: ", prefix);
507169689Skan      FOR_EACH_EDGE (e, ei, bb->succs)
50890075Sobrien	dump_edge_info (file, e, 1);
509169689Skan   }
51090075Sobrien
511169689Skan  if ((flags & TDF_DETAILS)
512169689Skan      && (bb->flags & BB_RTL))
513169689Skan    {
514169689Skan      if (bb->il.rtl->global_live_at_start && header)
515169689Skan	{
516169689Skan	  fprintf (file, "\n%sRegisters live at start:", prefix);
517169689Skan	  dump_regset (bb->il.rtl->global_live_at_start, file);
518169689Skan	}
51990075Sobrien
520169689Skan      if (bb->il.rtl->global_live_at_end && footer)
521169689Skan	{
522169689Skan	  fprintf (file, "\n%sRegisters live at end:", prefix);
523169689Skan	  dump_regset (bb->il.rtl->global_live_at_end, file);
524169689Skan	}
525169689Skan   }
52690075Sobrien
527169689Skan  putc ('\n', file);
528169689Skan}
529117395Skan
530169689Skanvoid
531169689Skandump_flow_info (FILE *file, int flags)
532169689Skan{
533169689Skan  basic_block bb;
534169689Skan
535169689Skan  /* There are no pseudo registers after reload.  Don't dump them.  */
536169689Skan  if (reg_n_info && !reload_completed
537169689Skan      && (flags & TDF_DETAILS) != 0)
538169689Skan    {
539169689Skan      unsigned int i, max = max_reg_num ();
540169689Skan      fprintf (file, "%d registers.\n", max);
541169689Skan      for (i = FIRST_PSEUDO_REGISTER; i < max; i++)
542169689Skan	if (REG_N_REFS (i))
543169689Skan	  {
544169689Skan	    enum reg_class class, altclass;
545169689Skan
546169689Skan	    fprintf (file, "\nRegister %d used %d times across %d insns",
547169689Skan		     i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
548169689Skan	    if (REG_BASIC_BLOCK (i) >= 0)
549169689Skan	      fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
550169689Skan	    if (REG_N_SETS (i))
551169689Skan	      fprintf (file, "; set %d time%s", REG_N_SETS (i),
552169689Skan		       (REG_N_SETS (i) == 1) ? "" : "s");
553169689Skan	    if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
554169689Skan	      fprintf (file, "; user var");
555169689Skan	    if (REG_N_DEATHS (i) != 1)
556169689Skan	      fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
557169689Skan	    if (REG_N_CALLS_CROSSED (i) == 1)
558169689Skan	      fprintf (file, "; crosses 1 call");
559169689Skan	    else if (REG_N_CALLS_CROSSED (i))
560169689Skan	      fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
561169689Skan	    if (regno_reg_rtx[i] != NULL
562169689Skan		&& PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
563169689Skan	      fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
564169689Skan
565169689Skan	    class = reg_preferred_class (i);
566169689Skan	    altclass = reg_alternate_class (i);
567169689Skan	    if (class != GENERAL_REGS || altclass != ALL_REGS)
568169689Skan	      {
569169689Skan		if (altclass == ALL_REGS || class == ALL_REGS)
570169689Skan		  fprintf (file, "; pref %s", reg_class_names[(int) class]);
571169689Skan		else if (altclass == NO_REGS)
572169689Skan		  fprintf (file, "; %s or none", reg_class_names[(int) class]);
573169689Skan		else
574169689Skan		  fprintf (file, "; pref %s, else %s",
575169689Skan			   reg_class_names[(int) class],
576169689Skan			   reg_class_names[(int) altclass]);
577169689Skan	      }
578169689Skan
579169689Skan	    if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
580169689Skan	      fprintf (file, "; pointer");
581169689Skan	    fprintf (file, ".\n");
582169689Skan	  }
58390075Sobrien    }
58490075Sobrien
585169689Skan  fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
586169689Skan  FOR_EACH_BB (bb)
587169689Skan    {
588169689Skan      dump_bb_info (bb, true, true, flags, "", file);
589169689Skan      check_bb_profile (bb, file);
590169689Skan    }
591169689Skan
59290075Sobrien  putc ('\n', file);
59390075Sobrien}
59490075Sobrien
59590075Sobrienvoid
596132718Skandebug_flow_info (void)
59790075Sobrien{
598169689Skan  dump_flow_info (stderr, TDF_DETAILS);
59990075Sobrien}
60090075Sobrien
60190075Sobrienvoid
602132718Skandump_edge_info (FILE *file, edge e, int do_succ)
60390075Sobrien{
60490075Sobrien  basic_block side = (do_succ ? e->dest : e->src);
60590075Sobrien
60690075Sobrien  if (side == ENTRY_BLOCK_PTR)
60790075Sobrien    fputs (" ENTRY", file);
60890075Sobrien  else if (side == EXIT_BLOCK_PTR)
60990075Sobrien    fputs (" EXIT", file);
61090075Sobrien  else
61190075Sobrien    fprintf (file, " %d", side->index);
61290075Sobrien
61390075Sobrien  if (e->probability)
61490075Sobrien    fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
61590075Sobrien
61690075Sobrien  if (e->count)
61790075Sobrien    {
61890075Sobrien      fprintf (file, " count:");
61990075Sobrien      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
62090075Sobrien    }
62190075Sobrien
62290075Sobrien  if (e->flags)
62390075Sobrien    {
624132718Skan      static const char * const bitnames[] = {
625132718Skan	"fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
626169689Skan	"can_fallthru", "irreducible", "sibcall", "loop_exit",
627169689Skan	"true", "false", "exec"
628132718Skan      };
62990075Sobrien      int comma = 0;
63090075Sobrien      int i, flags = e->flags;
63190075Sobrien
63290075Sobrien      fputs (" (", file);
63390075Sobrien      for (i = 0; flags; i++)
63490075Sobrien	if (flags & (1 << i))
63590075Sobrien	  {
63690075Sobrien	    flags &= ~(1 << i);
63790075Sobrien
63890075Sobrien	    if (comma)
63990075Sobrien	      fputc (',', file);
64090075Sobrien	    if (i < (int) ARRAY_SIZE (bitnames))
64190075Sobrien	      fputs (bitnames[i], file);
64290075Sobrien	    else
64390075Sobrien	      fprintf (file, "%d", i);
64490075Sobrien	    comma = 1;
64590075Sobrien	  }
64690075Sobrien
64790075Sobrien      fputc (')', file);
64890075Sobrien    }
64990075Sobrien}
65090075Sobrien
65190075Sobrien/* Simple routines to easily allocate AUX fields of basic blocks.  */
65290075Sobrien
65390075Sobrienstatic struct obstack block_aux_obstack;
65490075Sobrienstatic void *first_block_aux_obj = 0;
65590075Sobrienstatic struct obstack edge_aux_obstack;
65690075Sobrienstatic void *first_edge_aux_obj = 0;
65790075Sobrien
658117395Skan/* Allocate a memory block of SIZE as BB->aux.  The obstack must
65990075Sobrien   be first initialized by alloc_aux_for_blocks.  */
66090075Sobrien
66190075Sobrieninline void
662132718Skanalloc_aux_for_block (basic_block bb, int size)
66390075Sobrien{
66490075Sobrien  /* Verify that aux field is clear.  */
665169689Skan  gcc_assert (!bb->aux && first_block_aux_obj);
66690075Sobrien  bb->aux = obstack_alloc (&block_aux_obstack, size);
66790075Sobrien  memset (bb->aux, 0, size);
66890075Sobrien}
66990075Sobrien
67090075Sobrien/* Initialize the block_aux_obstack and if SIZE is nonzero, call
67190075Sobrien   alloc_aux_for_block for each basic block.  */
67290075Sobrien
67390075Sobrienvoid
674132718Skanalloc_aux_for_blocks (int size)
67590075Sobrien{
67690075Sobrien  static int initialized;
67790075Sobrien
67890075Sobrien  if (!initialized)
67990075Sobrien    {
68090075Sobrien      gcc_obstack_init (&block_aux_obstack);
68190075Sobrien      initialized = 1;
68290075Sobrien    }
683169689Skan  else
684169689Skan    /* Check whether AUX data are still allocated.  */
685169689Skan    gcc_assert (!first_block_aux_obj);
68690075Sobrien
687132718Skan  first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
68890075Sobrien  if (size)
68990075Sobrien    {
690117395Skan      basic_block bb;
69190075Sobrien
692117395Skan      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
693117395Skan	alloc_aux_for_block (bb, size);
69490075Sobrien    }
69590075Sobrien}
69690075Sobrien
69790075Sobrien/* Clear AUX pointers of all blocks.  */
69890075Sobrien
69990075Sobrienvoid
700132718Skanclear_aux_for_blocks (void)
70190075Sobrien{
702117395Skan  basic_block bb;
70390075Sobrien
704117395Skan  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
705117395Skan    bb->aux = NULL;
70690075Sobrien}
70790075Sobrien
70890075Sobrien/* Free data allocated in block_aux_obstack and clear AUX pointers
70990075Sobrien   of all blocks.  */
71090075Sobrien
71190075Sobrienvoid
712132718Skanfree_aux_for_blocks (void)
71390075Sobrien{
714169689Skan  gcc_assert (first_block_aux_obj);
71590075Sobrien  obstack_free (&block_aux_obstack, first_block_aux_obj);
71690075Sobrien  first_block_aux_obj = NULL;
71790075Sobrien
71890075Sobrien  clear_aux_for_blocks ();
71990075Sobrien}
72090075Sobrien
721117395Skan/* Allocate a memory edge of SIZE as BB->aux.  The obstack must
72290075Sobrien   be first initialized by alloc_aux_for_edges.  */
72390075Sobrien
72490075Sobrieninline void
725132718Skanalloc_aux_for_edge (edge e, int size)
72690075Sobrien{
72790075Sobrien  /* Verify that aux field is clear.  */
728169689Skan  gcc_assert (!e->aux && first_edge_aux_obj);
72990075Sobrien  e->aux = obstack_alloc (&edge_aux_obstack, size);
73090075Sobrien  memset (e->aux, 0, size);
73190075Sobrien}
73290075Sobrien
73390075Sobrien/* Initialize the edge_aux_obstack and if SIZE is nonzero, call
73490075Sobrien   alloc_aux_for_edge for each basic edge.  */
73590075Sobrien
73690075Sobrienvoid
737132718Skanalloc_aux_for_edges (int size)
73890075Sobrien{
73990075Sobrien  static int initialized;
74090075Sobrien
74190075Sobrien  if (!initialized)
74290075Sobrien    {
74390075Sobrien      gcc_obstack_init (&edge_aux_obstack);
74490075Sobrien      initialized = 1;
74590075Sobrien    }
746169689Skan  else
747169689Skan    /* Check whether AUX data are still allocated.  */
748169689Skan    gcc_assert (!first_edge_aux_obj);
74990075Sobrien
750132718Skan  first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
75190075Sobrien  if (size)
75290075Sobrien    {
753117395Skan      basic_block bb;
754117395Skan
755117395Skan      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
75690075Sobrien	{
75790075Sobrien	  edge e;
758169689Skan	  edge_iterator ei;
75990075Sobrien
760169689Skan	  FOR_EACH_EDGE (e, ei, bb->succs)
76190075Sobrien	    alloc_aux_for_edge (e, size);
76290075Sobrien	}
76390075Sobrien    }
76490075Sobrien}
76590075Sobrien
76690075Sobrien/* Clear AUX pointers of all edges.  */
76790075Sobrien
76890075Sobrienvoid
769132718Skanclear_aux_for_edges (void)
77090075Sobrien{
771117395Skan  basic_block bb;
772117395Skan  edge e;
77390075Sobrien
774117395Skan  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
77590075Sobrien    {
776169689Skan      edge_iterator ei;
777169689Skan      FOR_EACH_EDGE (e, ei, bb->succs)
77890075Sobrien	e->aux = NULL;
77990075Sobrien    }
78090075Sobrien}
78190075Sobrien
78290075Sobrien/* Free data allocated in edge_aux_obstack and clear AUX pointers
78390075Sobrien   of all edges.  */
78490075Sobrien
78590075Sobrienvoid
786132718Skanfree_aux_for_edges (void)
78790075Sobrien{
788169689Skan  gcc_assert (first_edge_aux_obj);
78990075Sobrien  obstack_free (&edge_aux_obstack, first_edge_aux_obj);
79090075Sobrien  first_edge_aux_obj = NULL;
79190075Sobrien
79290075Sobrien  clear_aux_for_edges ();
79390075Sobrien}
794132718Skan
795132718Skanvoid
796169689Skandebug_bb (basic_block bb)
797132718Skan{
798169689Skan  dump_bb (bb, stderr, 0);
799169689Skan}
800132718Skan
801169689Skanbasic_block
802169689Skandebug_bb_n (int n)
803169689Skan{
804169689Skan  basic_block bb = BASIC_BLOCK (n);
805169689Skan  dump_bb (bb, stderr, 0);
806169689Skan  return bb;
807169689Skan}
808132718Skan
809169689Skan/* Dumps cfg related information about basic block BB to FILE.  */
810169689Skan
811169689Skanstatic void
812169689Skandump_cfg_bb_info (FILE *file, basic_block bb)
813169689Skan{
814169689Skan  unsigned i;
815169689Skan  edge_iterator ei;
816169689Skan  bool first = true;
817169689Skan  static const char * const bb_bitnames[] =
818132718Skan    {
819169689Skan      "dirty", "new", "reachable", "visited", "irreducible_loop", "superblock"
820169689Skan    };
821169689Skan  const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *);
822169689Skan  edge e;
823132718Skan
824169689Skan  fprintf (file, "Basic block %d", bb->index);
825169689Skan  for (i = 0; i < n_bitnames; i++)
826169689Skan    if (bb->flags & (1 << i))
827169689Skan      {
828169689Skan	if (first)
829169689Skan	  fprintf (file, " (");
830169689Skan	else
831169689Skan	  fprintf (file, ", ");
832169689Skan	first = false;
833260012Spfg	fprintf (file, "%s", bb_bitnames[i]);
834169689Skan      }
835169689Skan  if (!first)
836169689Skan    fprintf (file, ")");
837169689Skan  fprintf (file, "\n");
838132718Skan
839169689Skan  fprintf (file, "Predecessors: ");
840169689Skan  FOR_EACH_EDGE (e, ei, bb->preds)
841169689Skan    dump_edge_info (file, e, 0);
842132718Skan
843169689Skan  fprintf (file, "\nSuccessors: ");
844169689Skan  FOR_EACH_EDGE (e, ei, bb->succs)
845169689Skan    dump_edge_info (file, e, 1);
846169689Skan  fprintf (file, "\n\n");
847169689Skan}
848169689Skan
849169689Skan/* Dumps a brief description of cfg to FILE.  */
850169689Skan
851169689Skanvoid
852169689Skanbrief_dump_cfg (FILE *file)
853169689Skan{
854169689Skan  basic_block bb;
855169689Skan
856169689Skan  FOR_EACH_BB (bb)
857132718Skan    {
858169689Skan      dump_cfg_bb_info (file, bb);
859169689Skan    }
860169689Skan}
861132718Skan
862169689Skan/* An edge originally destinating BB of FREQUENCY and COUNT has been proved to
863169689Skan   leave the block by TAKEN_EDGE.  Update profile of BB such that edge E can be
864169689Skan   redirected to destination of TAKEN_EDGE.
865132718Skan
866169689Skan   This function may leave the profile inconsistent in the case TAKEN_EDGE
867169689Skan   frequency or count is believed to be lower than FREQUENCY or COUNT
868169689Skan   respectively.  */
869169689Skanvoid
870169689Skanupdate_bb_profile_for_threading (basic_block bb, int edge_frequency,
871169689Skan				 gcov_type count, edge taken_edge)
872169689Skan{
873169689Skan  edge c;
874169689Skan  int prob;
875169689Skan  edge_iterator ei;
876132718Skan
877169689Skan  bb->count -= count;
878169689Skan  if (bb->count < 0)
879169689Skan    {
880169689Skan      if (dump_file)
881169689Skan	fprintf (dump_file, "bb %i count became negative after threading",
882169689Skan		 bb->index);
883169689Skan      bb->count = 0;
884169689Skan    }
885132718Skan
886169689Skan  /* Compute the probability of TAKEN_EDGE being reached via threaded edge.
887169689Skan     Watch for overflows.  */
888169689Skan  if (bb->frequency)
889169689Skan    prob = edge_frequency * REG_BR_PROB_BASE / bb->frequency;
890169689Skan  else
891169689Skan    prob = 0;
892169689Skan  if (prob > taken_edge->probability)
893169689Skan    {
894169689Skan      if (dump_file)
895169689Skan	fprintf (dump_file, "Jump threading proved probability of edge "
896169689Skan		 "%i->%i too small (it is %i, should be %i).\n",
897169689Skan		 taken_edge->src->index, taken_edge->dest->index,
898169689Skan		 taken_edge->probability, prob);
899169689Skan      prob = taken_edge->probability;
900169689Skan    }
901132718Skan
902169689Skan  /* Now rescale the probabilities.  */
903169689Skan  taken_edge->probability -= prob;
904169689Skan  prob = REG_BR_PROB_BASE - prob;
905169689Skan  bb->frequency -= edge_frequency;
906169689Skan  if (bb->frequency < 0)
907169689Skan    bb->frequency = 0;
908169689Skan  if (prob <= 0)
909169689Skan    {
910169689Skan      if (dump_file)
911169689Skan	fprintf (dump_file, "Edge frequencies of bb %i has been reset, "
912169689Skan		 "frequency of block should end up being 0, it is %i\n",
913169689Skan		 bb->index, bb->frequency);
914169689Skan      EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
915169689Skan      ei = ei_start (bb->succs);
916169689Skan      ei_next (&ei);
917169689Skan      for (; (c = ei_safe_edge (ei)); ei_next (&ei))
918169689Skan	c->probability = 0;
919169689Skan    }
920169689Skan  else if (prob != REG_BR_PROB_BASE)
921169689Skan    {
922169689Skan      int scale = RDIV (65536 * REG_BR_PROB_BASE, prob);
923132718Skan
924169689Skan      FOR_EACH_EDGE (c, ei, bb->succs)
925132718Skan	{
926169689Skan	  c->probability = RDIV (c->probability * scale, 65536);
927169689Skan	  if (c->probability > REG_BR_PROB_BASE)
928169689Skan	    c->probability = REG_BR_PROB_BASE;
929132718Skan	}
930132718Skan    }
931132718Skan
932169689Skan  gcc_assert (bb == taken_edge->src);
933169689Skan  taken_edge->count -= count;
934169689Skan  if (taken_edge->count < 0)
935169689Skan    {
936169689Skan      if (dump_file)
937169689Skan	fprintf (dump_file, "edge %i->%i count became negative after threading",
938169689Skan		 taken_edge->src->index, taken_edge->dest->index);
939169689Skan      taken_edge->count = 0;
940169689Skan    }
941169689Skan}
942132718Skan
943169689Skan/* Multiply all frequencies of basic blocks in array BBS of length NBBS
944169689Skan   by NUM/DEN, in int arithmetic.  May lose some accuracy.  */
945169689Skanvoid
946169689Skanscale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den)
947169689Skan{
948169689Skan  int i;
949169689Skan  edge e;
950169689Skan  if (num < 0)
951169689Skan    num = 0;
952169689Skan  if (num > den)
953169689Skan    return;
954169689Skan  /* Assume that the users are producing the fraction from frequencies
955169689Skan     that never grow far enough to risk arithmetic overflow.  */
956169689Skan  gcc_assert (num < 65536);
957169689Skan  for (i = 0; i < nbbs; i++)
958169689Skan    {
959169689Skan      edge_iterator ei;
960169689Skan      bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
961169689Skan      bbs[i]->count = RDIV (bbs[i]->count * num, den);
962169689Skan      FOR_EACH_EDGE (e, ei, bbs[i]->succs)
963169689Skan	e->count = RDIV (e->count * num, den);
964169689Skan    }
965169689Skan}
966132718Skan
967169689Skan/* numbers smaller than this value are safe to multiply without getting
968169689Skan   64bit overflow.  */
969169689Skan#define MAX_SAFE_MULTIPLIER (1 << (sizeof (HOST_WIDEST_INT) * 4 - 1))
970132718Skan
971169689Skan/* Multiply all frequencies of basic blocks in array BBS of length NBBS
972169689Skan   by NUM/DEN, in gcov_type arithmetic.  More accurate than previous
973169689Skan   function but considerably slower.  */
974169689Skanvoid
975169689Skanscale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num,
976169689Skan				 gcov_type den)
977169689Skan{
978169689Skan  int i;
979169689Skan  edge e;
980169689Skan  gcov_type fraction = RDIV (num * 65536, den);
981169689Skan
982169689Skan  gcc_assert (fraction >= 0);
983169689Skan
984169689Skan  if (num < MAX_SAFE_MULTIPLIER)
985169689Skan    for (i = 0; i < nbbs; i++)
986132718Skan      {
987169689Skan	edge_iterator ei;
988169689Skan	bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
989169689Skan	if (bbs[i]->count <= MAX_SAFE_MULTIPLIER)
990169689Skan	  bbs[i]->count = RDIV (bbs[i]->count * num, den);
991169689Skan	else
992169689Skan	  bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536);
993169689Skan	FOR_EACH_EDGE (e, ei, bbs[i]->succs)
994169689Skan	  if (bbs[i]->count <= MAX_SAFE_MULTIPLIER)
995169689Skan	    e->count = RDIV (e->count * num, den);
996169689Skan	  else
997169689Skan	    e->count = RDIV (e->count * fraction, 65536);
998132718Skan      }
999169689Skan   else
1000169689Skan    for (i = 0; i < nbbs; i++)
1001169689Skan      {
1002169689Skan	edge_iterator ei;
1003169689Skan	if (sizeof (gcov_type) > sizeof (int))
1004169689Skan	  bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
1005169689Skan	else
1006169689Skan	  bbs[i]->frequency = RDIV (bbs[i]->frequency * fraction, 65536);
1007169689Skan	bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536);
1008169689Skan	FOR_EACH_EDGE (e, ei, bbs[i]->succs)
1009169689Skan	  e->count = RDIV (e->count * fraction, 65536);
1010169689Skan      }
1011169689Skan}
1012132718Skan
1013169689Skan/* Data structures used to maintain mapping between basic blocks and
1014169689Skan   copies.  */
1015169689Skanstatic htab_t bb_original;
1016169689Skanstatic htab_t bb_copy;
1017169689Skanstatic alloc_pool original_copy_bb_pool;
1018132718Skan
1019169689Skanstruct htab_bb_copy_original_entry
1020169689Skan{
1021169689Skan  /* Block we are attaching info to.  */
1022169689Skan  int index1;
1023169689Skan  /* Index of original or copy (depending on the hashtable) */
1024169689Skan  int index2;
1025169689Skan};
1026169689Skan
1027169689Skanstatic hashval_t
1028169689Skanbb_copy_original_hash (const void *p)
1029169689Skan{
1030169689Skan  struct htab_bb_copy_original_entry *data
1031169689Skan    = ((struct htab_bb_copy_original_entry *)p);
1032169689Skan
1033169689Skan  return data->index1;
1034132718Skan}
1035169689Skanstatic int
1036169689Skanbb_copy_original_eq (const void *p, const void *q)
1037169689Skan{
1038169689Skan  struct htab_bb_copy_original_entry *data
1039169689Skan    = ((struct htab_bb_copy_original_entry *)p);
1040169689Skan  struct htab_bb_copy_original_entry *data2
1041169689Skan    = ((struct htab_bb_copy_original_entry *)q);
1042132718Skan
1043169689Skan  return data->index1 == data2->index1;
1044169689Skan}
1045132718Skan
1046169689Skan/* Initialize the data structures to maintain mapping between blocks
1047169689Skan   and its copies.  */
1048132718Skanvoid
1049169689Skaninitialize_original_copy_tables (void)
1050132718Skan{
1051169689Skan  gcc_assert (!original_copy_bb_pool);
1052169689Skan  original_copy_bb_pool
1053169689Skan    = create_alloc_pool ("original_copy",
1054169689Skan			 sizeof (struct htab_bb_copy_original_entry), 10);
1055169689Skan  bb_original = htab_create (10, bb_copy_original_hash,
1056169689Skan			     bb_copy_original_eq, NULL);
1057169689Skan  bb_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL);
1058169689Skan}
1059132718Skan
1060169689Skan/* Free the data structures to maintain mapping between blocks and
1061169689Skan   its copies.  */
1062169689Skanvoid
1063169689Skanfree_original_copy_tables (void)
1064169689Skan{
1065169689Skan  gcc_assert (original_copy_bb_pool);
1066169689Skan  htab_delete (bb_copy);
1067169689Skan  htab_delete (bb_original);
1068169689Skan  free_alloc_pool (original_copy_bb_pool);
1069169689Skan  bb_copy = NULL;
1070169689Skan  bb_original = NULL;
1071169689Skan  original_copy_bb_pool = NULL;
1072169689Skan}
1073132718Skan
1074169689Skan/* Set original for basic block.  Do nothing when data structures are not
1075169689Skan   initialized so passes not needing this don't need to care.  */
1076169689Skanvoid
1077169689Skanset_bb_original (basic_block bb, basic_block original)
1078169689Skan{
1079169689Skan  if (original_copy_bb_pool)
1080169689Skan    {
1081169689Skan      struct htab_bb_copy_original_entry **slot;
1082169689Skan      struct htab_bb_copy_original_entry key;
1083132718Skan
1084169689Skan      key.index1 = bb->index;
1085169689Skan      slot =
1086169689Skan	(struct htab_bb_copy_original_entry **) htab_find_slot (bb_original,
1087169689Skan							       &key, INSERT);
1088169689Skan      if (*slot)
1089169689Skan	(*slot)->index2 = original->index;
1090169689Skan      else
1091169689Skan	{
1092169689Skan	  *slot = pool_alloc (original_copy_bb_pool);
1093169689Skan	  (*slot)->index1 = bb->index;
1094169689Skan	  (*slot)->index2 = original->index;
1095169689Skan	}
1096169689Skan    }
1097132718Skan}
1098132718Skan
1099169689Skan/* Get the original basic block.  */
1100169689Skanbasic_block
1101169689Skanget_bb_original (basic_block bb)
1102169689Skan{
1103169689Skan  struct htab_bb_copy_original_entry *entry;
1104169689Skan  struct htab_bb_copy_original_entry key;
1105169689Skan
1106169689Skan  gcc_assert (original_copy_bb_pool);
1107169689Skan
1108169689Skan  key.index1 = bb->index;
1109169689Skan  entry = (struct htab_bb_copy_original_entry *) htab_find (bb_original, &key);
1110169689Skan  if (entry)
1111169689Skan    return BASIC_BLOCK (entry->index2);
1112169689Skan  else
1113169689Skan    return NULL;
1114169689Skan}
1115169689Skan
1116169689Skan/* Set copy for basic block.  Do nothing when data structures are not
1117169689Skan   initialized so passes not needing this don't need to care.  */
1118132718Skanvoid
1119169689Skanset_bb_copy (basic_block bb, basic_block copy)
1120132718Skan{
1121169689Skan  if (original_copy_bb_pool)
1122169689Skan    {
1123169689Skan      struct htab_bb_copy_original_entry **slot;
1124169689Skan      struct htab_bb_copy_original_entry key;
1125169689Skan
1126169689Skan      key.index1 = bb->index;
1127169689Skan      slot =
1128169689Skan	(struct htab_bb_copy_original_entry **) htab_find_slot (bb_copy,
1129169689Skan							       &key, INSERT);
1130169689Skan      if (*slot)
1131169689Skan	(*slot)->index2 = copy->index;
1132169689Skan      else
1133169689Skan	{
1134169689Skan	  *slot = pool_alloc (original_copy_bb_pool);
1135169689Skan	  (*slot)->index1 = bb->index;
1136169689Skan	  (*slot)->index2 = copy->index;
1137169689Skan	}
1138169689Skan    }
1139132718Skan}
1140132718Skan
1141169689Skan/* Get the copy of basic block.  */
1142132718Skanbasic_block
1143169689Skanget_bb_copy (basic_block bb)
1144132718Skan{
1145169689Skan  struct htab_bb_copy_original_entry *entry;
1146169689Skan  struct htab_bb_copy_original_entry key;
1147169689Skan
1148169689Skan  gcc_assert (original_copy_bb_pool);
1149169689Skan
1150169689Skan  key.index1 = bb->index;
1151169689Skan  entry = (struct htab_bb_copy_original_entry *) htab_find (bb_copy, &key);
1152169689Skan  if (entry)
1153169689Skan    return BASIC_BLOCK (entry->index2);
1154169689Skan  else
1155169689Skan    return NULL;
1156132718Skan}
1157