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