5 * File name: ir/ana2/irmemwalk.c
6 * Purpose: walk along memory edges
9 * Created: Mon 18 Oct 2004
11 * Copyright: (c) 1999-2004 Universität Karlsruhe
12 * Licence: This file is protected by GPL - GNU GENERAL PUBLIC LICENSE.
16 Walk over a firm graph along its memory edges.
18 Any number of graphs can be visited at the same time, but no graph
19 can be traversed more than once at any time.
27 # include "irgwalk.h" /* for irg_walk_func */
33 # endif /* not defined TRUE */
39 /* environment for a single memory walker */
40 typedef struct walk_mem_env_str {
41 ir_graph *graph; /* the graph we're visiting */
42 int visited; /* 'visited' marker */
43 irg_walk_func *pre; /* pre action */
44 irg_walk_func *post; /* post action */
45 void *env; /* user-defined environment */
47 struct walk_mem_env_str *prev; /* link up walking instances */
55 /* Link up walking instances */
56 static walk_mem_env_t *walk_envs = NULL;
59 Walk over the firm nodes of a graph via the memory edges (only)
60 starting from a node that has a memory input.
62 static void irg_walk_mem_node (ir_node *node,
63 walk_mem_env_t *walk_env)
65 const opcode op = get_irn_opcode (node);
68 if (get_irn_visited (node) >= walk_env->visited) {
71 set_irn_visited (node, walk_env->visited);
74 if (NULL != walk_env->pre) {
75 walk_env->pre (node, walk_env->env);
82 in = get_Load_mem (node);
84 irg_walk_mem_node (in, walk_env);
87 in = get_Store_mem (node);
89 irg_walk_mem_node (in, walk_env);
92 in = get_Alloc_mem (node);
94 irg_walk_mem_node (in, walk_env);
97 in = get_Free_mem (node);
99 irg_walk_mem_node (in, walk_env);
102 in = get_Raise_mem (node);
104 irg_walk_mem_node (in, walk_env);
107 in = get_Sel_mem (node);
109 irg_walk_mem_node (in, walk_env);
112 in = get_Call_mem (node);
114 irg_walk_mem_node (in, walk_env);
117 in = get_Return_mem (node);
119 irg_walk_mem_node (in, walk_env);
122 in = get_Proj_pred (node);
124 irg_walk_mem_node (in, walk_env);
128 int n_ins = get_irn_arity (node);
130 for (i = 0; i < n_ins; i ++) {
131 in = get_irn_n (node, i);
133 irg_walk_mem_node (in, walk_env);
137 in = get_Div_mem (node);
139 irg_walk_mem_node (in, walk_env);
142 in = get_Quot_mem (node);
144 irg_walk_mem_node (in, walk_env);
147 in = get_Mod_mem (node);
149 irg_walk_mem_node (in, walk_env);
152 in = get_DivMod_mem (node);
154 irg_walk_mem_node (in, walk_env);
157 assert (0 && "something not handled");
161 if (NULL != walk_env->post) {
162 walk_env->post (node, walk_env->env);
167 See whether the given graph is being visited right now.
168 We can't be visiting a graph multiple times.
170 int get_irg_is_mem_visited (ir_graph *graph)
172 walk_mem_env_t *walk_env = walk_envs;
174 while (NULL != walk_env) {
175 if (graph == walk_env->graph) {
179 walk_env = walk_env->prev;
186 Walk over the nodes of the given graph via the memory edges (only).
187 Each graph can only be subject to this walk once at any given time.
189 void irg_walk_mem (ir_graph *graph,
190 irg_walk_func *pre, irg_walk_func *post,
195 ir_node *end = get_irg_end_block (graph);
197 walk_mem_env_t *walk_env = (walk_mem_env_t*) xmalloc (sizeof (walk_mem_env_t));
199 assert (! get_irg_is_mem_visited (graph));
201 walk_env->graph = graph;
202 inc_irg_visited (walk_env->graph);
203 walk_env->visited = get_irg_visited (graph);
205 walk_env->prev = walk_envs;
206 walk_envs = walk_env;
209 walk_env->post = post;
212 /* 'graph' is not actually being visited right now, but it should be reported that way */
213 assert (get_irg_is_mem_visited (graph));
215 /* all return nodes */
216 n_ins = get_irn_arity (end);
217 for (i = 0; i < n_ins; i ++) {
218 ret = get_irn_n (end, i);
220 irg_walk_mem_node (ret, walk_env);
224 The end NODE sometimes has some more ins. not sure whether we need to walk them.
227 /* allow only properly nested calls right now */
228 assert (walk_envs == walk_env);
229 walk_envs = walk_envs->prev;
233 assert (! get_irg_is_mem_visited (graph));
240 Revision 1.2 2004/10/22 14:41:12 liekweg
241 execute 'pre' for a change. Also, add CVS log