X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_polymorphy.c;h=a0902b70642c4dfee4bb5288ec3a5c01eb00dbdc;hb=6b124543aff56817fcfe6d5b5ff181ac5c790e73;hp=c59eaab9db8594eaca43e2ad26644d99ec0d3a54;hpb=0d78d6a846ed88c044aa436e3bdf572d17a06a69;p=libfirm diff --git a/ir/opt/opt_polymorphy.c b/ir/opt/opt_polymorphy.c index c59eaab9d..a0902b706 100644 --- a/ir/opt/opt_polymorphy.c +++ b/ir/opt/opt_polymorphy.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -22,13 +22,12 @@ * @brief Optimize polymorphic Sel and Load nodes. * @author Goetz Lindenmaier, Michael Beck * @version $Id$ - * @summary + * @brief * This file subsumes optimization code from cgana. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif +#include "iroptimize.h" #include "irprog_t.h" #include "entity_t.h" #include "type_t.h" @@ -48,14 +47,12 @@ */ 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; } -typedef ir_type *(*get_Alloc_func)(ir_node *n); - /** The get_Alloc function */ static get_Alloc_func firm_get_Alloc = default_firm_get_Alloc; @@ -101,7 +98,8 @@ static ir_type *get_dynamic_type(ir_node *ptr) { /** * Check, if an entity is final, i.e. is not anymore overridden. */ -static int is_final_ent(ir_entity *ent) { +static int is_final_ent(ir_entity *ent) +{ if (is_entity_final(ent)) { /* not possible to override this entity. */ return 1; @@ -158,8 +156,6 @@ ir_node *transform_node_Sel(ir_node *node) { /* We know which method will be called, no dispatch necessary. */ called_ent = resolve_ent_polymorphy(dyn_tp, ent); - /* called_ent may not be description: has no Address/Const to Call! */ - assert(get_entity_peculiarity(called_ent) != peculiarity_description); rem_block = get_cur_block(); set_cur_block(get_nodes_block(node)); @@ -181,49 +177,47 @@ 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; + if ( !(get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) ) + 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); + 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; }