X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fldstopt.c;h=d792260b51e0cb116192141acdd3385c630230bf;hb=9bea3d74018e82f653deadff88f8626fd1a6557d;hp=7ad1fbe42e0423b686308fcbe691042b3f4cb3aa;hpb=a18f7145f262acfbe98d573077ff0795d33128bc;p=libfirm diff --git a/ir/opt/ldstopt.c b/ir/opt/ldstopt.c index 7ad1fbe42..d792260b5 100644 --- a/ir/opt/ldstopt.c +++ b/ir/opt/ldstopt.c @@ -8,6 +8,20 @@ * Copyright: (c) 1998-2004 Universität Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_ALLOCA_H +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_STRING_H +# include +#endif + # include "irnode_t.h" # include "irgraph_t.h" # include "irmode_t.h" @@ -21,7 +35,7 @@ # include "iropt_dbg.h" # include "irflag_t.h" # include "array.h" -# include "firmstat.h" +# include "irhooks.h" #undef IMAX #define IMAX(a,b) ((a) > (b) ? (a) : (b)) @@ -219,6 +233,60 @@ static void collect_nodes(ir_node *node, void *env) } } +/** + * returns a entity if the address ptr points to a constant one. + */ +static entity *find_constant_entity(ir_node *ptr) +{ + for (;;) { + ir_op *op = get_irn_op(ptr); + + if (op == op_SymConst && (get_SymConst_kind(ptr) == symconst_addr_ent)) { + return get_SymConst_entity(ptr); + } + else if (op == op_Sel) { + entity *ent = get_Sel_entity(ptr); + type *tp = get_entity_owner(ent); + + if (is_Array_type(tp)) { + /* check bounds */ + int i, n; + + for (i = 0, n = get_Sel_n_indexs(ptr); i < n; ++i) { + ir_node *bound; + tarval *tlower, *tupper; + ir_node *index = get_Sel_index(ptr, i); + tarval *tv = computed_value(index); + + /* check if the index is constant */ + if (tv == tarval_bad) + return NULL; + + bound = get_array_lower_bound(tp, i); + tlower = computed_value(bound); + bound = get_array_upper_bound(tp, i); + tupper = computed_value(bound); + + if (tlower == tarval_bad || tupper == tarval_bad) + return NULL; + + if (tarval_cmp(tv, tlower) & pn_Cmp_Lt) + return NULL; + if (tarval_cmp(tupper, tv) & pn_Cmp_Lt) + return NULL; + + /* ok, bounds check finished */ + } + } + + /* try next */ + ptr = get_Sel_ptr(ptr); + } + else + return NULL; + } +} + /** * optimize a Load */ @@ -227,6 +295,7 @@ static int optimize_load(ir_node *load) ldst_info_t *info = get_irn_link(load); ir_mode *load_mode = get_Load_mode(load); ir_node *pred, *mem, *ptr; + entity *ent; int res = 0; /* the address of the load to be optimized */ @@ -285,11 +354,9 @@ static int optimize_load(ir_node *load) /* the mem of the Load. Must still be returned after optimization */ mem = get_Load_mem(load); - if ((get_irn_opcode(ptr) == iro_SymConst) && (get_SymConst_kind(ptr) == symconst_addr_ent)) { - entity *ent = get_SymConst_entity(ptr); - - assert(mode_is_reference(get_irn_mode(ptr))); - + /* check if we can determine the entity that will be loaded */ + ent = find_constant_entity(ptr); + if (ent) { if ((allocation_static == get_entity_allocation(ent)) && (visibility_external_allocated != get_entity_visibility(ent))) { /* a static allocation that is not external: there should be NO exception @@ -315,10 +382,20 @@ static int optimize_load(ir_node *load) exchange(info->projs[pn_Load_M], mem); /* no result :-) */ - if (info->projs[pn_Load_res]) - exchange(info->projs[pn_Load_res], copy_const_value(get_atomic_ent_value(ent))); + if (info->projs[pn_Load_res]) { + if (is_atomic_entity(ent)) { + ir_node *c = copy_const_value(get_atomic_ent_value(ent)); - return 1; + DBG_OPT_RC(load, c); + exchange(info->projs[pn_Load_res], c); + + return 1; + } + } + } + else if (variability_constant == get_entity_variability(ent)) { + printf(">>>>>>>>>>>>> Found access to constant entity %s in function %s\n", get_entity_name(ent), + get_entity_name(get_irg_entity(current_ir_graph))); } /* we changed the irg, but try further */ @@ -358,7 +435,7 @@ static int optimize_load(ir_node *load) */ if ((!pred_info->projs[pn_Store_X_except] && !info->projs[pn_Load_X_except]) || get_nodes_block(load) == get_nodes_block(pred)) { - DBG_OPT_RAW(pred, load); + DBG_OPT_RAW(load, pred); exchange( info->projs[pn_Load_res], get_Store_value(pred) ); if (info->projs[pn_Load_M]) @@ -384,7 +461,7 @@ static int optimize_load(ir_node *load) if (! info->projs[pn_Load_X_except] || get_nodes_block(load) == get_nodes_block(pred)) { ldst_info_t *pred_info = get_irn_link(pred); - DBG_OPT_RAR(pred, load); + DBG_OPT_RAR(load, pred); if (pred_info->projs[pn_Load_res]) { /* we need a data proj from the previous load for this optimization */ @@ -476,7 +553,7 @@ static int optimize_store(ir_node *store) * We may remove the second Store, if it does not have an exception handler. */ if (! info->projs[pn_Store_X_except]) { - DBG_OPT_WAR(pred, store); + DBG_OPT_WAR(store, pred); exchange( info->projs[pn_Store_M], mem ); return 1; }