From: Florian Liekweg Date: Wed, 14 Jul 2004 11:58:48 +0000 (+0000) Subject: Optionally do whole-program assumption; obey stickiness (OBEY) X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=c85be8caf0fb190e6560a76198d04cbc33fec004;p=libfirm Optionally do whole-program assumption; obey stickiness (OBEY) [r3440] --- diff --git a/ir/ana/cgana.c b/ir/ana/cgana.c index c481a0f14..2a4362493 100644 --- a/ir/ana/cgana.c +++ b/ir/ana/cgana.c @@ -84,7 +84,7 @@ static entity *get_inherited_methods_implementation(entity *inh_meth) { if (get_irn_op(addr) == op_Const) { impl_meth = tarval_to_entity(get_Const_tarval(addr)); } else if ((get_irn_op(addr) == op_SymConst) && - (get_SymConst_kind(addr) == symconst_addr_ent)) { + (get_SymConst_kind(addr) == symconst_addr_ent)) { impl_meth = get_SymConst_entity(addr); } else { assert(0 && "Complex constant values not supported -- address of method should be straight constant!"); @@ -144,7 +144,7 @@ static void collect_impls(entity *method, eset *set, int *size, bool *open) { } } } - /** recursive descend **/ + /** recursive descent **/ for (i = get_entity_n_overwrittenby(method) - 1; i >= 0; --i) collect_impls(get_entity_overwrittenby(method, i), set, size, open); } @@ -226,17 +226,17 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) { if (get_SymConst_kind(node) == symconst_addr_name) { pmap_entry * entry = pmap_find(ldname_map, (void *) get_SymConst_name(node)); if (entry != NULL) { /* Method is declared in the compiled code */ - entity * ent = entry->value; - if (get_opt_normalize() && (get_entity_visibility(ent) != visibility_external_allocated)) { /* Meth. is defined */ - ir_node *new_node; - symconst_symbol sym; - assert(get_entity_irg(ent)); - sym.entity_p = ent; - set_irg_current_block(current_ir_graph, get_nodes_Block(node)); - new_node = new_d_SymConst(get_irn_dbg_info(node), sym, symconst_addr_ent); DBG_OPT_NORMALIZE; - DDMN(new_node); - exchange(node, new_node); - } + entity * ent = entry->value; + if (get_opt_normalize() && (get_entity_visibility(ent) != visibility_external_allocated)) { /* Meth. is defined */ + ir_node *new_node; + symconst_symbol sym; + assert(get_entity_irg(ent)); + sym.entity_p = ent; + set_irg_current_block(current_ir_graph, get_nodes_Block(node)); + new_node = new_d_SymConst(get_irn_dbg_info(node), sym, symconst_addr_ent); DBG_OPT_NORMALIZE; + DDMN(new_node); + exchange(node, new_node); + } } } } else if (get_irn_op(node) == op_Sel && @@ -460,10 +460,10 @@ static void callee_ana_node(ir_node * node, eset * methods) { entity * ent = get_SymConst_entity(node); assert(ent && is_method_type(get_entity_type(ent))); if (get_entity_visibility(ent) != visibility_external_allocated) { - assert(get_entity_irg(ent)); - eset_insert(methods, ent); + assert(get_entity_irg(ent)); + eset_insert(methods, ent); } else { - eset_insert(methods, MARK); /* free method -> unknown */ + eset_insert(methods, MARK); /* free method -> unknown */ } } else { assert(get_SymConst_kind(node) == symconst_addr_name); @@ -478,8 +478,8 @@ static void callee_ana_node(ir_node * node, eset * methods) { assert(ent && is_method_type(get_entity_type(ent))); if (get_entity_visibility(ent) != visibility_external_allocated) { if (!get_entity_irg(ent)) { - dump_entity(ent); - assert(get_entity_irg(ent)); + dump_entity(ent); + assert(get_entity_irg(ent)); } eset_insert(methods, ent); } else { @@ -718,7 +718,7 @@ static void free_ana_walker(ir_node * node, eset * set) { for (i = get_Call_arity(node) - 1; i >= 0; --i) { ir_node * pred = get_Call_param(node, i); if (mode_is_reference(get_irn_mode(pred))) { - free_mark(pred, set); + free_mark(pred, set); } } break; @@ -743,23 +743,37 @@ static void free_ana_walker(ir_node * node, eset * set) { * SymConst-Operationen müssen in passende Const-Operationen * umgewandelt worden sein, d.h. SymConst-Operationen verweisen immer * auf eine echt externe Methode. */ -static entity ** get_free_methods(void) { +static entity ** get_free_methods(int whole) +{ eset * set = eset_create(); int i; entity ** arr = NEW_ARR_F(entity *, 0); entity * ent; + if (! whole) { + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + ir_graph * irg = get_irp_irg(i); + entity * ent = get_irg_ent(irg); + /* insert "external visible" methods. */ + if (get_entity_visibility(ent) != visibility_local) { + eset_insert(set, ent); + } + /* Finde alle Methoden die in dieser Methode extern sichtbar werden, + z.B. da die Adresse einer Methode abgespeichert wird. */ + irg_walk_graph(irg, NULL, (irg_walk_func *) free_ana_walker, set); + } + } + + /* insert sticky methods, too */ for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_graph * irg = get_irp_irg(i); entity * ent = get_irg_ent(irg); /* insert "external visible" methods. */ - if (get_entity_visibility(ent) != visibility_local) { + if (get_entity_stickyness (ent) == stickyness_sticky) { eset_insert(set, ent); } - /* Finde alle Methoden die in dieser Methode extern sichtbar werden, - z.B. da die Adresse einer Methode abgespeichert wird. */ - irg_walk_graph(irg, NULL, (irg_walk_func *) free_ana_walker, set); } + /* Hauptprogramm ist auch dann frei, wenn es nicht "external * visible" ist. */ if (get_irp_main_irg()) { @@ -774,12 +788,12 @@ static entity ** get_free_methods(void) { return arr; } -void cgana(int *length, entity ***free_methods) { +void cgana(int *length, entity ***free_methods, int whole) { entity ** free_meths; int i; sel_methods_init(); - free_meths = get_free_methods(); + free_meths = get_free_methods(whole); callee_ana(); sel_methods_dispose();