fixed the fix of the fix (that was fix)
[libfirm] / ir / ir / irgwalk.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Functions for traversing ir graphs
23  * @author  Boris Boesler, Goetz Lindenmaier, Michael Beck
24  * @version $Id$
25  * @summary
26  *  traverse an ir graph
27  *  - execute the pre function before recursion
28  *  - execute the post function after recursion
29  */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #ifdef HAVE_STDLIB_H
35 # include <stdlib.h>
36 #endif
37
38 #include "irnode_t.h"
39 #include "irgraph_t.h" /* visited flag */
40 #include "irprog.h"
41 #include "irgwalk.h"
42 #include "irhooks.h"
43 #include "ircgcons.h"
44
45 #include "pset_new.h"
46 #include "array.h"
47
48 /**
49  * Walk over an interprocedural graph (callgraph).
50  * Visits only graphs in irg_set.
51  */
52 static void irg_walk_cg(ir_node * node, unsigned long visited,
53                         pset_new_t *irg_set, irg_walk_func *pre,
54                         irg_walk_func *post, void * env) {
55   int i;
56   ir_graph * rem = current_ir_graph;
57   ir_node * pred;
58
59   assert(node && node->kind == k_ir_node);
60   if (get_irn_visited(node) >= visited) return;
61
62   set_irn_visited(node, visited);
63
64   if (pre) pre(node, env);
65
66   pred = skip_Proj(node);
67   if (get_irn_op(pred) == op_CallBegin
68       || get_irn_op(pred) == op_EndReg
69       || get_irn_op(pred) == op_EndExcept) {
70     current_ir_graph = get_irn_irg(pred);
71   }
72
73   if (is_no_Block(node)) { /* not block */
74     irg_walk_cg(get_nodes_block(node), visited, irg_set, pre, post, env);
75   }
76
77   if (get_irn_op(node) == op_Block) { /* block */
78     for (i = get_irn_arity(node) - 1; i >= 0; --i) {
79       ir_node * exec = get_irn_n(node, i);
80       ir_node * pred = skip_Proj(exec);
81       if ((get_irn_op(pred) != op_CallBegin
82            && get_irn_op(pred) != op_EndReg
83            && get_irn_op(pred) != op_EndExcept)
84           || pset_new_contains(irg_set, get_irn_irg(pred))) {
85         irg_walk_cg(exec, visited, irg_set, pre, post, env);
86       }
87     }
88   } else if (get_irn_op(node) == op_Filter) { /* filter */
89     for (i = get_irn_arity(node) - 1; i >= 0; --i) {
90       ir_node * pred = get_irn_n(node, i);
91       if (get_irn_op(pred) == op_Unknown || get_irn_op(pred) == op_Bad) {
92         irg_walk_cg(pred, visited, irg_set, pre, post, env);
93       } else {
94         ir_node * exec;
95         exec = skip_Proj(get_Block_cfgpred(get_nodes_block(node), i));
96
97         if (op_Bad == get_irn_op (exec)) {
98           continue;
99         }
100
101         assert(get_irn_op(exec) == op_CallBegin
102                || get_irn_op(exec) == op_EndReg
103                || get_irn_op(exec) == op_EndExcept);
104         if (pset_new_contains(irg_set, get_irn_irg(exec))) {
105           current_ir_graph = get_irn_irg(exec);
106           irg_walk_cg(pred, visited, irg_set, pre, post, env);
107           current_ir_graph = rem;
108         }
109       }
110     }
111   } else {                      /* everything else */
112     for (i = get_irn_arity(node) - 1; i >= 0; --i) {
113       irg_walk_cg(get_irn_n(node, i), visited, irg_set, pre, post, env);
114     }
115   }
116
117   if (post) post(node, env);
118
119   current_ir_graph = rem;
120 }
121
122
123 /**
124  * Insert all ir_graphs in irg_set, that are (transitive) reachable.
125  */
126 static void collect_irgs(ir_node * node, pset_new_t *irg_set) {
127   if (is_Call(node)) {
128     int i;
129     for (i = get_Call_n_callees(node) - 1; i >= 0; --i) {
130       ir_entity * ent = get_Call_callee(node, i);
131       ir_graph * irg = get_entity_irg(ent);
132       if (irg && !pset_new_contains(irg_set, irg)) {
133         pset_new_insert(irg_set, irg);
134         irg_walk_graph(irg, (irg_walk_func *) collect_irgs, NULL, irg_set);
135       }
136     }
137   }
138 }
139
140 /**
141  * specialized version of irg_walk_2, called if only pre callback exists
142  *
143  * @return number of visited nodes
144  */
145 static unsigned
146 irg_walk_2_pre(ir_node *node, irg_walk_func *pre, void * env) {
147   int i;
148   unsigned cnt = 1;
149   ir_graph *irg = current_ir_graph;
150
151   set_irn_visited(node, irg->visited);
152
153   pre(node, env);
154
155   if (node->op != op_Block) {
156     ir_node *pred = get_irn_n(node, -1);
157     if (pred->visited < irg->visited)
158       cnt += irg_walk_2_pre(pred, pre, env);
159   }
160   for (i = get_irn_arity(node) - 1; i >= 0; --i) {
161     ir_node *pred = get_irn_n(node, i);
162     if (pred->visited < irg->visited)
163       cnt += irg_walk_2_pre(pred, pre, env);
164   }
165   return cnt;
166 }
167
168 /**
169  * specialized version of irg_walk_2, called if only post callback exists
170  *
171  * @return number of visited nodes
172  */
173 static unsigned
174 irg_walk_2_post(ir_node *node, irg_walk_func *post, void * env) {
175   int i;
176   unsigned cnt = 1;
177   ir_graph *irg = current_ir_graph;
178
179   set_irn_visited(node, irg->visited);
180
181   if (node->op != op_Block) {
182     ir_node *pred = get_irn_n(node, -1);
183     if (pred->visited < irg->visited)
184       cnt += irg_walk_2_post(pred, post, env);
185   }
186   for (i = get_irn_arity(node) - 1; i >= 0; --i) {
187     ir_node *pred = get_irn_n(node, i);
188     if (pred->visited < irg->visited)
189       cnt += irg_walk_2_post(pred, post, env);
190   }
191
192   post(node, env);
193
194   return cnt;
195 }
196
197 /**
198  * specialized version of irg_walk_2, called if pre and post callbacks exist
199  *
200  * @return number of visited nodes
201  */
202 static unsigned
203 irg_walk_2_both(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void * env) {
204   int i;
205   unsigned cnt = 1;
206   ir_graph *irg = current_ir_graph;
207
208   set_irn_visited(node, irg->visited);
209
210   pre(node, env);
211
212   if (node->op != op_Block) {
213     ir_node *pred = get_irn_n(node, -1);
214     if (pred->visited < irg->visited)
215       cnt += irg_walk_2_both(pred, pre, post, env);
216   }
217   for (i = get_irn_arity(node) - 1; i >= 0; --i) {
218     ir_node *pred = get_irn_n(node, i);
219     if (pred->visited < irg->visited)
220       cnt += irg_walk_2_both(pred, pre, post, env);
221   }
222
223   post(node, env);
224
225   return cnt;
226 }
227
228 /**
229  * Intraprozedural graph walker.
230  *
231  * @return number of visited nodes
232  */
233 static unsigned
234 irg_walk_2(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void * env)
235 {
236   if (node->visited < current_ir_graph->visited) {
237     if      (!post) return irg_walk_2_pre (node, pre, env);
238     else if (!pre)  return irg_walk_2_post(node, post, env);
239     else            return irg_walk_2_both(node, pre, post, env);
240   }
241   return 0;
242 }
243
244 /* a counter */
245 static unsigned nodes_touched = 0;
246
247 /*
248  * generic graph walker
249  */
250 void irg_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env)
251 {
252   assert(is_ir_node(node));
253
254   if (get_interprocedural_view()) {
255         pset_new_t           irg_set;
256         pset_new_iterator_t  iter;
257     unsigned long        visited;
258     ir_graph            *irg;
259     assert(get_irp_ip_view_state() == ip_view_valid);
260
261         pset_new_init(&irg_set);
262     set_interprocedural_view(0);
263     pset_new_insert(&irg_set, current_ir_graph);
264     irg_walk(node, (irg_walk_func *) collect_irgs, NULL, &irg_set);
265     set_interprocedural_view(1);
266     visited = get_max_irg_visited() + 1;
267
268         foreach_pset_new(&irg_set, irg, iter) {
269       set_irg_visited(irg, visited);
270     }
271     irg_walk_cg(node, visited, &irg_set, pre, post, env);
272         pset_new_destroy(&irg_set);
273   } else {
274     set_using_visited(current_ir_graph);
275     inc_irg_visited(current_ir_graph);
276     nodes_touched = irg_walk_2(node, pre, post, env);
277     clear_using_visited(current_ir_graph);
278   }
279   return;
280 }
281
282 /*
283  * walk over a graph
284  */
285 void irg_walk_graph(ir_graph *irg, irg_walk_func *pre, irg_walk_func *post, void *env) {
286   ir_graph * rem = current_ir_graph;
287
288   hook_irg_walk(irg, (generic_func *)pre, (generic_func *)post);
289   current_ir_graph = irg;
290   irg_walk(get_irg_end(irg), pre, post, env);
291   irg->estimated_node_count = nodes_touched;
292   current_ir_graph = rem;
293 }
294
295 /* Executes irg_walk(end, pre, post, env) for all irgraphs in irprog.
296    Sets current_ir_graph properly for each walk.  Conserves current
297    current_ir_graph. */
298 void all_irg_walk(irg_walk_func *pre, irg_walk_func *post, void *env) {
299   int i;
300   ir_graph *irg, *rem;
301
302   rem = current_ir_graph;
303
304   for (i = 0; i < get_irp_n_irgs(); i++) {
305     irg = get_irp_irg(i);
306     current_ir_graph = irg;
307     irg_walk(get_irg_end(irg), pre, post, env);
308   }
309   current_ir_graph = rem;
310 }
311
312 /***************************************************************************/
313
314 /**
315  * specialized version of irg_walk_in_or_dep_2, called if only pre callback exists
316  *
317  * @return number of visited nodes
318  */
319 static unsigned
320 irg_walk_in_or_dep_2_pre(ir_node *node, irg_walk_func *pre, void *env) {
321   int i;
322   unsigned cnt = 1;
323   ir_graph *irg = current_ir_graph;
324
325   set_irn_visited(node, irg->visited);
326
327   pre(node, env);
328
329   if (node->op != op_Block) {
330     ir_node *pred = get_irn_n(node, -1);
331     if (pred->visited < irg->visited)
332       cnt += irg_walk_in_or_dep_2_pre(pred, pre, env);
333   }
334   for (i = get_irn_ins_or_deps(node) - 1; i >= 0; --i) {
335     ir_node *pred = get_irn_in_or_dep(node, i);
336     if (pred->visited < irg->visited)
337       cnt += irg_walk_in_or_dep_2_pre(pred, pre, env);
338   }
339   return cnt;
340 }
341
342 /**
343  * specialized version of irg_walk_in_or_dep_2, called if only post callback exists
344  *
345  * @return number of visited nodes
346  */
347 static unsigned
348 irg_walk_in_or_dep_2_post(ir_node *node, irg_walk_func *post, void *env) {
349   int i;
350   unsigned cnt = 1;
351   ir_graph *irg = current_ir_graph;
352
353   set_irn_visited(node, irg->visited);
354
355   if (node->op != op_Block) {
356     ir_node *pred = get_irn_n(node, -1);
357     if (pred->visited < irg->visited)
358       cnt += irg_walk_in_or_dep_2_post(pred, post, env);
359   }
360   for (i = get_irn_ins_or_deps(node) - 1; i >= 0; --i) {
361     ir_node *pred = get_irn_in_or_dep(node, i);
362     if (pred->visited < irg->visited)
363       cnt += irg_walk_in_or_dep_2_post(pred, post, env);
364   }
365
366   post(node, env);
367
368   return cnt;
369 }
370
371 /**
372  * specialized version of irg_walk_in_or_dep_2, called if pre and post callbacks exist
373  *
374  * @return number of visited nodes
375  */
376 static unsigned
377 irg_walk_in_or_dep_2_both(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env) {
378   int i;
379   unsigned cnt = 1;
380   ir_graph *irg = current_ir_graph;
381
382   set_irn_visited(node, irg->visited);
383
384   pre(node, env);
385
386   if (node->op != op_Block) {
387     ir_node *pred = get_irn_n(node, -1);
388     if (pred->visited < irg->visited)
389       cnt += irg_walk_in_or_dep_2_both(pred, pre, post, env);
390   }
391   for (i = get_irn_ins_or_deps(node) - 1; i >= 0; --i) {
392     ir_node *pred = get_irn_in_or_dep(node, i);
393     if (pred->visited < irg->visited)
394       cnt += irg_walk_in_or_dep_2_both(pred, pre, post, env);
395   }
396
397   post(node, env);
398
399   return cnt;
400 }
401
402 /**
403  * Intraprozedural graph walker. Follows dependency edges as well.
404  *
405  * @return number of visited nodes
406  */
407 static unsigned
408 irg_walk_in_or_dep_2(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env)
409 {
410   if (node->visited < current_ir_graph->visited) {
411     if      (! post) return irg_walk_in_or_dep_2_pre (node, pre, env);
412     else if (! pre)  return irg_walk_in_or_dep_2_post(node, post, env);
413     else             return irg_walk_in_or_dep_2_both(node, pre, post, env);
414   }
415   return 0;
416 }
417
418 /*
419  * Generic graph walker. Follows dependency edges as well.
420  */
421 void irg_walk_in_or_dep(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env)
422 {
423   assert(is_ir_node(node));
424
425   if (get_interprocedural_view()) {
426         assert(0 && "This is not yet implemented.");
427   } else {
428     set_using_visited(current_ir_graph);
429     inc_irg_visited(current_ir_graph);
430     nodes_touched = irg_walk_in_or_dep_2(node, pre, post, env);
431     clear_using_visited(current_ir_graph);
432   }
433   return;
434 }
435
436 /*
437  * Walk over a graph. Follow all edges (including dependencies)
438  */
439 void irg_walk_in_or_dep_graph(ir_graph *irg, irg_walk_func *pre, irg_walk_func *post, void *env) {
440   ir_graph * rem = current_ir_graph;
441
442   hook_irg_walk(irg, (generic_func *)pre, (generic_func *)post);
443   current_ir_graph = irg;
444   irg_walk_in_or_dep(get_irg_end(irg), pre, post, env);
445   irg->estimated_node_count = nodes_touched;
446   current_ir_graph = rem;
447 }
448
449 /***************************************************************************/
450
451 /**
452  * Returns current_ir_graph and sets it to the irg of predecessor index
453  * of node n.
454  */
455 static INLINE ir_graph *
456 switch_irg (ir_node *n, int index) {
457   ir_graph *old_current = current_ir_graph;
458
459   if (get_interprocedural_view()) {
460     /* Only Filter and Block nodes can have predecessors in other graphs. */
461     if (get_irn_op(n) == op_Filter)
462       n = get_nodes_block(n);
463     if (get_irn_op(n) == op_Block) {
464       ir_node *cfop = skip_Proj(get_Block_cfgpred(n, index));
465       if (is_ip_cfop(cfop)) {
466         current_ir_graph = get_irn_irg(cfop);
467       }
468     }
469   }
470
471   return old_current;
472 }
473
474 static void
475 cg_walk_2(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void * env)
476 {
477   int i;
478   ir_graph *rem = NULL;
479   assert(node);
480
481   if (get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
482     set_irn_visited(node, get_irg_visited(current_ir_graph));
483
484     if (pre) pre(node, env);
485
486     if (is_no_Block(node))
487       cg_walk_2(get_nodes_block(node), pre, post, env);
488     for (i = get_irn_arity(node) - 1; i >= 0; --i) {
489       rem = switch_irg(node, i);  /* @@@ AS: Is this wrong? We do have to
490                                              switch to the irg of the predecessor, don't we? */
491       cg_walk_2(get_irn_n(node, i), pre, post, env);
492       current_ir_graph = rem;
493     }
494
495     if (post) post(node, env);
496   }
497   return;
498 }
499
500
501 /* Walks all irgs in interprocedural view.  Visits each node only once. */
502 void cg_walk(irg_walk_func *pre, irg_walk_func *post, void *env) {
503   int i;
504   ir_graph *rem = current_ir_graph;
505   int rem_view = get_interprocedural_view();
506
507   set_interprocedural_view(1);
508
509   inc_max_irg_visited();
510   /* Fix all irg_visited flags */
511   for (i = 0; i < get_irp_n_irgs(); i++)
512     set_irg_visited(get_irp_irg(i), get_max_irg_visited());
513
514   /* Walk starting at unreachable procedures. Only these
515    * have End blocks visible in interprocedural view. */
516   for (i = 0; i < get_irp_n_irgs(); i++) {
517     ir_node *sb;
518     current_ir_graph = get_irp_irg(i);
519
520     sb = get_irg_start_block(current_ir_graph);
521
522     if ((get_Block_n_cfgpreds(sb) > 1) ||
523     (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
524
525     cg_walk_2(get_irg_end(current_ir_graph), pre, post, env);
526   }
527
528   /* Check whether we walked all procedures: there could be procedures
529      with cyclic calls but no call from the outside. */
530   for (i = 0; i < get_irp_n_irgs(); i++) {
531     ir_node *sb;
532     current_ir_graph = get_irp_irg(i);
533
534     /* Test start block: if inner procedure end and end block are not
535      * visible and therefore not marked. */
536     sb = get_irg_start_block(current_ir_graph);
537     if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) {
538       cg_walk_2(sb, pre, post, env);
539     }
540   }
541
542   /* Walk all endless loops in inner procedures.
543    * We recognize an inner procedure if the End node is not visited. */
544   for (i = 0; i < get_irp_n_irgs(); i++) {
545     ir_node *e;
546     current_ir_graph = get_irp_irg(i);
547     e = get_irg_end(current_ir_graph);
548     if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
549       int j;
550       /* Don't visit the End node. */
551       for (j = 0; j < get_End_n_keepalives(e); j++)
552     cg_walk_2(get_End_keepalive(e, j), pre, post, env);
553     }
554   }
555
556   set_interprocedural_view(rem_view);
557   current_ir_graph = rem;
558 }
559
560
561 /***************************************************************************/
562
563 /* Walks back from n until it finds a real cf op. */
564 static ir_node *get_cf_op(ir_node *n) {
565   ir_node *pred;
566
567   n = skip_Id(n);
568   n = skip_Tuple(n);
569   pred = skip_Proj(n);
570   if (!(is_cfop(pred) || is_fragile_op(pred) || is_Bad(pred)))
571     n = get_cf_op(n);
572
573   return skip_Proj(n);
574 }
575
576 static void irg_block_walk_2(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env)
577 {
578   int i;
579
580   if (Block_not_block_visited(node)) {
581     mark_Block_block_visited(node);
582
583     if(pre) pre(node, env);
584
585     for(i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
586       /* find the corresponding predecessor block. */
587       ir_node *pred = get_cf_op(get_Block_cfgpred(node, i));
588       pred = get_nodes_block(pred);
589       if(get_irn_opcode(pred) == iro_Block) {
590         /* recursion */
591         irg_block_walk_2(pred, pre, post, env);
592       }
593       else {
594         assert(get_irn_opcode(pred) == iro_Bad);
595       }
596     }
597
598     if(post) post(node, env);
599   }
600   return;
601 }
602
603
604 /* walks only over Block nodes in the graph.  Has it's own visited
605    flag, so that it can be interleaved with the other walker.         */
606 void irg_block_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env)
607 {
608   ir_node *block, *pred;
609   int i;
610
611   hook_irg_block_walk(current_ir_graph, node, (generic_func *)pre, (generic_func *)post);
612
613   assert(node);
614   assert(!get_interprocedural_view());   /* interprocedural_view not implemented, because it
615                     * interleaves with irg_walk */
616   set_using_block_visited(current_ir_graph);
617   inc_irg_block_visited(current_ir_graph);
618   block = is_Block(node) ? node : get_nodes_block(node);
619   assert(get_irn_op(block) == op_Block);
620   irg_block_walk_2(block, pre, post, env);
621
622   /* keepalive: the endless loops ... */
623   if (get_irn_op(node) == op_End) {
624     int arity = get_irn_arity(node);
625     for (i = 0; i < arity; i++) {
626       pred = get_irn_n(node, i);
627       if (get_irn_op(pred) == op_Block)
628         irg_block_walk_2(pred, pre, post, env);
629     }
630     /* Sometimes the blocks died, but are still reachable through Phis.
631      * Make sure the algorithms that try to remove these reach them. */
632     for (i = 0; i < arity; i++) {
633       pred = get_irn_n(node, i);
634       if (get_irn_op(pred) == op_Phi) {
635         ir_node *block = get_nodes_block(pred);
636
637         if (! is_Bad(block))
638           irg_block_walk_2(block, pre, post, env);
639       }
640     }
641   }
642
643   clear_using_block_visited(current_ir_graph);
644 }
645
646 /*
647  * walk over a graph block wise
648  */
649 void irg_block_walk_graph(ir_graph *irg, irg_walk_func *pre,
650               irg_walk_func *post, void *env) {
651   ir_graph * rem = current_ir_graph;
652   current_ir_graph = irg;
653   irg_block_walk(get_irg_end(irg), pre, post, env);
654   current_ir_graph = rem;
655 }
656
657 /*
658  * Additionally walk over all anchors. Do NOT increase the visit flag.
659  */
660 void irg_walk_anchors(ir_graph *irg, irg_walk_func *pre, irg_walk_func *post, void *env) {
661   int i;
662   ir_graph * rem = current_ir_graph;
663   current_ir_graph = irg;
664
665   for (i = 0; i < anchor_max; ++i) {
666     ir_node *anchor = irg->anchors[i];
667
668     irg_walk_2(anchor, pre, post, env);
669   }
670   current_ir_graph = rem;
671 }
672
673 /********************************************************************/
674
675 typedef struct walk_env {
676   irg_walk_func *pre;
677   irg_walk_func *post;
678   void *env;
679 } walk_env;
680
681 /**
682  * Walk to all constant expressions in this entity.
683  */
684 static void walk_entity(ir_entity *ent, void *env)
685 {
686   walk_env *my_env = (walk_env *)env;
687
688   if (get_entity_variability(ent) != variability_uninitialized) {
689     if (is_atomic_entity(ent)) {
690       irg_walk(get_atomic_ent_value(ent), my_env->pre, my_env->post, my_env->env);
691     }
692     else {
693       int i, n_vals = get_compound_ent_n_values(ent);
694
695       for (i = 0; i < n_vals; i++)
696         irg_walk(get_compound_ent_value(ent, i), my_env->pre, my_env->post, my_env->env);
697     }
698   }
699 }
700
701 /* Walks over all code in const_code_irg. */
702 void walk_const_code(irg_walk_func *pre, irg_walk_func *post, void *env) {
703   int i, j;
704   walk_env my_env;
705
706   ir_graph *rem = current_ir_graph;
707   current_ir_graph = get_const_code_irg();
708   inc_irg_visited(current_ir_graph);
709
710   my_env.pre = pre;
711   my_env.post = post;
712   my_env.env = env;
713
714   /* Walk all types that can contain constant entities.  */
715   walk_types_entities(get_glob_type(), &walk_entity, &my_env);
716   for (i = 0; i < get_irp_n_types(); i++)
717     walk_types_entities(get_irp_type(i), &walk_entity, &my_env);
718   for (i = 0; i < get_irp_n_irgs(); i++)
719     walk_types_entities(get_irg_frame_type(get_irp_irg(i)), &walk_entity, &my_env);
720
721   /* Walk constant array bounds. */
722   for (i = 0; i < get_irp_n_types(); i++) {
723     ir_type *tp = get_irp_type(i);
724     if (is_Array_type(tp)) {
725       for (j = 0; j < get_array_n_dimensions(tp); j++) {
726         ir_node *n = get_array_lower_bound(tp, j);
727         if (n) irg_walk(n, pre, post, env);
728         n = get_array_upper_bound(tp, j);
729         if (n) irg_walk(n, pre, post, env);
730       }
731     }
732   }
733
734   current_ir_graph = rem;
735 }