+ * @file
+ * @brief Functions for traversing ir graphs
+ * @author Boris Boesler, Goetz Lindenmaier, Michael Beck
+ * @version $Id$
+ * @summary
+ * traverse an ir graph
+ * - execute the pre function before recursion
+ * - execute the post function after recursion
+ */
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "irnode_t.h"
+#include "irgraph_t.h"
+#include "irprog.h"
+#include "irgwalk.h"
+#include "irhooks.h"
+#include "ircgcons.h"
+#include "entity_t.h"
+
+#include "error.h"
+#include "pset_new.h"
+#include "array.h"
+
+#ifdef INTERPROCEDURAL_VIEW
+/**
+ * Walk over an interprocedural graph (callgraph).
+ * Visits only graphs in irg_set.
+ */
+static void irg_walk_cg(ir_node * node, ir_visited_t visited,
+ pset_new_t *irg_set, irg_walk_func *pre,
+ irg_walk_func *post, void * env)
+{
+ int i;
+ ir_graph * rem = current_ir_graph;
+ ir_node * pred;
+
+ assert(node && node->kind == k_ir_node);
+ if (get_irn_visited(node) >= visited) return;
+
+ set_irn_visited(node, visited);
+
+ if (pre) pre(node, env);
+
+ pred = skip_Proj(node);
+ if (is_CallBegin(pred) ||
+ get_irn_op(pred) == op_EndReg ||
+ get_irn_op(pred) == op_EndExcept) {
+ current_ir_graph = get_irn_irg(pred);
+ }
+
+ if (is_no_Block(node)) { /* not block */
+ irg_walk_cg(get_nodes_block(node), visited, irg_set, pre, post, env);
+ }
+
+ if (is_Block(node)) { /* block */
+ for (i = get_irn_arity(node) - 1; i >= 0; --i) {
+ ir_node * exec = get_irn_n(node, i);
+ ir_node * pred = skip_Proj(exec);
+ if ((
+ !is_CallBegin(pred) &&
+ get_irn_op(pred) != op_EndReg &&
+ get_irn_op(pred) != op_EndExcept
+ ) || pset_new_contains(irg_set, get_irn_irg(pred))) {
+ irg_walk_cg(exec, visited, irg_set, pre, post, env);
+ }
+ }
+ } else if (is_Filter(node)) { /* filter */
+ for (i = get_irn_arity(node) - 1; i >= 0; --i) {
+ ir_node * pred = get_irn_n(node, i);
+ if (is_Unknown(pred) || is_Bad(pred)) {
+ irg_walk_cg(pred, visited, irg_set, pre, post, env);
+ } else {
+ ir_node * exec;
+ exec = skip_Proj(get_Block_cfgpred(get_nodes_block(node), i));
+
+ if (is_Bad(exec)) {
+ continue;
+ }
+
+ assert(is_CallBegin(exec) ||
+ get_irn_op(exec) == op_EndReg ||
+ get_irn_op(exec) == op_EndExcept);
+ if (pset_new_contains(irg_set, get_irn_irg(exec))) {
+ current_ir_graph = get_irn_irg(exec);
+ irg_walk_cg(pred, visited, irg_set, pre, post, env);
+ current_ir_graph = rem;
+ }
+ }
+ }
+ } else { /* everything else */
+ for (i = get_irn_arity(node) - 1; i >= 0; --i) {
+ irg_walk_cg(get_irn_n(node, i), visited, irg_set, pre, post, env);
+ }
+ }
+
+ if (post) post(node, env);