X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbesched.c;h=d9bcb8c95360e4283068913551490df0b298917f;hb=557b24d620738753fda7d0137575f4d12a996b36;hp=a588458457016fbf41ef2259c8a94836b0baff77;hpb=e75b04273cb928f5a2dfd63326b147c7a26857da;p=libfirm diff --git a/ir/be/besched.c b/ir/be/besched.c index a58845845..d9bcb8c95 100644 --- a/ir/be/besched.c +++ b/ir/be/besched.c @@ -1,3 +1,5 @@ +/* $Id$ */ + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -12,6 +14,7 @@ #include "irnode_t.h" #include "irgraph_t.h" #include "iredges_t.h" +#include "ircons.h" #include "debug.h" #include "bearch.h" @@ -258,3 +261,51 @@ ir_node **sched_create_block_schedule(ir_graph *irg) } return blk_list; } + +typedef struct remove_dead_nodes_env_t_ { + ir_graph *irg; + bitset_t *reachable; +} remove_dead_nodes_env_t; + +static void mark_dead_nodes_walker(ir_node *node, void *data) +{ + remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data; + bitset_set(env->reachable, get_irn_idx(node)); +} + +static void remove_dead_nodes_walker(ir_node *block, void *data) +{ + remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data; + ir_node *node; + + for(node = sched_first(block); !sched_is_end(node); ) { + // get next node now, as after calling sched_remove it will be invalid + ir_node* next = sched_next(node); + int i, arity; + + if(bitset_is_set(env->reachable, get_irn_idx(node))) { + node = next; + continue; + } + + sched_remove(node); + arity = get_irn_arity(node); + for(i = 0; i < arity; ++i) + set_irn_n(node, i, new_r_Bad(env->irg)); + + node = next; + } +} + +void be_remove_dead_nodes_from_schedule(ir_graph *irg) +{ + remove_dead_nodes_env_t env; + env.irg = irg; + env.reachable = bitset_alloca(get_irg_last_idx(irg)); + + // mark all reachable nodes + irg_walk_graph(irg, mark_dead_nodes_walker, NULL, &env); + + // walk schedule and remove non-marked nodes + irg_block_walk_graph(irg, remove_dead_nodes_walker, NULL, &env); +}