X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_polymorphy.c;h=b8fa9efc3a3118473cdeaed4f08481fcf944eedf;hb=4b734653b3f11a3182963369bb58980e4d5a62cb;hp=af26044359c3c7cc95b349232139c8a038a748e3;hpb=1ce363f80e6a204d4011f85813362d9bd1d0e7e4;p=libfirm diff --git a/ir/opt/opt_polymorphy.c b/ir/opt/opt_polymorphy.c index af2604435..b8fa9efc3 100644 --- a/ir/opt/opt_polymorphy.c +++ b/ir/opt/opt_polymorphy.c @@ -25,9 +25,7 @@ * @summary * This file subsumes optimization code from cgana. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include "iroptimize.h" #include "irprog_t.h" @@ -49,7 +47,7 @@ */ ir_type *default_firm_get_Alloc(ir_node *n) { n = skip_Proj(n); - if (get_irn_op(n) == op_Alloc) { + if (is_Alloc(n)) { return get_Alloc_type(n); } return NULL; @@ -182,49 +180,50 @@ ir_node *transform_node_Sel(ir_node *node) { * a tuple, or replace the Projs of the load. * Therefore we call this optimization in ldstopt(). */ -ir_node *transform_node_Load(ir_node *n) { - ir_node *field_ptr, *new_node, *ptr; +ir_node *transform_polymorph_Load(ir_node *load) { + ir_node *new_node = NULL; + ir_node *field_ptr, *ptr; ir_entity *ent; ir_type *dyn_tp; if (!(get_opt_optimize() && get_opt_dyn_meth_dispatch())) - return n; + return load; - field_ptr = get_Load_ptr(n); + field_ptr = get_Load_ptr(load); - if (! is_Sel(field_ptr)) return n; + if (! is_Sel(field_ptr)) return load; ent = get_Sel_entity(field_ptr); if ((get_entity_allocation(ent) != allocation_static) || (get_entity_variability(ent) != variability_constant) ) - return n; + return load; /* If the entity is a leave in the inheritance tree, we can replace the Sel by a constant. */ if ((get_irp_phase_state() != phase_building) && is_final_ent(ent)) { - new_node = copy_const_value(get_irn_dbg_info(n), get_atomic_ent_value(ent)); - DBG_OPT_POLY(field_ptr, new_node); - - return new_node; + new_node = get_atomic_ent_value(ent); + } else { + /* If we know the dynamic type, we can replace the Sel by a constant. */ + ptr = get_Sel_ptr(field_ptr); /* The address we select from. */ + dyn_tp = get_dynamic_type(ptr); /* The runtime type of ptr. */ + + if (dyn_tp != firm_unknown_type) { + ir_entity *loaded_ent; + + /* We know which method will be called, no dispatch necessary. */ + loaded_ent = resolve_ent_polymorphy(dyn_tp, ent); + /* called_ent may not be description: has no Address/Const to Call! */ + assert(get_entity_peculiarity(loaded_ent) != peculiarity_description); + new_node = get_atomic_ent_value(loaded_ent); + } } + if (new_node != NULL) { + new_node = can_replace_load_by_const(load, new_node); + if (new_node != NULL) { + DBG_OPT_POLY(field_ptr, new_node); - /* If we know the dynamic type, we can replace the Sel by a constant. */ - ptr = get_Sel_ptr(field_ptr); /* The address we select from. */ - dyn_tp = get_dynamic_type(ptr); /* The runtime type of ptr. */ - - if (dyn_tp != firm_unknown_type) { - ir_entity *loaded_ent; - - /* We know which method will be called, no dispatch necessary. */ - loaded_ent = resolve_ent_polymorphy(dyn_tp, ent); - /* called_ent may not be description: has no Address/Const to Call! */ - assert(get_entity_peculiarity(loaded_ent) != peculiarity_description); - - new_node = copy_const_value(get_irn_dbg_info(n), get_atomic_ent_value(loaded_ent)); - DBG_OPT_POLY(field_ptr, new_node); - - return new_node; + return new_node; + } } - - return n; + return load; }