X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Firmemory.c;h=db1f94cfcfe7b1afdd22697b154e1ba8dd925f5c;hb=b47d39bb3bc9194300e0fed4a0289c27930b41a1;hp=90bb5352b015a68ad811a5c16b32a625a4d5b6eb;hpb=ace092feb0715fd976e4537f55dc735abe57d02f;p=libfirm diff --git a/ir/ana/irmemory.c b/ir/ana/irmemory.c index 90bb5352b..db1f94cfc 100644 --- a/ir/ana/irmemory.c +++ b/ir/ana/irmemory.c @@ -24,13 +24,12 @@ * @date 27.12.2006 * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include #include +#include "adt/pmap.h" #include "irnode_t.h" #include "irgraph_t.h" #include "irprog_t.h" @@ -44,9 +43,11 @@ #include "irprintf.h" #include "debug.h" #include "error.h" +#include "typerep.h" /** The debug handle. */ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) +DEBUG_ONLY(static firm_dbg_module_t *dbgcall = NULL;) /** The source language specific language disambiguator function. */ static DISAMBIGUATOR_FUNC language_disambuigator = NULL; @@ -333,6 +334,8 @@ static ir_alias_relation different_sel_offsets(ir_node *sel1, ir_node *sel2) { return have_no > 0 ? no_alias : sure_alias; } } +#else + (void) different_index; #endif return ir_may_alias; } /* different_sel_offsets */ @@ -363,13 +366,11 @@ static ir_alias_relation different_types(ir_node *adr1, ir_node *adr2) ir_type *tp2 = get_entity_type(ent2); if (tp1 != tp2) { -#if 0 /* do deref until no pointer types are found */ while (is_Pointer_type(tp1) && is_Pointer_type(tp2)) { tp1 = get_pointer_points_to_type(tp1); tp2 = get_pointer_points_to_type(tp2); } -#endif if (get_type_tpop(tp1) != get_type_tpop(tp2)) { /* different type structure */ @@ -439,6 +440,8 @@ ir_storage_class_class_t classify_pointer(ir_graph *irg, ir_node *irn, ir_entity res |= ir_sc_modifier_nottaken; } else if (is_Proj(irn) && is_malloc_Result(irn)) { return ir_sc_malloced; + } else if (is_Const(irn)) { + return ir_sc_globaladdr; } return res; @@ -604,6 +607,16 @@ static ir_alias_relation _get_alias_relation( /* for some reason CSE didn't happen yet for the 2 SymConsts... */ return ir_may_alias; + } else if (class1 == ir_sc_globaladdr) { + tarval *tv = get_Const_tarval(base1); + offset1 += get_tarval_long(tv); + tv = get_Const_tarval(base2); + offset2 += get_tarval_long(tv); + + if ((unsigned long)labs(offset2 - offset1) >= mode_size) + return ir_no_alias; + else + return ir_sure_alias; } } @@ -772,7 +785,7 @@ static int is_hidden_cast(ir_mode *mode, ir_mode *ent_mode) { } /* is_hidden_cast */ /** - * Determine the usage state of a node (or it's successor Sels). + * Determine the usage state of a node (or its successor Sels). * * @param irn the node */ @@ -788,7 +801,8 @@ static ir_entity_usage determine_entity_usage(const ir_node *irn, ir_entity *ent switch (get_irn_opcode(succ)) { case iro_Load: - assert(irn == get_Load_ptr(succ)); + /* beware: irn might be a Id node here, so irn might be not + equal to get_Load_ptr(succ) */ res |= ir_usage_read; /* check if this load is not a hidden conversion */ @@ -852,8 +866,36 @@ static ir_entity_usage determine_entity_usage(const ir_node *irn, ir_entity *ent } break; + /* skip identities */ + case iro_Id: + res |= determine_entity_usage(succ, entity); + break; + + /* skip tuples */ + case iro_Tuple: { + int input_nr; + for (input_nr = get_Tuple_n_preds(succ) - 1; input_nr >= 0; + --input_nr) { + ir_node *pred = get_Tuple_pred(succ, input_nr); + if (pred == irn) { + int k; + /* we found one input */ + for (k = get_irn_n_outs(succ) - 1; k >= 0; --k) { + ir_node *proj = get_irn_out(succ, k); + + if (is_Proj(proj) && get_Proj_proj(proj) == input_nr) { + res |= determine_entity_usage(proj, entity); + break; + } + } + } + } + break; + } + default: - /* another op, we don't know anything */ + /* another op, we don't know anything (we could do more advanced + * things like a dataflow analysis here) */ res |= ir_usage_unknown; break; } @@ -872,9 +914,11 @@ static void analyse_irg_entity_usage(ir_graph *irg) { /* set initial state to not_taken, as this is the "smallest" state */ for (i = get_class_n_members(ft) - 1; i >= 0; --i) { - ir_entity *ent = get_class_member(ft, i); + ir_entity *ent = get_class_member(ft, i); + ir_entity_usage flags = + get_entity_stickyness(ent) == stickyness_sticky ? ir_usage_unknown : 0; - set_entity_usage(ent, 0); + set_entity_usage(ent, flags); } assure_irg_outs(irg); @@ -923,34 +967,42 @@ static void init_entity_usage(ir_type * tp) { /* We have to be conservative: All external visible entities are unknown */ for (i = get_compound_n_members(tp) - 1; i >= 0; --i) { - ir_entity *entity = get_compound_member(tp, i); - ir_entity_usage flags; - - flags = get_entity_visibility(entity) == visibility_external_visible ? - ir_usage_unknown : 0; - set_entity_usage(entity, flags); + ir_entity *ent = get_compound_member(tp, i); + ir_entity_usage flags = ir_usage_none; + ir_visibility vis = get_entity_visibility(ent); + + if (vis == visibility_external_visible || + vis == visibility_external_allocated || + get_entity_stickyness(ent) == stickyness_sticky) { + flags |= ir_usage_unknown; + } + set_entity_usage(ent, flags); } } +/** + * Mark all entities used in the initializer as unknown usage. + * + * @param initializer the initializer to check + */ static void check_initializer_nodes(ir_initializer_t *initializer) { - switch (initializer->kind) { - case IR_INITIALIZER_CONST: { - ir_node *n = initializer->consti.value; + unsigned i; + ir_node *n; + switch (initializer->kind) { + case IR_INITIALIZER_CONST: /* let's check if it's an address */ + n = initializer->consti.value; if (is_Global(n)) { ir_entity *ent = get_Global_entity(n); set_entity_usage(ent, ir_usage_unknown); } return; - } case IR_INITIALIZER_TARVAL: case IR_INITIALIZER_NULL: return; - case IR_INITIALIZER_COMPOUND: { - size_t i; - + case IR_INITIALIZER_COMPOUND: for (i = 0; i < initializer->compound.n_initializers; ++i) { ir_initializer_t *sub_initializer = initializer->compound.initializers[i]; @@ -958,12 +1010,12 @@ static void check_initializer_nodes(ir_initializer_t *initializer) } return; } - } panic("invalid initializer found"); } /* check_initializer_nodes */ /** - * Mark all entities used in the initializer for the given entity as address taken. + * Mark all entities used in the initializer for the given entity as unknown + * usage. * * @param ent the entity */ @@ -1004,7 +1056,7 @@ static void check_initializer(ir_entity *ent) { /** - * Mark all entities used in initializers as address taken. + * Mark all entities used in initializers as unknown usage. * * @param tp a compound type */ @@ -1032,7 +1084,7 @@ static void print_entity_usage_flags(ir_type *tp) { if (flags == 0) continue; - ir_printf("%+F:"); + ir_printf("%+F:", ent); if (flags & ir_usage_address_taken) printf(" address_taken"); if (flags & ir_usage_read) @@ -1125,14 +1177,10 @@ void assure_irp_globals_entity_usage_computed(void) { void firm_init_memory_disambiguator(void) { FIRM_DBG_REGISTER(dbg, "firm.ana.irmemory"); + FIRM_DBG_REGISTER(dbgcall, "firm.opt.cc"); } -#include -#include "typerep.h" - -DEBUG_ONLY(static firm_dbg_module_t *dbgcall = NULL;) - /** Maps method types to cloned method types. */ static pmap *mtp_map; @@ -1189,8 +1237,6 @@ void mark_private_methods(void) { int i; int changed = 0; - FIRM_DBG_REGISTER(dbgcall, "firm.opt.cc"); - assure_irp_globals_entity_usage_computed(); mtp_map = pmap_create();