e6ee58bfbc94f52e460d7fae525b9cabb726d203
[libfirm] / ir / ir / irgwalk.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Author: Boris Boesler
5 **
6 ** traverse an ir graph
7 ** - execute the pre function before recursion
8 ** - execute the post function after recursion
9 */
10
11 # include "irnode.h"
12 # include "irgraph.h" /* visited flag */
13
14
15 void irg_walk_2(ir_node *node,
16               void (pre)(ir_node*, void*), void (post)(ir_node*, void*),
17               void *env)
18 {
19   int i;
20
21   assert(node);
22   if(get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
23     set_irn_visited(node, get_irg_visited(current_ir_graph));
24     if(pre) {
25       pre(node, env);
26     }
27
28     if (is_no_Block(node)) {
29       irg_walk_2(get_nodes_Block(node), pre, post, env);
30     }
31     for(i = get_irn_arity(node) - 1; i >= 0; --i) {
32       irg_walk_2(get_irn_n(node, i), pre, post, env);
33     }
34
35     if(post)
36       post(node, env);
37   }
38   return;
39 }
40
41
42 void irg_walk(ir_node *node,
43               void (pre)(ir_node*, void*), void (post)(ir_node*, void*),
44               void *env)
45 {
46   assert(node);
47   inc_irg_visited (current_ir_graph);
48   irg_walk_2(node, pre, post, env);
49   return;
50 }
51
52 /***************************************************************************/
53 void irg_block_walk_2(ir_node *node, void (pre)(ir_node*, void*),
54                       void (post)(ir_node*, void*), void *env)
55 {
56   int i;
57
58   assert(get_irn_opcode(node) == iro_Block);
59
60   if(get_Block_block_visited(node) < get_irg_block_visited(current_ir_graph)) {
61     set_Block_block_visited(node, get_irg_block_visited(current_ir_graph));
62
63     if(pre)
64       pre(node, env);
65
66     for(i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
67
68       /* find the corresponding predecessor block. */
69       ir_node *pred = skip_Proj(get_Block_cfgpred(node, i));
70       /* GL: I'm not sure whether this assert must go through.  There
71          could be Id chains?? */
72       assert(is_cfop(pred) || is_fragile_op(pred));
73       pred = get_nodes_Block(pred);
74       assert(get_irn_opcode(pred) == iro_Block);
75
76       /* recursion */
77       irg_block_walk_2(pred, pre, post, env);
78     }
79
80     if(post)
81       post(node, env);
82   }
83   return;
84 }
85
86
87 /* walks only over Block nodes in the graph.  Has it's own visited
88    flag, so that it can be interleaved with the other walker.         */
89 void irg_block_walk(ir_node *node,
90                     void (pre)(ir_node*, void*), void (post)(ir_node*, void*),
91                     void *env)
92 {
93   assert(node);
94   inc_irg_block_visited(current_ir_graph);
95   if (is_no_Block(node)) node = get_nodes_Block(node);
96   assert(get_irn_opcode(node)  == iro_Block);
97   irg_block_walk_2(node, pre, post, env);
98   return;
99 }