OSDN Git Service

gcc/testsuite/
[pf3gnuchains/gcc-fork.git] / gcc / domwalk.c
1 /* Generic dominator tree walker
2    Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
3    Contributed by Diego Novillo <dnovillo@redhat.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "basic-block.h"
27 #include "tree-flow.h"
28 #include "domwalk.h"
29 #include "ggc.h"
30
31 /* This file implements a generic walker for dominator trees. 
32
33   To understand the dominator walker one must first have a grasp of dominators,
34   immediate dominators and the dominator tree.
35
36   Dominators
37     A block B1 is said to dominate B2 if every path from the entry to B2 must
38     pass through B1.  Given the dominance relationship, we can proceed to
39     compute immediate dominators.  Note it is not important whether or not
40     our definition allows a block to dominate itself.
41
42   Immediate Dominators:
43     Every block in the CFG has no more than one immediate dominator.  The
44     immediate dominator of block BB must dominate BB and must not dominate
45     any other dominator of BB and must not be BB itself.
46
47   Dominator tree:
48     If we then construct a tree where each node is a basic block and there
49     is an edge from each block's immediate dominator to the block itself, then
50     we have a dominator tree.
51
52
53   [ Note this walker can also walk the post-dominator tree, which is
54     defined in a similar manner.  i.e., block B1 is said to post-dominate
55     block B2 if all paths from B2 to the exit block must pass through
56     B1.  ]
57
58   For example, given the CFG
59
60                    1
61                    |
62                    2
63                   / \
64                  3   4
65                     / \
66        +---------->5   6
67        |          / \ /
68        |    +--->8   7
69        |    |   /    |
70        |    +--9    11
71        |      /      |
72        +--- 10 ---> 12
73           
74   
75   We have a dominator tree which looks like
76
77                    1
78                    |
79                    2
80                   / \
81                  /   \
82                 3     4
83                    / / \ \
84                    | | | |
85                    5 6 7 12
86                    |   |
87                    8   11
88                    |
89                    9
90                    |
91                   10
92   
93   
94   
95   The dominator tree is the basis for a number of analysis, transformation
96   and optimization algorithms that operate on a semi-global basis.
97   
98   The dominator walker is a generic routine which visits blocks in the CFG
99   via a depth first search of the dominator tree.  In the example above
100   the dominator walker might visit blocks in the following order
101   1, 2, 3, 4, 5, 8, 9, 10, 6, 7, 11, 12.
102   
103   The dominator walker has a number of callbacks to perform actions
104   during the walk of the dominator tree.  There are two callbacks
105   which walk statements, one before visiting the dominator children,
106   one after visiting the dominator children.  There is a callback 
107   before and after each statement walk callback.  In addition, the
108   dominator walker manages allocation/deallocation of data structures
109   which are local to each block visited.
110   
111   The dominator walker is meant to provide a generic means to build a pass
112   which can analyze or transform/optimize a function based on walking
113   the dominator tree.  One simply fills in the dominator walker data
114   structure with the appropriate callbacks and calls the walker.
115   
116   We currently use the dominator walker to prune the set of variables
117   which might need PHI nodes (which can greatly improve compile-time
118   performance in some cases).
119   
120   We also use the dominator walker to rewrite the function into SSA form
121   which reduces code duplication since the rewriting phase is inherently
122   a walk of the dominator tree.
123
124   And (of course), we use the dominator walker to drive our dominator
125   optimizer, which is a semi-global optimizer.
126
127   TODO:
128
129     Walking statements is based on the block statement iterator abstraction,
130     which is currently an abstraction over walking tree statements.  Thus
131     the dominator walker is currently only useful for trees.  */
132
133 /* Recursively walk the dominator tree.
134
135    WALK_DATA contains a set of callbacks to perform pass-specific
136    actions during the dominator walk as well as a stack of block local
137    data maintained during the dominator walk.
138
139    BB is the basic block we are currently visiting.  */
140
141 void
142 walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
143 {
144   void *bd = NULL;
145   basic_block dest;
146   block_stmt_iterator bsi;
147   bool is_interesting;
148   basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
149   int sp = 0;
150
151   while (true)
152     {
153       /* Don't worry about unreachable blocks.  */
154       if (EDGE_COUNT (bb->preds) > 0
155           || bb == ENTRY_BLOCK_PTR
156           || bb == EXIT_BLOCK_PTR)
157         {
158           /* If block BB is not interesting to the caller, then none of the
159              callbacks that walk the statements in BB are going to be
160              executed.  */
161           is_interesting = walk_data->interesting_blocks == NULL
162                            || TEST_BIT (walk_data->interesting_blocks,
163                                         bb->index);
164
165           /* Callback to initialize the local data structure.  */
166           if (walk_data->initialize_block_local_data)
167             {
168               bool recycled;
169
170               /* First get some local data, reusing any local data pointer we may
171                  have saved.  */
172               if (VEC_length (void_p, walk_data->free_block_data) > 0)
173                 {
174                   bd = VEC_pop (void_p, walk_data->free_block_data);
175                   recycled = 1;
176                 }
177               else
178                 {
179                   bd = xcalloc (1, walk_data->block_local_data_size);
180                   recycled = 0;
181                 }
182
183               /* Push the local data into the local data stack.  */
184               VEC_safe_push (void_p, heap, walk_data->block_data_stack, bd);
185
186               /* Call the initializer.  */
187               walk_data->initialize_block_local_data (walk_data, bb,
188                                                       recycled);
189
190             }
191
192           /* Callback for operations to execute before we have walked the
193              dominator children, but before we walk statements.  */
194           if (walk_data->before_dom_children_before_stmts)
195             (*walk_data->before_dom_children_before_stmts) (walk_data, bb);
196
197           /* Statement walk before walking dominator children.  */
198           if (is_interesting && walk_data->before_dom_children_walk_stmts)
199             {
200               if (walk_data->walk_stmts_backward)
201                 for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
202                   (*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
203                                                                 bsi);
204               else
205                 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
206                   (*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
207                                                                 bsi);
208             }
209
210           /* Callback for operations to execute before we have walked the
211              dominator children, and after we walk statements.  */
212           if (walk_data->before_dom_children_after_stmts)
213             (*walk_data->before_dom_children_after_stmts) (walk_data, bb);
214
215           /* Mark the current BB to be popped out of the recursion stack
216              once childs are processed.  */
217           worklist[sp++] = bb;
218           worklist[sp++] = NULL;
219
220           for (dest = first_dom_son (walk_data->dom_direction, bb);
221                dest; dest = next_dom_son (walk_data->dom_direction, dest))
222             worklist[sp++] = dest;
223         }
224       /* NULL is used to signalize pop operation in recursion stack.  */
225       while (sp > 0 && !worklist[sp - 1])
226         {
227           --sp;
228           bb = worklist[--sp];
229           is_interesting = walk_data->interesting_blocks == NULL
230                            || TEST_BIT (walk_data->interesting_blocks,
231                                         bb->index);
232           /* Callback for operations to execute after we have walked the
233              dominator children, but before we walk statements.  */
234           if (walk_data->after_dom_children_before_stmts)
235             (*walk_data->after_dom_children_before_stmts) (walk_data, bb);
236
237           /* Statement walk after walking dominator children.  */
238           if (is_interesting && walk_data->after_dom_children_walk_stmts)
239             {
240               if (walk_data->walk_stmts_backward)
241                 for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
242                   (*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
243                                                                bsi);
244               else
245                 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
246                   (*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
247                                                                bsi);
248             }
249
250           /* Callback for operations to execute after we have walked the
251              dominator children and after we have walked statements.  */
252           if (walk_data->after_dom_children_after_stmts)
253             (*walk_data->after_dom_children_after_stmts) (walk_data, bb);
254
255           if (walk_data->initialize_block_local_data)
256             {
257               /* And finally pop the record off the block local data stack.  */
258               bd = VEC_pop (void_p, walk_data->block_data_stack);
259               /* And save the block data so that we can re-use it.  */
260               VEC_safe_push (void_p, heap, walk_data->free_block_data, bd);
261             }
262         }
263       if (sp)
264         bb = worklist[--sp];
265       else
266         break;
267     }
268   free (worklist);
269 }
270
271 void
272 init_walk_dominator_tree (struct dom_walk_data *walk_data)
273 {
274   walk_data->free_block_data = NULL;
275   walk_data->block_data_stack = NULL;
276 }
277
278 void
279 fini_walk_dominator_tree (struct dom_walk_data *walk_data)
280 {
281   if (walk_data->initialize_block_local_data)
282     {
283       while (VEC_length (void_p, walk_data->free_block_data) > 0)
284         free (VEC_pop (void_p, walk_data->free_block_data));
285     }
286
287   VEC_free (void_p, heap, walk_data->free_block_data);
288   VEC_free (void_p, heap, walk_data->block_data_stack);
289 }