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);
/* 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);
}
}
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);
}
}
/* 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 */
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;
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
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));
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);
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;
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;
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);
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
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);
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;
+}
/** 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_ */