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