From e64d870786b1564302c650e90eb9d3e5599b139e Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 17 Jun 2010 09:22:34 +0000 Subject: [PATCH] implement node walker in direction of out-edges [r27631] --- include/libfirm/iredges.h | 3 +++ ir/ir/iredges.c | 48 +++++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/libfirm/iredges.h b/include/libfirm/iredges.h index a13b58bb8..f9d29b04f 100644 --- a/include/libfirm/iredges.h +++ b/include/libfirm/iredges.h @@ -266,6 +266,9 @@ FIRM_API void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, FIRM_API void irg_block_edges_walk(ir_node *block, irg_walk_func *pre, irg_walk_func *post, void *env); +FIRM_API void irg_walk_edges(ir_node *start, irg_walk_func *pre, + irg_walk_func *post, void *env); + /** * Reset the user's private data at offset 'offset' * The user has to remember his offset and the size of his data! diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index 9a345e76d..d9cc65824 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -1074,6 +1074,44 @@ int (get_irn_n_edges_kind)(const ir_node *irn, ir_edge_kind_t kind) return _get_irn_n_edges_kind(irn, kind); } +static void irg_walk_edges2(ir_node *node, irg_walk_func *pre, + irg_walk_func *post, void *env) +{ + const ir_edge_t *edge, *next; + + if (irn_visited(node)) + return; + mark_irn_visited(node); + + if (pre != NULL) + pre(node, env); + + foreach_out_edge_kind_safe(node, edge, next, EDGE_KIND_NORMAL) { + /* find the corresponding successor block. */ + ir_node *pred = get_edge_src_irn(edge); + irg_walk_edges2(pred, pre, post, env); + } + + if (post != NULL) + post(node, env); +} + +void irg_walk_edges(ir_node *node, irg_walk_func *pre, irg_walk_func *post, + void *env) +{ + ir_graph *irg = get_irn_irg(node); + + assert(edges_activated(irg)); + assert(is_Block(node)); + + ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED); + + inc_irg_visited(irg); + irg_walk_edges2(node, pre, post, env); + + ir_free_resources(irg, IR_RESOURCE_IRN_VISITED); +} + static void irg_block_edges_walk2(ir_node *bl, irg_walk_func *pre, irg_walk_func *post, void *env) { @@ -1099,13 +1137,15 @@ static void irg_block_edges_walk2(ir_node *bl, irg_walk_func *pre, void irg_block_edges_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void *env) { - assert(edges_activated(current_ir_graph)); + ir_graph *irg = get_irn_irg(node); + + assert(edges_activated(irg)); assert(is_Block(node)); - ir_reserve_resources(current_ir_graph, IR_RESOURCE_BLOCK_VISITED); + ir_reserve_resources(irg, IR_RESOURCE_BLOCK_VISITED); - inc_irg_block_visited(current_ir_graph); + inc_irg_block_visited(irg); irg_block_edges_walk2(node, pre, post, env); - ir_free_resources(current_ir_graph, IR_RESOURCE_BLOCK_VISITED); + ir_free_resources(irg, IR_RESOURCE_BLOCK_VISITED); } -- 2.20.1