CVS:
[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 /*      printf(" - "); DDMSG2(node);  */
23
24   if (get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
25
26 /*      printf(" -> "); DDMSG2(node);  */
27     set_irn_visited(node, get_irg_visited(current_ir_graph));
28
29     if (pre) {
30       pre(node, env);
31     }
32
33     if (is_no_Block(node)) {
34       irg_walk_2(get_nodes_Block(node), pre, post, env);
35     }
36     for (i = get_irn_arity(node) - 1; i >= 0; --i) {
37 /*        printf("   "); DDMSG2(node); */
38 /*        printf("   "); DDMSG2(get_irn_n(node, i)); */
39
40       irg_walk_2(get_irn_n(node, i), pre, post, env);
41     }
42
43 /*      printf(" <- "); DDMSG2(node);  */
44     if (post)
45       post(node, env);
46   }
47   return;
48 }
49
50
51 void irg_walk(ir_node *node,
52               void (pre)(ir_node*, void*), void (post)(ir_node*, void*),
53               void *env)
54 {
55   assert(node);
56   inc_irg_visited (current_ir_graph);
57   irg_walk_2(node, pre, post, env);
58   return;
59 }
60
61 /***************************************************************************/
62 void irg_block_walk_2(ir_node *node, void (pre)(ir_node*, void*),
63                       void (post)(ir_node*, void*), void *env)
64 {
65   int i;
66
67   assert(get_irn_opcode(node) == iro_Block);
68
69   if(get_Block_block_visited(node) < get_irg_block_visited(current_ir_graph)) {
70     set_Block_block_visited(node, get_irg_block_visited(current_ir_graph));
71
72     if(pre)
73       pre(node, env);
74
75     for(i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
76
77       /* find the corresponding predecessor block. */
78       ir_node *pred = skip_Proj(get_Block_cfgpred(node, i));
79       /* GL: I'm not sure whether this assert must go through.  There
80          could be Id chains?? */
81       assert(is_cfop(pred) || is_fragile_op(pred));
82       pred = get_nodes_Block(pred);
83       assert(get_irn_opcode(pred) == iro_Block);
84
85       /* recursion */
86       irg_block_walk_2(pred, pre, post, env);
87     }
88
89     if(post)
90       post(node, env);
91   }
92   return;
93 }
94
95
96 /* walks only over Block nodes in the graph.  Has it's own visited
97    flag, so that it can be interleaved with the other walker.         */
98 void irg_block_walk(ir_node *node,
99                     void (pre)(ir_node*, void*), void (post)(ir_node*, void*),
100                     void *env)
101 {
102   assert(node);
103   inc_irg_block_visited(current_ir_graph);
104   if (is_no_Block(node)) node = get_nodes_Block(node);
105   assert(get_irn_opcode(node)  == iro_Block);
106   irg_block_walk_2(node, pre, post, env);
107   return;
108 }