X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Ftr%2Ftr_inheritance.c;h=03bc472e69a6776bf5d8fa56e02d53a49c9928e4;hb=2c8cc375a52fbfb9bdf15ebed6278a6d7b23a6ff;hp=ef0c6d49d779926fca60e536088a5d83a0acd142;hpb=cc3a5c3a7faef685a3c5ee2af5439e5912eee1b3;p=libfirm diff --git a/ir/tr/tr_inheritance.c b/ir/tr/tr_inheritance.c index ef0c6d49d..03bc472e6 100644 --- a/ir/tr/tr_inheritance.c +++ b/ir/tr/tr_inheritance.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -23,10 +23,9 @@ * @author Goetz Lindenmaier * @version $Id$ */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" +#include "debug.h" #include "typerep.h" #include "irgraph_t.h" #include "irprog_t.h" @@ -36,37 +35,42 @@ #include "irgwalk.h" #include "irflag.h" +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); } @@ -145,74 +154,67 @@ typedef enum { } dir; typedef struct { - firm_kind *kind; /* An entity or type. */ + const firm_kind *kind; /**< An entity or type. */ pset *directions[2]; } tr_inh_trans_tp; /* We use this set for all types and entities. */ static set *tr_inh_trans_set = NULL; -static int tr_inh_trans_cmp(const void *e1, const void *e2, size_t size) { - tr_inh_trans_tp *ef1 = (tr_inh_trans_tp *)e1; - tr_inh_trans_tp *ef2 = (tr_inh_trans_tp *)e2; +/** + * 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 = (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); + return ef1->kind != ef2->kind; } -static INLINE unsigned int tr_inh_trans_hash(void *e) { - tr_inh_trans_tp *v = e; +/** + * calculate the hash value of an tr_inh_trans_tp + */ +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(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(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)); - found = get_firm_kind_entry((firm_kind *)ent); + found = get_firm_kind_entry((const firm_kind *)ent); return found->directions[d]; } -/* -static void add_entity_map(ir_entity *ent, dir d, ir_entity *new) { - tr_inh_trans_tp *found; - assert(is_entity(ent) && is_entity(new)); - tr_inh_trans_tp *found = get_firm_kind_entry((firm_kind *)ent); - pset_insert_ptr(found->directions[d], new); -} -*/ -static pset *get_type_map(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)); - found = get_firm_kind_entry((firm_kind *)tp); + found = get_firm_kind_entry((const firm_kind *)tp); return found->directions[d]; } -/* -static void add_type_map(ir_type *tp, dir d, type *new) { - tr_inh_trans_tp *found; - - assert(is_type(tp) && is_type(new)); - found = get_firm_kind_entry((firm_kind *)tp); - pset_insert_ptr(found->directions[d], new); -} -*/ /** @@ -231,10 +233,11 @@ static void add_type_map(ir_type *tp, dir d, type *new) { * 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; - unsigned long master_visited = get_master_type_visited(); + size_t i, n_subtypes, n_members, n_supertypes; + ir_visited_t master_visited = get_master_type_visited(); assert(is_Class_type(tp)); @@ -262,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) { @@ -285,10 +288,11 @@ 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; - unsigned long master_visited = get_master_type_visited(); + size_t i, n_subtypes, n_members, n_supertypes; + ir_visited_t master_visited = get_master_type_visited(); assert(is_Class_type(tp)); @@ -316,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) { @@ -344,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); @@ -378,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); @@ -397,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]); } @@ -415,70 +424,77 @@ void free_inh_transitive_closure(void) { /* - subtype ------------------------------------------------------------- */ -ir_type *get_class_trans_subtype_first(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 (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 (ir_type *tp, 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(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 (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(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 (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(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 (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)); } - - - /* ----------------------------------------------------------------------- */ /* Classify pairs of types/entities in the inheritance relations. */ /* ----------------------------------------------------------------------- */ /** 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); @@ -492,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; @@ -511,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); @@ -522,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) { @@ -550,8 +569,9 @@ 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; if (get_entity_owner(static_ent) == dynamic_class) return static_ent; @@ -568,8 +588,10 @@ static ir_entity *do_resolve_ent_polymorphy(ir_type *dynamic_class, ir_entity *s * * 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)); @@ -587,29 +609,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) { - int i; - for (i = 0; i < get_irp_n_irgs(); ++i) +void set_irp_class_cast_state(ir_class_cast_state s) +{ +#ifndef NDEBUG + 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); @@ -626,13 +656,17 @@ 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; int ref_depth = 0; - if (get_irn_op(n) != op_Cast) return; + if (!is_Cast(n)) return; fromtype = get_irn_typeinfo_type(get_Cast_op(n)); totype = get_Cast_type(n); @@ -646,14 +680,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; } } @@ -673,20 +704,23 @@ void verify_irn_class_cast_state(ir_node *n, void *env) { ccs->worst_situation = this_state; } - /** 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"); + env.expected_state = get_irg_class_cast_state(irg); env.worst_situation = ir_class_casts_normalized; irg_walk_graph(irg, NULL, verify_irn_class_cast_state, &env); - if ((env.worst_situation > env.expected_state) && get_firm_verbosity()) { - ir_printf("Note: class cast state is set lower than reqired in graph \n\t%+F\n", irg); - printf(" state is %s, reqired is %s\n", + if ((env.worst_situation > env.expected_state)) { + DB((dbg, LEVEL_1, "Note: class cast state is set lower than reqired " + "in graph \n\t%+F\n", irg)); + DB((dbg, LEVEL_1, " state is %s, reqired is %s\n", get_class_cast_state_string(env.expected_state), - get_class_cast_state_string(env.worst_situation)); + get_class_cast_state_string(env.worst_situation))); } }