X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fscalar_replace.c;h=5e7a00e95540984ddb2540ed90428ffff57e8c04;hb=1cf669f14fb238c8cdcfe187714ff2f6579a784c;hp=9fcb8d55959bd0804a6d39a540a11e8d19c141ba;hpb=c2d7ef5e4abd85780c11a840856d8780beefb061;p=libfirm diff --git a/ir/opt/scalar_replace.c b/ir/opt/scalar_replace.c index 9fcb8d559..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 @@ -344,6 +376,11 @@ static int find_possible_replacements(ir_graph *irg) { ir_entity *ent = get_Sel_entity(succ); ir_type *ent_type; + /* we are only interested in entities on the frame, NOT + on the value type */ + if (get_entity_owner(ent) != frame_tp) + continue; + if (get_entity_link(ent) == ADDRESS_TAKEN) continue; @@ -647,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);