1169689Skan/* Generic dominator tree walker
2169689Skan   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3169689Skan   Contributed by Diego Novillo <dnovillo@redhat.com>
4169689Skan
5169689SkanThis file is part of GCC.
6169689Skan
7169689SkanGCC is free software; you can redistribute it and/or modify
8169689Skanit under the terms of the GNU General Public License as published by
9169689Skanthe Free Software Foundation; either version 2, or (at your option)
10169689Skanany later version.
11169689Skan
12169689SkanGCC is distributed in the hope that it will be useful,
13169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
14169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169689SkanGNU General Public License for more details.
16169689Skan
17169689SkanYou should have received a copy of the GNU General Public License
18169689Skanalong with GCC; see the file COPYING.  If not, write to
19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689SkanBoston, MA 02110-1301, USA.  */
21169689Skan
22169689Skan#include "config.h"
23169689Skan#include "system.h"
24169689Skan#include "coretypes.h"
25169689Skan#include "tm.h"
26169689Skan#include "tree.h"
27169689Skan#include "basic-block.h"
28169689Skan#include "tree-flow.h"
29169689Skan#include "domwalk.h"
30169689Skan#include "ggc.h"
31169689Skan
32169689Skan/* This file implements a generic walker for dominator trees.
33169689Skan
34169689Skan  To understand the dominator walker one must first have a grasp of dominators,
35169689Skan  immediate dominators and the dominator tree.
36169689Skan
37169689Skan  Dominators
38169689Skan    A block B1 is said to dominate B2 if every path from the entry to B2 must
39169689Skan    pass through B1.  Given the dominance relationship, we can proceed to
40169689Skan    compute immediate dominators.  Note it is not important whether or not
41169689Skan    our definition allows a block to dominate itself.
42169689Skan
43169689Skan  Immediate Dominators:
44169689Skan    Every block in the CFG has no more than one immediate dominator.  The
45169689Skan    immediate dominator of block BB must dominate BB and must not dominate
46169689Skan    any other dominator of BB and must not be BB itself.
47169689Skan
48169689Skan  Dominator tree:
49169689Skan    If we then construct a tree where each node is a basic block and there
50169689Skan    is an edge from each block's immediate dominator to the block itself, then
51169689Skan    we have a dominator tree.
52169689Skan
53169689Skan
54169689Skan  [ Note this walker can also walk the post-dominator tree, which is
55169689Skan    defined in a similar manner.  i.e., block B1 is said to post-dominate
56169689Skan    block B2 if all paths from B2 to the exit block must pass through
57169689Skan    B1.  ]
58169689Skan
59169689Skan  For example, given the CFG
60169689Skan
61169689Skan                   1
62169689Skan                   |
63169689Skan                   2
64169689Skan                  / \
65169689Skan                 3   4
66169689Skan                    / \
67169689Skan       +---------->5   6
68169689Skan       |          / \ /
69169689Skan       |    +--->8   7
70169689Skan       |    |   /    |
71169689Skan       |    +--9    11
72169689Skan       |      /      |
73169689Skan       +--- 10 ---> 12
74169689Skan
75169689Skan
76169689Skan  We have a dominator tree which looks like
77169689Skan
78169689Skan                   1
79169689Skan                   |
80169689Skan                   2
81169689Skan                  / \
82169689Skan                 /   \
83169689Skan                3     4
84169689Skan                   / / \ \
85169689Skan                   | | | |
86169689Skan                   5 6 7 12
87169689Skan                   |   |
88169689Skan                   8   11
89169689Skan                   |
90169689Skan                   9
91169689Skan                   |
92169689Skan                  10
93169689Skan
94169689Skan
95169689Skan
96169689Skan  The dominator tree is the basis for a number of analysis, transformation
97169689Skan  and optimization algorithms that operate on a semi-global basis.
98169689Skan
99169689Skan  The dominator walker is a generic routine which visits blocks in the CFG
100169689Skan  via a depth first search of the dominator tree.  In the example above
101169689Skan  the dominator walker might visit blocks in the following order
102169689Skan  1, 2, 3, 4, 5, 8, 9, 10, 6, 7, 11, 12.
103169689Skan
104169689Skan  The dominator walker has a number of callbacks to perform actions
105169689Skan  during the walk of the dominator tree.  There are two callbacks
106169689Skan  which walk statements, one before visiting the dominator children,
107169689Skan  one after visiting the dominator children.  There is a callback
108169689Skan  before and after each statement walk callback.  In addition, the
109169689Skan  dominator walker manages allocation/deallocation of data structures
110169689Skan  which are local to each block visited.
111169689Skan
112169689Skan  The dominator walker is meant to provide a generic means to build a pass
113169689Skan  which can analyze or transform/optimize a function based on walking
114169689Skan  the dominator tree.  One simply fills in the dominator walker data
115169689Skan  structure with the appropriate callbacks and calls the walker.
116169689Skan
117169689Skan  We currently use the dominator walker to prune the set of variables
118169689Skan  which might need PHI nodes (which can greatly improve compile-time
119169689Skan  performance in some cases).
120169689Skan
121169689Skan  We also use the dominator walker to rewrite the function into SSA form
122169689Skan  which reduces code duplication since the rewriting phase is inherently
123169689Skan  a walk of the dominator tree.
124169689Skan
125169689Skan  And (of course), we use the dominator walker to drive a our dominator
126169689Skan  optimizer, which is a semi-global optimizer.
127169689Skan
128169689Skan  TODO:
129169689Skan
130169689Skan    Walking statements is based on the block statement iterator abstraction,
131169689Skan    which is currently an abstraction over walking tree statements.  Thus
132169689Skan    the dominator walker is currently only useful for trees.  */
133169689Skan
134169689Skan/* Recursively walk the dominator tree.
135169689Skan
136169689Skan   WALK_DATA contains a set of callbacks to perform pass-specific
137169689Skan   actions during the dominator walk as well as a stack of block local
138169689Skan   data maintained during the dominator walk.
139169689Skan
140169689Skan   BB is the basic block we are currently visiting.  */
141169689Skan
142169689Skanvoid
143169689Skanwalk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
144169689Skan{
145169689Skan  void *bd = NULL;
146169689Skan  basic_block dest;
147169689Skan  block_stmt_iterator bsi;
148169689Skan  bool is_interesting;
149169689Skan  basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
150169689Skan  int sp = 0;
151169689Skan
152169689Skan  while (true)
153169689Skan    {
154169689Skan      /* Don't worry about unreachable blocks.  */
155169689Skan      if (EDGE_COUNT (bb->preds) > 0 || bb == ENTRY_BLOCK_PTR)
156169689Skan	{
157169689Skan	  /* If block BB is not interesting to the caller, then none of the
158169689Skan	     callbacks that walk the statements in BB are going to be
159169689Skan	     executed.  */
160169689Skan	  is_interesting = walk_data->interesting_blocks == NULL
161169689Skan	                   || TEST_BIT (walk_data->interesting_blocks,
162169689Skan					bb->index);
163169689Skan
164169689Skan	  /* Callback to initialize the local data structure.  */
165169689Skan	  if (walk_data->initialize_block_local_data)
166169689Skan	    {
167169689Skan	      bool recycled;
168169689Skan
169169689Skan	      /* First get some local data, reusing any local data pointer we may
170169689Skan	         have saved.  */
171169689Skan	      if (VEC_length (void_p, walk_data->free_block_data) > 0)
172169689Skan		{
173169689Skan		  bd = VEC_pop (void_p, walk_data->free_block_data);
174169689Skan		  recycled = 1;
175169689Skan		}
176169689Skan	      else
177169689Skan		{
178169689Skan		  bd = xcalloc (1, walk_data->block_local_data_size);
179169689Skan		  recycled = 0;
180169689Skan		}
181169689Skan
182169689Skan	      /* Push the local data into the local data stack.  */
183169689Skan	      VEC_safe_push (void_p, heap, walk_data->block_data_stack, bd);
184169689Skan
185169689Skan	      /* Call the initializer.  */
186169689Skan	      walk_data->initialize_block_local_data (walk_data, bb,
187169689Skan						      recycled);
188169689Skan
189169689Skan	    }
190169689Skan
191169689Skan	  /* Callback for operations to execute before we have walked the
192169689Skan	     dominator children, but before we walk statements.  */
193169689Skan	  if (walk_data->before_dom_children_before_stmts)
194169689Skan	    (*walk_data->before_dom_children_before_stmts) (walk_data, bb);
195169689Skan
196169689Skan	  /* Statement walk before walking dominator children.  */
197169689Skan	  if (is_interesting && walk_data->before_dom_children_walk_stmts)
198169689Skan	    {
199169689Skan	      if (walk_data->walk_stmts_backward)
200169689Skan		for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
201169689Skan		  (*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
202169689Skan								bsi);
203169689Skan	      else
204169689Skan		for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
205169689Skan		  (*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
206169689Skan								bsi);
207169689Skan	    }
208169689Skan
209169689Skan	  /* Callback for operations to execute before we have walked the
210169689Skan	     dominator children, and after we walk statements.  */
211169689Skan	  if (walk_data->before_dom_children_after_stmts)
212169689Skan	    (*walk_data->before_dom_children_after_stmts) (walk_data, bb);
213169689Skan
214169689Skan	  /* Mark the current BB to be popped out of the recursion stack
215169689Skan	     once childs are processed.  */
216169689Skan	  worklist[sp++] = bb;
217169689Skan	  worklist[sp++] = NULL;
218169689Skan
219169689Skan	  for (dest = first_dom_son (walk_data->dom_direction, bb);
220169689Skan	       dest; dest = next_dom_son (walk_data->dom_direction, dest))
221169689Skan	    worklist[sp++] = dest;
222169689Skan	}
223169689Skan      /* NULL is used to signalize pop operation in recursion stack.  */
224169689Skan      while (sp > 0 && !worklist[sp - 1])
225169689Skan	{
226169689Skan	  --sp;
227169689Skan	  bb = worklist[--sp];
228169689Skan	  is_interesting = walk_data->interesting_blocks == NULL
229169689Skan	                   || TEST_BIT (walk_data->interesting_blocks,
230169689Skan				        bb->index);
231169689Skan	  /* Callback for operations to execute after we have walked the
232169689Skan	     dominator children, but before we walk statements.  */
233169689Skan	  if (walk_data->after_dom_children_before_stmts)
234169689Skan	    (*walk_data->after_dom_children_before_stmts) (walk_data, bb);
235169689Skan
236169689Skan	  /* Statement walk after walking dominator children.  */
237169689Skan	  if (is_interesting && walk_data->after_dom_children_walk_stmts)
238169689Skan	    {
239169689Skan	      if (walk_data->walk_stmts_backward)
240169689Skan		for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
241169689Skan		  (*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
242169689Skan							       bsi);
243169689Skan	      else
244169689Skan		for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
245169689Skan		  (*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
246169689Skan							       bsi);
247169689Skan	    }
248169689Skan
249169689Skan	  /* Callback for operations to execute after we have walked the
250169689Skan	     dominator children and after we have walked statements.  */
251169689Skan	  if (walk_data->after_dom_children_after_stmts)
252169689Skan	    (*walk_data->after_dom_children_after_stmts) (walk_data, bb);
253169689Skan
254169689Skan	  if (walk_data->initialize_block_local_data)
255169689Skan	    {
256169689Skan	      /* And finally pop the record off the block local data stack.  */
257169689Skan	      bd = VEC_pop (void_p, walk_data->block_data_stack);
258169689Skan	      /* And save the block data so that we can re-use it.  */
259169689Skan	      VEC_safe_push (void_p, heap, walk_data->free_block_data, bd);
260169689Skan	    }
261169689Skan	}
262169689Skan      if (sp)
263169689Skan	bb = worklist[--sp];
264169689Skan      else
265169689Skan	break;
266169689Skan    }
267169689Skan  free (worklist);
268169689Skan}
269169689Skan
270169689Skanvoid
271169689Skaninit_walk_dominator_tree (struct dom_walk_data *walk_data)
272169689Skan{
273169689Skan  walk_data->free_block_data = NULL;
274169689Skan  walk_data->block_data_stack = NULL;
275169689Skan}
276169689Skan
277169689Skanvoid
278169689Skanfini_walk_dominator_tree (struct dom_walk_data *walk_data)
279169689Skan{
280169689Skan  if (walk_data->initialize_block_local_data)
281169689Skan    {
282169689Skan      while (VEC_length (void_p, walk_data->free_block_data) > 0)
283169689Skan	free (VEC_pop (void_p, walk_data->free_block_data));
284169689Skan    }
285169689Skan
286169689Skan  VEC_free (void_p, heap, walk_data->free_block_data);
287169689Skan  VEC_free (void_p, heap, walk_data->block_data_stack);
288169689Skan}
289