From a63ae9728ba0fbe891a2bb6c291c41b0e618af62 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Tue, 20 Jan 2009 01:20:08 +0000 Subject: [PATCH] - teach the analyzer how to handle inner functions [r25276] --- ir/ana/irmemory.c | 52 ++++++++++++++++++++++++++++++++++++----- ir/opt/scalar_replace.c | 38 +++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/ir/ana/irmemory.c b/ir/ana/irmemory.c index db1f94cfc..84ff2954f 100644 --- a/ir/ana/irmemory.c +++ b/ir/ana/irmemory.c @@ -909,16 +909,19 @@ static ir_entity_usage determine_entity_usage(const ir_node *irn, ir_entity *ent */ static void analyse_irg_entity_usage(ir_graph *irg) { ir_type *ft = get_irg_frame_type(irg); - ir_node *irg_frame; - int i; + ir_node *irg_frame, *args, *arg; + int i, j, k, static_link_arg; /* set initial state to not_taken, as this is the "smallest" state */ for (i = get_class_n_members(ft) - 1; i >= 0; --i) { - ir_entity *ent = get_class_member(ft, i); - ir_entity_usage flags = - get_entity_stickyness(ent) == stickyness_sticky ? ir_usage_unknown : 0; + ir_entity *ent = get_class_member(ft, i); - set_entity_usage(ent, flags); + /* methods can only be analyzed globally */ + if (! is_method_entity(ent)) { + ir_entity_usage flags = + get_entity_stickyness(ent) == stickyness_sticky ? ir_usage_unknown : 0; + set_entity_usage(ent, flags); + } } assure_irg_outs(irg); @@ -939,6 +942,43 @@ static void analyse_irg_entity_usage(ir_graph *irg) { set_entity_usage(entity, flags); } + /* check inner functions accessing outer frame */ + static_link_arg = 0; + for (i = get_class_n_members(ft) - 1; i >= 0; --i) { + ir_entity *ent = get_class_member(ft, i); + + if (is_method_entity(ent)) { + ir_graph *inner_irg = get_entity_irg(ent); + ir_node *args; + + assure_irg_outs(inner_irg); + args = get_irg_args(inner_irg); + for (j = get_irn_n_outs(args) - 1; j >= 0; --j) { + ir_node *arg = get_irn_out(args, j); + + if (get_Proj_proj(arg) == static_link_arg) { + for (k = get_irn_n_outs(arg) - 1; k >= 0; --k) { + ir_node *succ = get_irn_out(arg, k); + + if (is_Sel(succ)) { + ir_entity *entity = get_Sel_entity(succ); + + if (get_entity_owner(entity) == ft) { + /* found an access to the outer frame */ + ir_entity_usage flags; + + flags = get_entity_usage(entity); + flags |= determine_entity_usage(succ, entity); + set_entity_usage(entity, flags); + } + } + } + } + } + } + } + + /* now computed */ irg->entity_usage_state = ir_entity_usage_computed; } diff --git a/ir/opt/scalar_replace.c b/ir/opt/scalar_replace.c index d0a1203b2..5e7a00e95 100644 --- a/ir/opt/scalar_replace.c +++ b/ir/opt/scalar_replace.c @@ -319,7 +319,7 @@ static void *ADDRESS_TAKEN = &_x; static int find_possible_replacements(ir_graph *irg) { ir_node *irg_frame; ir_type *frame_tp; - int i; + int i, j, k, static_link_arg; int res = 0; /* @@ -331,6 +331,38 @@ static int find_possible_replacements(ir_graph *irg) { set_entity_link(ent, NULL); } + /* check for inner functions: + * FIXME: need a way to get the argument position for the static link */ + static_link_arg = 0; + for (i = get_class_n_members(frame_tp) - 1; i >= 0; --i) { + ir_entity *ent = get_class_member(frame_tp, i); + if (is_method_entity(ent)) { + ir_graph *inner_irg = get_entity_irg(ent); + ir_node *args; + + assure_irg_outs(inner_irg); + args = get_irg_args(inner_irg); + for (j = get_irn_n_outs(args) - 1; j >= 0; --j) { + ir_node *arg = get_irn_out(args, j); + + if (get_Proj_proj(arg) == static_link_arg) { + for (k = get_irn_n_outs(arg) - 1; k >= 0; --k) { + ir_node *succ = get_irn_out(arg, k); + + if (is_Sel(succ)) { + ir_entity *ent = get_Sel_entity(succ); + + if (get_entity_owner(ent) == frame_tp) { + /* found an access to the outer frame */ + set_entity_link(ent, ADDRESS_TAKEN); + } + } + } + } + } + } + } + /* * Check the ir_graph for Sel nodes. If the entity of Sel * isn't a scalar replacement set the link of this entity @@ -652,11 +684,11 @@ int scalar_replacement_opt(ir_graph *irg) { /* we use the link firld to store the VNUM */ ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); - irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK); + irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK); /* Find possible scalar replacements */ if (find_possible_replacements(irg)) { - DB((dbg, SET_LEVEL_1, "Scalar Replacement: %s\n", get_entity_name(get_irg_entity(irg)))); + DB((dbg, SET_LEVEL_1, "Scalar Replacement: %+F\n", irg)); /* Insert in set the scalar replacements. */ irg_frame = get_irg_frame(irg); -- 2.20.1