X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana2%2Firmemwalk.c;h=bbb8e3701098218d79db2bc0772ee21ba20e3e95;hb=c53a503e81f6e7c0995fbbcc451c2178ad9083bd;hp=b4768e93e8d728429e19be3c5ed123128fa9b997;hpb=41b022e5d3a77bd3743f6a7b4444b13179dbd2e0;p=libfirm diff --git a/ir/ana2/irmemwalk.c b/ir/ana2/irmemwalk.c index b4768e93e..bbb8e3701 100644 --- a/ir/ana2/irmemwalk.c +++ b/ir/ana2/irmemwalk.c @@ -21,11 +21,14 @@ # ifdef HAVE_CONFIG_H -# include +# 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 @@ -36,15 +39,16 @@ 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)); } + + + +/* + $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 + + +*/