X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftr_inheritance.c;h=f1c7d9c40bf744ef6dd82c79bd51f641066ef9f5;hb=87b6a945e992229095254b628b932ebd40114f0a;hp=b5912d6ef13d0e3899c7e172b98375895d5803c8;hpb=bb9f2e36362333c6635b89f5258171b06c786608;p=libfirm diff --git a/ir/tr/tr_inheritance.c b/ir/tr/tr_inheritance.c index b5912d6ef..f1c7d9c40 100644 --- a/ir/tr/tr_inheritance.c +++ b/ir/tr/tr_inheritance.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -41,32 +41,36 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg); /* Resolve implicit inheritance. */ /* ----------------------------------------------------------------------- */ -ident *default_mangle_inherited_name(ir_entity *super, ir_type *clss) { - return mangle_u(new_id_from_str("inh"), mangle_u(get_type_ident(clss), get_entity_ident(super))); +ident *default_mangle_inherited_name(const ir_entity *super, const ir_type *clss) +{ + return id_mangle_u(new_id_from_str("inh"), id_mangle_u(get_class_ident(clss), get_entity_ident(super))); } /** Replicates all entities in all super classes that are not overwritten by an entity of this class. */ static void copy_entities_from_superclass(ir_type *clss, void *env) { - int i, j, k, l; + size_t i; + size_t j; + size_t k; + size_t l; int overwritten; ir_type *super, *inhenttype; ir_entity *inhent, *thisent; mangle_inherited_name_func *mfunc = *(mangle_inherited_name_func **)env; - for(i = 0; i < get_class_n_supertypes(clss); i++) { + for (i = 0; i < get_class_n_supertypes(clss); i++) { super = get_class_supertype(clss, i); assert(is_Class_type(super) && "not a class"); - for(j = 0; j < get_class_n_members(super); j++) { + for (j = 0; j < get_class_n_members(super); j++) { inhent = get_class_member(super, j); inhenttype = get_entity_type(inhent); /* check whether inhent is already overwritten */ overwritten = 0; for (k = 0; (k < get_class_n_members(clss)) && (overwritten == 0); k++) { thisent = get_class_member(clss, k); - for(l = 0; l < get_entity_n_overwrites(thisent); l++) { - if(inhent == get_entity_overwrites(thisent, l)) { + for (l = 0; l < get_entity_n_overwrites(thisent); l++) { + if (inhent == get_entity_overwrites(thisent, l)) { /* overwritten - do not copy */ overwritten = 1; break; @@ -80,10 +84,10 @@ static void copy_entities_from_superclass(ir_type *clss, void *env) if (get_entity_peculiarity(inhent) == peculiarity_existent) set_entity_peculiarity(thisent, peculiarity_inherited); set_entity_ld_ident(thisent, mfunc(inhent, clss)); - if (get_entity_variability(inhent) == variability_constant) { + if (get_entity_linkage(inhent) & IR_LINKAGE_CONSTANT) { assert(is_atomic_entity(inhent) && /* @@@ */ "Inheritance of constant, compound entities not implemented"); - set_entity_variability(thisent, variability_constant); + add_entity_linkage(thisent, IR_LINKAGE_CONSTANT); set_atomic_ent_value(thisent, get_atomic_ent_value(inhent)); } } @@ -95,7 +99,8 @@ static void copy_entities_from_superclass(ir_type *clss, void *env) * * Resolves the implicit inheritance supplied by firm. */ -void resolve_inheritance(mangle_inherited_name_func *mfunc) { +void resolve_inheritance(mangle_inherited_name_func *mfunc) +{ if (!mfunc) mfunc = default_mangle_inherited_name; class_walk_super2sub(copy_entities_from_superclass, NULL, (void *)&mfunc); @@ -115,18 +120,22 @@ void resolve_inheritance(mangle_inherited_name_func *mfunc) { /* adding the infix 'trans_'. */ /* ----------------------------------------------------------------------- */ -void set_irp_inh_transitive_closure_state(inh_transitive_closure_state s) { +void set_irp_inh_transitive_closure_state(inh_transitive_closure_state s) +{ irp->inh_trans_closure_state = s; } -void invalidate_irp_inh_transitive_closure_state(void) { +void invalidate_irp_inh_transitive_closure_state(void) +{ if (irp->inh_trans_closure_state == inh_transitive_closure_valid) irp->inh_trans_closure_state = inh_transitive_closure_invalid; } -inh_transitive_closure_state get_irp_inh_transitive_closure_state(void) { +inh_transitive_closure_state get_irp_inh_transitive_closure_state(void) +{ return irp->inh_trans_closure_state; } -static void assert_valid_state(void) { +static void assert_valid_state(void) +{ assert(irp->inh_trans_closure_state == inh_transitive_closure_valid || irp->inh_trans_closure_state == inh_transitive_closure_invalid); } @@ -155,9 +164,10 @@ static set *tr_inh_trans_set = NULL; /** * Compare two tr_inh_trans_tp entries. */ -static int tr_inh_trans_cmp(const void *e1, const void *e2, size_t size) { - const tr_inh_trans_tp *ef1 = e1; - const tr_inh_trans_tp *ef2 = e2; +static int tr_inh_trans_cmp(const void *e1, const void *e2, size_t size) +{ + const tr_inh_trans_tp *ef1 = (const tr_inh_trans_tp*)e1; + const tr_inh_trans_tp *ef2 = (const tr_inh_trans_tp*)e2; (void) size; return ef1->kind != ef2->kind; @@ -166,27 +176,30 @@ static int tr_inh_trans_cmp(const void *e1, const void *e2, size_t size) { /** * calculate the hash value of an tr_inh_trans_tp */ -static inline unsigned int tr_inh_trans_hash(const tr_inh_trans_tp *v) { +static inline unsigned int tr_inh_trans_hash(const tr_inh_trans_tp *v) +{ return HASH_PTR(v->kind); } /* This always completes successfully. */ -static tr_inh_trans_tp *get_firm_kind_entry(const firm_kind *k) { +static tr_inh_trans_tp *get_firm_kind_entry(const firm_kind *k) +{ tr_inh_trans_tp a, *found; a.kind = k; if (!tr_inh_trans_set) tr_inh_trans_set = new_set(tr_inh_trans_cmp, 128); - found = set_find(tr_inh_trans_set, &a, sizeof(a), tr_inh_trans_hash(&a)); + found = (tr_inh_trans_tp*)set_find(tr_inh_trans_set, &a, sizeof(a), tr_inh_trans_hash(&a)); if (!found) { a.directions[d_up] = pset_new_ptr(16); a.directions[d_down] = pset_new_ptr(16); - found = set_insert(tr_inh_trans_set, &a, sizeof(a), tr_inh_trans_hash(&a)); + found = (tr_inh_trans_tp*)set_insert(tr_inh_trans_set, &a, sizeof(a), tr_inh_trans_hash(&a)); } return found; } -static pset *get_entity_map(const ir_entity *ent, dir d) { +static pset *get_entity_map(const ir_entity *ent, dir d) +{ tr_inh_trans_tp *found; assert(is_entity(ent)); @@ -194,7 +207,8 @@ static pset *get_entity_map(const ir_entity *ent, dir d) { return found->directions[d]; } -static pset *get_type_map(const ir_type *tp, dir d) { +static pset *get_type_map(const ir_type *tp, dir d) +{ tr_inh_trans_tp *found; assert(is_type(tp)); @@ -219,9 +233,10 @@ static pset *get_type_map(const ir_type *tp, dir d) { * If it is marked with master_flag_visited it is fully processed. * * Well, we still miss some candidates ... */ -static void compute_down_closure(ir_type *tp) { +static void compute_down_closure(ir_type *tp) +{ pset *myset, *subset; - int i, n_subtypes, n_members, n_supertypes; + size_t i, n_subtypes, n_members, n_supertypes; ir_visited_t master_visited = get_master_type_visited(); assert(is_Class_type(tp)); @@ -250,7 +265,7 @@ static void compute_down_closure(ir_type *tp) { n_members = get_class_n_members(tp); for (i = 0; i < n_members; ++i) { ir_entity *mem = get_class_member(tp, i); - int j, n_overwrittenby = get_entity_n_overwrittenby(mem); + size_t j, n_overwrittenby = get_entity_n_overwrittenby(mem); myset = get_entity_map(mem, d_down); for (j = 0; j < n_overwrittenby; ++j) { @@ -273,9 +288,10 @@ static void compute_down_closure(ir_type *tp) { } } -static void compute_up_closure(ir_type *tp) { +static void compute_up_closure(ir_type *tp) +{ pset *myset, *subset; - int i, n_subtypes, n_members, n_supertypes; + size_t i, n_subtypes, n_members, n_supertypes; ir_visited_t master_visited = get_master_type_visited(); assert(is_Class_type(tp)); @@ -304,7 +320,7 @@ static void compute_up_closure(ir_type *tp) { n_members = get_class_n_members(tp); for (i = 0; i < n_members; ++i) { ir_entity *mem = get_class_member(tp, i); - int j, n_overwrites = get_entity_n_overwrites(mem); + size_t j, n_overwrites = get_entity_n_overwrites(mem); myset = get_entity_map(mem, d_up); for (j = 0; j < n_overwrites; ++j) { @@ -332,17 +348,19 @@ static void compute_up_closure(ir_type *tp) { * * This function walks over the ir (O(#types+#entities)) to compute the * transitive closure. */ -void compute_inh_transitive_closure(void) { - int i, n_types = get_irp_n_types(); +void compute_inh_transitive_closure(void) +{ + size_t i, n_types = get_irp_n_types(); free_inh_transitive_closure(); /* The 'down' relation */ + irp_reserve_resources(irp, IR_RESOURCE_TYPE_VISITED); inc_master_type_visited(); /* Inc twice: one if on stack, second if values computed. */ inc_master_type_visited(); for (i = 0; i < n_types; ++i) { ir_type *tp = get_irp_type(i); if (is_Class_type(tp) && type_not_visited(tp)) { /* For others there is nothing to accumulate. */ - int j, n_subtypes = get_class_n_subtypes(tp); + size_t j, n_subtypes = get_class_n_subtypes(tp); int has_unmarked_subtype = 0; assert(get_type_visited(tp) < get_master_type_visited()-1); @@ -366,7 +384,7 @@ void compute_inh_transitive_closure(void) { for (i = 0; i < n_types; ++i) { ir_type *tp = get_irp_type(i); if (is_Class_type(tp) && type_not_visited(tp)) { /* For others there is nothing to accumulate. */ - int j, n_supertypes = get_class_n_supertypes(tp); + size_t j, n_supertypes = get_class_n_supertypes(tp); int has_unmarked_supertype = 0; assert(get_type_visited(tp) < get_master_type_visited()-1); @@ -385,13 +403,16 @@ void compute_inh_transitive_closure(void) { } irp->inh_trans_closure_state = inh_transitive_closure_valid; + irp_free_resources(irp, IR_RESOURCE_TYPE_VISITED); } /** Free memory occupied by the transitive closure information. */ -void free_inh_transitive_closure(void) { +void free_inh_transitive_closure(void) +{ if (tr_inh_trans_set) { tr_inh_trans_tp *elt; - for (elt = set_first(tr_inh_trans_set); elt; elt = set_next(tr_inh_trans_set)) { + for (elt = (tr_inh_trans_tp*)set_first(tr_inh_trans_set); elt != NULL; + elt = (tr_inh_trans_tp*)set_next(tr_inh_trans_set)) { del_pset(elt->directions[d_up]); del_pset(elt->directions[d_down]); } @@ -403,57 +424,66 @@ void free_inh_transitive_closure(void) { /* - subtype ------------------------------------------------------------- */ -ir_type *get_class_trans_subtype_first(const ir_type *tp) { +ir_type *get_class_trans_subtype_first(const ir_type *tp) +{ assert_valid_state(); - return pset_first(get_type_map(tp, d_down)); + return (ir_type*)pset_first(get_type_map(tp, d_down)); } -ir_type *get_class_trans_subtype_next(const ir_type *tp) { +ir_type *get_class_trans_subtype_next(const ir_type *tp) +{ assert_valid_state(); - return pset_next(get_type_map(tp, d_down)); + return (ir_type*)pset_next(get_type_map(tp, d_down)); } -int is_class_trans_subtype(const ir_type *tp, const ir_type *subtp) { +int is_class_trans_subtype(const ir_type *tp, const ir_type *subtp) +{ assert_valid_state(); return (pset_find_ptr(get_type_map(tp, d_down), subtp) != NULL); } /* - supertype ----------------------------------------------------------- */ -ir_type *get_class_trans_supertype_first(const ir_type *tp) { +ir_type *get_class_trans_supertype_first(const ir_type *tp) +{ assert_valid_state(); - return pset_first(get_type_map(tp, d_up)); + return (ir_type*)pset_first(get_type_map(tp, d_up)); } -ir_type *get_class_trans_supertype_next(const ir_type *tp) { +ir_type *get_class_trans_supertype_next(const ir_type *tp) +{ assert_valid_state(); - return pset_next(get_type_map(tp, d_up)); + return (ir_type*)pset_next(get_type_map(tp, d_up)); } /* - overwrittenby ------------------------------------------------------- */ -ir_entity *get_entity_trans_overwrittenby_first(const ir_entity *ent) { +ir_entity *get_entity_trans_overwrittenby_first(const ir_entity *ent) +{ assert_valid_state(); - return pset_first(get_entity_map(ent, d_down)); + return (ir_entity*)pset_first(get_entity_map(ent, d_down)); } -ir_entity *get_entity_trans_overwrittenby_next(const ir_entity *ent) { +ir_entity *get_entity_trans_overwrittenby_next(const ir_entity *ent) +{ assert_valid_state(); - return pset_next(get_entity_map(ent, d_down)); + return (ir_entity*)pset_next(get_entity_map(ent, d_down)); } /* - overwrites ---------------------------------------------------------- */ /** Iterate over all transitive overwritten entities. */ -ir_entity *get_entity_trans_overwrites_first(const ir_entity *ent) { +ir_entity *get_entity_trans_overwrites_first(const ir_entity *ent) +{ assert_valid_state(); - return pset_first(get_entity_map(ent, d_up)); + return (ir_entity*)pset_first(get_entity_map(ent, d_up)); } -ir_entity *get_entity_trans_overwrites_next(const ir_entity *ent) { +ir_entity *get_entity_trans_overwrites_next(const ir_entity *ent) +{ assert_valid_state(); - return pset_next(get_entity_map(ent, d_up)); + return (ir_entity*)pset_next(get_entity_map(ent, d_up)); } @@ -462,8 +492,9 @@ ir_entity *get_entity_trans_overwrites_next(const ir_entity *ent) { /* ----------------------------------------------------------------------- */ /** Returns true if low is subclass of high. */ -static int check_is_SubClass_of(ir_type *low, ir_type *high) { - int i, n_subtypes; +static int check_is_SubClass_of(ir_type *low, ir_type *high) +{ + size_t i, n_subtypes; /* depth first search from high downwards. */ n_subtypes = get_class_n_subtypes(high); @@ -477,7 +508,8 @@ static int check_is_SubClass_of(ir_type *low, ir_type *high) { } /* Returns true if low is subclass of high. */ -int is_SubClass_of(ir_type *low, ir_type *high) { +int is_SubClass_of(ir_type *low, ir_type *high) +{ assert(is_Class_type(low) && is_Class_type(high)); if (low == high) return 1; @@ -496,7 +528,8 @@ int is_SubClass_of(ir_type *low, ir_type *high) { * many as possible). If the remaining types are both class types * and subclasses, returns true, else false. Can also be called with * two class types. */ -int is_SubClass_ptr_of(ir_type *low, ir_type *high) { +int is_SubClass_ptr_of(ir_type *low, ir_type *high) +{ while (is_Pointer_type(low) && is_Pointer_type(high)) { low = get_pointer_points_to_type(low); high = get_pointer_points_to_type(high); @@ -507,8 +540,9 @@ int is_SubClass_ptr_of(ir_type *low, ir_type *high) { return 0; } -int is_overwritten_by(ir_entity *high, ir_entity *low) { - int i, n_overwrittenby; +int is_overwritten_by(ir_entity *high, ir_entity *low) +{ + size_t i, n_overwrittenby; assert(is_entity(low) && is_entity(high)); if (get_irp_inh_transitive_closure_state() == inh_transitive_closure_valid) { @@ -535,10 +569,16 @@ int is_overwritten_by(ir_entity *high, ir_entity *low) { * * Need two routines because I want to assert the result. */ -static ir_entity *do_resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *static_ent) { - int i, n_overwrittenby; +static ir_entity *do_resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *static_ent) +{ + size_t i, n_overwrittenby; + + ir_type *owner = get_entity_owner(static_ent); + if (owner == dynamic_class) return static_ent; - if (get_entity_owner(static_ent) == dynamic_class) return static_ent; + // if the owner of the static_ent already is more special than the dynamic + // type to check against - stop here. + if (! is_SubClass_of(dynamic_class, owner)) return NULL; n_overwrittenby = get_entity_n_overwrittenby(static_ent); for (i = 0; i < n_overwrittenby; ++i) { @@ -546,15 +586,19 @@ static ir_entity *do_resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *s ent = do_resolve_ent_polymorphy(dynamic_class, ent); if (ent) return ent; } - return NULL; + + // No further specialization of static_ent has been found + return static_ent; } /* Resolve polymorphy in the inheritance relation. * * Returns the dynamically referenced entity if the static entity and the * dynamic type are given. - * Search downwards in overwritten tree. */ -ir_entity *resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *static_ent) { + * Search downwards in overwritten tree. + */ +ir_entity *resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *static_ent) +{ ir_entity *res; assert(static_ent && is_entity(static_ent)); @@ -572,31 +616,37 @@ ir_entity *resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *static_ent) /* - State handling. ----------------------------------------- */ -void set_irg_class_cast_state(ir_graph *irg, ir_class_cast_state s) { - if (get_irp_class_cast_state() > s) set_irp_class_cast_state(s); +void set_irg_class_cast_state(ir_graph *irg, ir_class_cast_state s) +{ + if (get_irp_class_cast_state() > s) + set_irp_class_cast_state(s); irg->class_cast_state = s; } -ir_class_cast_state get_irg_class_cast_state(ir_graph *irg) { +ir_class_cast_state get_irg_class_cast_state(const ir_graph *irg) +{ return irg->class_cast_state; } -void set_irp_class_cast_state(ir_class_cast_state s) { +void set_irp_class_cast_state(ir_class_cast_state s) +{ #ifndef NDEBUG - int i; - for (i = get_irp_n_irgs() - 1; i >= 0; --i) + size_t i, n; + for (i = 0, n = get_irp_n_irgs(); i < n; ++i) assert(get_irg_class_cast_state(get_irp_irg(i)) >= s); #endif irp->class_cast_state = s; } -ir_class_cast_state get_irp_class_cast_state(void) { +ir_class_cast_state get_irp_class_cast_state(void) +{ return irp->class_cast_state; } -char *get_class_cast_state_string(ir_class_cast_state s) { +const char *get_class_cast_state_string(ir_class_cast_state s) +{ #define X(a) case a: return #a - switch(s) { + switch (s) { X(ir_class_casts_any); X(ir_class_casts_transitive); X(ir_class_casts_normalized); @@ -613,7 +663,11 @@ typedef struct ccs_env { ir_class_cast_state worst_situation; } ccs_env; -void verify_irn_class_cast_state(ir_node *n, void *env) { +/** + * Walker: check Casts. + */ +static void verify_irn_class_cast_state(ir_node *n, void *env) +{ ccs_env *ccs = (ccs_env *)env; ir_class_cast_state this_state = ir_class_casts_any; ir_type *fromtype, *totype; @@ -633,14 +687,11 @@ void verify_irn_class_cast_state(ir_node *n, void *env) { if (!is_Class_type(totype)) return; if (is_SubClass_of(totype, fromtype) || - is_SubClass_of(fromtype, totype) ) { + is_SubClass_of(fromtype, totype)) { this_state = ir_class_casts_transitive; - if ((get_class_supertype_index(totype, fromtype) != -1) || - (get_class_supertype_index(fromtype, totype) != -1) || + if ((get_class_supertype_index(totype, fromtype) != (size_t)-1) || + (get_class_supertype_index(fromtype, totype) != (size_t)-1) || fromtype == totype) { - /* Das ist doch alt? Aus dem cvs aufgetaucht ... - if ((get_class_supertype_index(totype, fromtype) == -1) && - (get_class_supertype_index(fromtype, totype) == -1) ) { */ this_state = ir_class_casts_normalized; } } @@ -661,7 +712,8 @@ void verify_irn_class_cast_state(ir_node *n, void *env) { } /** Verify that the graph meets requirements of state set. */ -void verify_irg_class_cast_state(ir_graph *irg) { +void verify_irg_class_cast_state(ir_graph *irg) +{ ccs_env env; FIRM_DBG_REGISTER(dbg, "firm.tr.inheritance");