rename type entity into ir_entity
[libfirm] / ir / ana2 / irmemwalk.c
index b4768e9..bbb8e37 100644 (file)
 
 
 # ifdef HAVE_CONFIG_H
-#  include <config.h>
+#  include "config.h"
 # endif
 
+# include "irnode_t.h"
 # include "irgwalk.h"           /* for irg_walk_func */
+# include "irprog.h"            /* for get_irp_main_irg */
 # include "xmalloc.h"
+# include "gnu_ext.h"
 
 # ifndef TRUE
 #  define TRUE 1
    Data
 */
 
-/* environment for a single memory walker */
+/** environment for a single memory walker */
 typedef struct walk_mem_env_str {
-  ir_graph *graph;              /* the graph we're visiting */
-  int visited;                  /* 'visited' marker */
-  irg_walk_func *pre;           /* pre action */
-  irg_walk_func *post;          /* post action */
-  void *env;                    /* user-defined environment */
-
-  struct walk_mem_env_str *prev; /* link up walking instances */
+  ir_graph *graph;              /**< the graph we're visiting */
+  unsigned long visited;        /**< 'visited' marker
+                                 (unsigned long in case we walk more than 2^32 graphs) */
+  irg_walk_func *pre;           /**< pre action */
+  irg_walk_func *post;          /**< post action */
+  void *env;                    /**< user-defined environment */
+
+  struct walk_mem_env_str *prev; /**< link up walking instances */
   /* what else? */
 } walk_mem_env_t;
 
@@ -68,13 +72,24 @@ static void irg_walk_mem_node (ir_node *node,
   if (get_irn_visited (node) >= walk_env->visited) {
     return;
   } else {
-    set_irn_visited (node, walk_env->visited + 1);
+    set_irn_visited (node, walk_env->visited);
+  }
+
+  if (op_NoMem == get_irn_op (node)) {
+    /* We don't want to see it it if it's not memory */
+    return;
   }
 
-  fprintf (stdout, "Node (0x%08x).op = %s\n", (int)
-           node,
-           get_op_name (get_irn_op (node)));
+  if (iro_Proj == op) {
+    /* We don't want to see proj nodes at all --- skip over them */
+    in = get_Proj_pred (node);
 
+    irg_walk_mem_node (in, walk_env);
+
+    return;
+  }
+
+  /* execute the 'pre' function */
   if (NULL != walk_env->pre) {
     walk_env->pre (node, walk_env->env);
   }
@@ -122,16 +137,10 @@ static void irg_walk_mem_node (ir_node *node,
 
     irg_walk_mem_node (in, walk_env);
   } break;
-  case (iro_Proj): {
-    in = get_Proj_pred (node);
-
-    irg_walk_mem_node (in, walk_env);
-  } break;
   case (iro_Phi): {
     int i;
     int n_ins = get_irn_arity (node);
 
-
     for (i = 0; i < n_ins; i ++) {
       in = get_irn_n (node, i);
 
@@ -158,11 +167,28 @@ static void irg_walk_mem_node (ir_node *node,
 
     irg_walk_mem_node (in, walk_env);
   } break;
+  case (iro_Block): {
+    /* End Block ONLY */
+    int i;
+    int n_ins = get_irn_arity (node);
+
+    for (i = 0; i < n_ins; i ++) {
+      ir_node *ret = get_irn_n (node, i);
+
+      irg_walk_mem_node (ret, walk_env);
+    }
+  } break;
   default: {
+    fprintf (stderr, "%s: not handled: node[%li].op = %s\n",
+             __FUNCTION__,
+             get_irn_node_nr (node),
+             get_op_name (get_irn_op (node)));
+
     assert (0 && "something not handled");
   }
   }
 
+  /* execute the 'post' function */
   if (NULL != walk_env->post) {
     walk_env->post (node, walk_env->env);
   }
@@ -195,11 +221,8 @@ void irg_walk_mem (ir_graph *graph,
                    irg_walk_func *pre, irg_walk_func *post,
                    void *env)
 {
-  int i;
-  ir_node *ret = NULL;
-  ir_node *end = get_irg_end_block (graph);
-  int n_ins;
-  walk_mem_env_t *walk_env = (walk_mem_env_t*) xmalloc (sizeof (walk_mem_env_t));
+  ir_node *end_block = get_irg_end_block (graph);
+  walk_mem_env_t *walk_env = xmalloc (sizeof (walk_mem_env_t));
 
   assert (! get_irg_is_mem_visited (graph));
 
@@ -214,17 +237,16 @@ void irg_walk_mem (ir_graph *graph,
   walk_env->post = post;
   walk_env->env  = env;
 
-  /* 'graph' is not actually being visited right now, but it should be reported that way */
+  /* 'graph' is not actually being visited right now, so make sure it is reported that way */
   assert (get_irg_is_mem_visited (graph));
 
-  /* all return nodes */
-  n_ins = get_irn_arity (end);
-  for (i = 0; i < n_ins; i ++) {
-    ret = get_irn_n (end, i);
-
-    irg_walk_mem_node (ret, walk_env);
-  }
-
+  /*
+    The ins of the end BLOCK are either 'return's (regular exits) or
+    'ProjX'/'Raise's (exception exits).  We only walk over the
+    'return' nodes, assuming that all memory-changing nodes are found
+    from there on.
+  */
+  irg_walk_mem_node (end_block, walk_env);
   /*
     The end NODE sometimes has some more ins. not sure whether we need to walk them.
   */
@@ -237,3 +259,41 @@ void irg_walk_mem (ir_graph *graph,
 
   assert (! get_irg_is_mem_visited (graph));
 }
+
+\f
+
+/*
+  $Log$
+  Revision 1.11  2005/01/26 12:20:20  beck
+  gnu_ext.h included
+
+  Revision 1.10  2005/01/14 13:34:48  liekweg
+  Don't cast malloc
+
+  Revision 1.9  2005/01/10 17:26:34  liekweg
+  fixup printfs, don't put environments on the stack
+
+  Revision 1.8  2004/12/22 14:43:14  beck
+  made allocations C-like
+
+  Revision 1.7  2004/12/21 14:25:35  beck
+  removed C99 constructs
+  make visit counter of same type as irn visit counter
+
+  Revision 1.6  2004/12/02 16:17:51  beck
+  fixed config.h include
+
+  Revision 1.5  2004/11/19 10:35:20  liekweg
+  also test for NoMem
+
+  Revision 1.4  2004/11/18 16:35:11  liekweg
+  Do not touch Proj nodes at all
+
+  Revision 1.3  2004/11/04 14:57:12  liekweg
+  fixed end block handling
+
+  Revision 1.2  2004/10/22 14:41:12  liekweg
+  execute 'pre' for a change.  Also, add CVS log
+
+
+*/