From: Götz Lindenmaier Date: Tue, 9 Mar 2004 14:10:22 +0000 (+0000) Subject: bugfixes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=bbba4631276380ff7e88dbc70a3b8fb89cb96899;p=libfirm bugfixes [r2515] --- diff --git a/ir/ana/cgana.c b/ir/ana/cgana.c index a750e0241..619c30465 100644 --- a/ir/ana/cgana.c +++ b/ir/ana/cgana.c @@ -209,12 +209,22 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) { if (get_optimize() && get_opt_dyn_meth_dispatch() && (get_irn_op(skip_Proj(get_Sel_ptr(node))) == op_Alloc)) { ir_node *new_node; + entity *called_ent; /* We know which method will be called, no dispatch necessary. */ +#if 0 assert(get_entity_peculiarity(ent) != peculiarity_description); set_irg_current_block(current_ir_graph, get_nodes_Block(node)); /* @@@ Is this correct?? Alloc could reference a subtype of the owner of Sel that overwrites the method referenced in Sel. */ + /* @@@ Yes, this is wrong. GL, 10.3.04 */ new_node = copy_const_value(get_atomic_ent_value(ent)); DBG_OPT_POLY_ALLOC; +#else + called_ent = resolve_ent_polymorphy(get_Alloc_type(skip_Proj(get_Sel_ptr(node))), ent); + set_irg_current_block(current_ir_graph, get_nodes_Block(node)); + /* called_ent may not be description: has no Address/Const to Call! */ + assert(get_entity_peculiarity(called_ent) != peculiarity_description); + new_node = copy_const_value(get_atomic_ent_value(called_ent)); DBG_OPT_POLY_ALLOC; +#endif exchange (node, new_node); } else { assert(get_entity_peculiarity(ent) != peculiarity_inherited); @@ -508,6 +518,7 @@ static void callee_ana(void) { /* Alle Graphen analysieren. */ for (i = get_irp_n_irgs() - 1; i >= 0; --i) { irg_walk_graph(get_irp_irg(i), callee_walker, NULL, NULL); + set_irg_callee_info_state(get_irp_irg(i), irg_callee_info_consistent); } } diff --git a/ir/ir/ircgcons.c b/ir/ir/ircgcons.c index 75f40ccf2..dd9af4a77 100644 --- a/ir/ir/ircgcons.c +++ b/ir/ir/ircgcons.c @@ -830,5 +830,6 @@ void cg_destruct(void) { irg_walk_graph(irg, destruct_walker, clear_link, NULL); set_irg_frame(irg, skip_nop(get_irg_frame(irg))); set_irg_globals(irg, skip_nop(get_irg_globals(irg))); + set_irg_callee_info_state(irg, irg_callee_info_none); } } diff --git a/ir/ir/irgopt.c b/ir/ir/irgopt.c index 3ac0ec54c..e170b8fce 100644 --- a/ir/ir/irgopt.c +++ b/ir/ir/irgopt.c @@ -412,6 +412,7 @@ dead_node_elimination(ir_graph *irg) { /* Handle graph state */ assert(get_irg_phase_state(current_ir_graph) != phase_building); + assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none); free_outs(current_ir_graph); /* @@@ so far we loose loops when copying */ @@ -571,7 +572,6 @@ void inline_method(ir_node *call, ir_graph *called_graph) { ir_node **res_pred; ir_node **cf_pred; ir_node *ret, *phi; - ir_node *cf_op = NULL, *bl; int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity; int exc_handling; ir_node *proj; type *called_frame; @@ -972,6 +972,7 @@ void inline_small_irgs(ir_graph *irg, int size) { current_ir_graph = irg; /* Handle graph state */ assert(get_irg_phase_state(current_ir_graph) != phase_building); + assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none); /* Find Call nodes to inline. (We can not inline during a walk of the graph, as inlineing the same @@ -1081,6 +1082,7 @@ void inline_leave_functions(int maxsize, int leavesize, int size) { for (i = 0; i < n_irgs; ++i) { current_ir_graph = get_irp_irg(i); assert(get_irg_phase_state(current_ir_graph) != phase_building); + assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none); irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2, get_irg_link(current_ir_graph)); diff --git a/ir/ir/irgopt.h b/ir/ir/irgopt.h index 0c249a206..e85fd4e65 100644 --- a/ir/ir/irgopt.h +++ b/ir/ir/irgopt.h @@ -38,6 +38,8 @@ void local_optimize_graph (ir_graph *irg); Backedge information is conserved. Removes old attributes of nodes. Sets link field to NULL. + Callee information must be freed (irg_callee_info_none). + Attention: the numbers assigned to nodes if the library is compiled for development/debugging are not conserved by copying. */ void dead_node_elimination(ir_graph *irg); diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index 652f3b9fb..3356e91c5 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -71,6 +71,7 @@ new_ir_graph (entity *ent, int n_loc) ir_node *projX; res = (ir_graph *) malloc (sizeof (ir_graph)); + memset(res, 0, sizeof (ir_graph)); res->kind=k_ir_graph; current_ir_graph = res; @@ -533,6 +534,15 @@ set_irg_pinned (ir_graph *irg, op_pinned p) { irg->pinned = p; } + +irg_callee_info_state get_irg_callee_info_state(ir_graph *irg) { + return irg->callee_info_state; +} + +void set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s) { + irg->callee_info_state = s; +} + INLINE void set_irg_link (ir_graph *irg, void *thing) { irg->link = thing; diff --git a/ir/ir/irgraph.h b/ir/ir/irgraph.h index c4a18f239..fae83fa1b 100644 --- a/ir/ir/irgraph.h +++ b/ir/ir/irgraph.h @@ -254,6 +254,17 @@ irg_loopinfo_state get_irg_loopinfo_state(ir_graph *irg); void set_irg_loopinfo_inconsistent(ir_graph *irg); +/** state: callee_information_state + * Call nodes contain a list of possible callees. This list must be + * computed by an anlyses. */ +typedef enum { + irg_callee_info_none, + irg_callee_info_consistent, + irg_callee_info_inconsistent +} irg_callee_info_state; +irg_callee_info_state get_irg_callee_info_state(ir_graph *irg); +void set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s); + /* A void * field to link arbritary information to the node. */ void set_irg_link (ir_graph *irg, void *thing); void *get_irg_link (ir_graph *irg); diff --git a/ir/ir/irgraph_t.h b/ir/ir/irgraph_t.h index 0d0740c33..4b8a0b546 100644 --- a/ir/ir/irgraph_t.h +++ b/ir/ir/irgraph_t.h @@ -60,7 +60,8 @@ struct ir_graph { op_pinned pinned; /**< Flag for status of nodes */ irg_outs_state outs_state; /**< Out edges. */ irg_dom_state dom_state; /**< Dominator information */ - irg_typeinfo_state typeinfo_state; /**< Validity of type inforamtion */ + irg_typeinfo_state typeinfo_state; /**< Validity of type information */ + irg_callee_info_state callee_info_state; /**< Validity of callee information */ /* -- Fields for construction -- */ #if USE_EXPLICIT_PHI_IN_STACK diff --git a/ir/ir/irnode.h b/ir/ir/irnode.h index ed1b16767..1e655b0e6 100644 --- a/ir/ir/irnode.h +++ b/ir/ir/irnode.h @@ -448,6 +448,7 @@ INLINE int get_Call_arity (ir_node *node); int Call_has_callees (ir_node *node); int get_Call_n_callees (ir_node * node); entity *get_Call_callee (ir_node * node, int pos); +/* assumes current_ir_graph set properly! */ void set_Call_callee_arr (ir_node * node, int n, entity ** arr); void remove_Call_callee_arr(ir_node * node); diff --git a/ir/tr/entity.c b/ir/tr/entity.c index 0cd48b932..2bee18370 100644 --- a/ir/tr/entity.c +++ b/ir/tr/entity.c @@ -894,3 +894,28 @@ INLINE bool entity_visited(entity *ent) { INLINE bool entity_not_visited(entity *ent) { return get_entity_visited(ent) < type_visited; } + +/* Need two routines because I want to assert the result. */ +static INLINE entity *resolve_ent_polymorphy2 (type *dynamic_class, entity* static_ent) { + int i, n_overwrittenby; + entity *res = NULL; + + if (get_entity_owner(static_ent) == dynamic_class) return static_ent; + + n_overwrittenby = get_entity_n_overwrittenby(static_ent); + for (i = 0; i < n_overwrittenby; ++i) { + res = resolve_ent_polymorphy2(dynamic_class, get_entity_overwrittenby(static_ent, i)); + if (res) break; + } + + return res; +} + +/* Returns the dynamically referenced entity if the static entity and the + * dynamic type are given. + * Search downwards in overwritten tree. */ +entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent) { + entity *res = resolve_ent_polymorphy2(dynamic_class, static_ent); + assert(res); + return res; +} diff --git a/ir/tr/entity.h b/ir/tr/entity.h index 72ac0bf1f..6938e1187 100644 --- a/ir/tr/entity.h +++ b/ir/tr/entity.h @@ -451,4 +451,8 @@ bool entity_visited(entity *ent); /** Returns true if this entity was not visited. */ bool entity_not_visited(entity *ent); +/** Returns the dynamically referenced entity if the static entity and the + * dynamic type are given. */ +entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent); + # endif /* _ENTITY_H_ */