3 * @file tp_inheritance.c
5 * Project: libFIRM <br>
6 * File name: ir/tr/tp_inheritance.c <br>
7 * Purpose: Utility routines for inheritance representation <br>
8 * Author: Goetz Lindenmaier <br>
11 * Copyright: (c) 2001-2005 Universität Karlsruhe <br>
12 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. <br>
17 * @see type.h entity.h
31 /* ----------------------------------------------------------------------- */
32 /* Resolve implicit inheritance. */
33 /* ----------------------------------------------------------------------- */
35 ident *default_mangle_inherited_name(entity *super, type *clss) {
36 return mangle_u(get_type_ident(clss), get_entity_ident(super));
39 /* Replicates all entities in all super classes that are not overwritten
40 by an entity of this class. */
41 static void copy_entities_from_superclass(type *clss, void *env)
45 type *super, *inhenttype;
46 entity *inhent, *thisent;
47 mangle_inherited_name_func *mfunc = (mangle_inherited_name_func *)env;
49 for(i = 0; i < get_class_n_supertypes(clss); i++) {
50 super = get_class_supertype(clss, i);
51 assert(is_Class_type(super) && "not a class");
52 for(j = 0; j < get_class_n_members(super); j++) {
53 inhent = get_class_member(super, j);
54 inhenttype = get_entity_type(inhent);
55 /* check whether inhent is already overwritten */
57 for (k = 0; (k < get_class_n_members(clss)) && (overwritten == 0); k++) {
58 thisent = get_class_member(clss, k);
59 for(l = 0; l < get_entity_n_overwrites(thisent); l++) {
60 if(inhent == get_entity_overwrites(thisent, l)) {
61 /* overwritten - do not copy */
69 thisent = copy_entity_own(inhent, clss);
70 add_entity_overwrites(thisent, inhent);
71 set_entity_peculiarity(thisent, peculiarity_inherited);
72 set_entity_ld_ident(thisent, mfunc(inhent, clss));
73 if (get_entity_variability(inhent) == variability_constant) {
74 assert(is_atomic_entity(inhent) && /* @@@ */
75 "Inheritance of constant, compound entities not implemented");
76 set_entity_variability(thisent, variability_constant);
77 set_atomic_ent_value(thisent, get_atomic_ent_value(inhent));
84 /* Resolve implicit inheritance.
86 * Resolves the implicit inheritance supplied by firm.
88 void resolve_inheritance(mangle_inherited_name_func *mfunc) {
90 mfunc = default_mangle_inherited_name;
91 class_walk_super2sub(copy_entities_from_superclass, NULL, (void *)mfunc);
95 /* ----------------------------------------------------------------------- */
96 /* The transitive closure of the subclass/superclass and */
97 /* overwrites/overwrittenby relation. */
99 /* A walk over the ir (O(#types+#entities)) computes the transitive */
100 /* closure. Adding a new type/entity or changing the basic relations in */
101 /* some other way invalidates the transitive closure, i.e., it is not */
102 /* updated by the basic functions. */
104 /* All functions are named as their counterparts for the basic relations, */
105 /* adding the infix 'trans_'. */
106 /* ----------------------------------------------------------------------- */
108 void set_irp_inh_transitive_closure_state(inh_transitive_closure_state s) {
109 irp->inh_trans_closure_state = s;
111 void invalidate_irp_inh_transitive_closure_state(void) {
112 if (irp->inh_trans_closure_state == inh_transitive_closure_valid)
113 irp->inh_trans_closure_state = inh_transitive_closure_invalid;
115 inh_transitive_closure_state get_irp_inh_transitive_closure_state(void) {
116 return irp->inh_trans_closure_state;
119 static void assert_valid_state(void) {
120 assert(irp->inh_trans_closure_state == inh_transitive_closure_valid ||
121 irp->inh_trans_closure_state == inh_transitive_closure_invalid);
124 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
125 /* There is a set that extends each entity/type with two new */
126 /* fields: one for the upwards directed relation: 'up' (supertype, */
127 /* overwrites) and one for the downwards directed relation: 'down' (sub- */
128 /* type, overwrittenby. These fields contain psets (and maybe later */
129 /* arrays) listing all subtypes... */
130 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
133 firm_kind *kind; /* An entity or type. */
138 /* We use this set for all types and entities. */
139 static set *tr_inh_trans_set = NULL;
141 static int tr_inh_trans_cmp(const void *e1, const void *e2, size_t size) {
142 tr_inh_trans_tp *ef1 = (tr_inh_trans_tp *)e1;
143 tr_inh_trans_tp *ef2 = (tr_inh_trans_tp *)e2;
144 return (ef1->kind != ef2->kind);
147 static INLINE unsigned int tr_inh_trans_hash(void *e) {
148 void *v = (void *) ((tr_inh_trans_tp *)e)->kind;
157 /* This always completes successfully. */
158 static tr_inh_trans_tp* get_firm_kind_entry(firm_kind *k) {
159 tr_inh_trans_tp a, *found;
162 if (!tr_inh_trans_set) tr_inh_trans_set = new_set(tr_inh_trans_cmp, 128);
164 found = set_find(tr_inh_trans_set, &a, sizeof(a), tr_inh_trans_hash(&a));
166 a.up = pset_new_ptr(16);
167 a.down = pset_new_ptr(16);
168 found = set_insert(tr_inh_trans_set, &a, sizeof(a), tr_inh_trans_hash(&a));
173 static pset *get_entity_map(entity *ent, dir d) {
174 assert(is_entity(ent));
175 tr_inh_trans_tp *found = get_firm_kind_entry((firm_kind *)ent);
176 if (d == d_up) return found->up;
177 else return found->down;
180 static void add_entity_map(entity *ent, dir d, entity *new) {
181 assert(is_entity(ent) && is_entity(new));
182 tr_inh_trans_tp *found = get_firm_kind_entry((firm_kind *)ent);
183 if (d == d_up) pset_insert_ptr(found->up, new);
184 else pset_insert_ptr(found->down, new);
187 static pset *get_type_map(type *tp, dir d) {
189 tr_inh_trans_tp *found = get_firm_kind_entry((firm_kind *)tp);
190 if (d == d_up) return found->up;
191 else return found->down;
194 static void add_type_map(type *tp, dir d, type *new) {
195 assert(is_type(tp) && is_type(new));
196 tr_inh_trans_tp *found = get_firm_kind_entry((firm_kind *)tp);
197 if (d == d_up) pset_insert_ptr(found->up, new);
198 else pset_insert_ptr(found->down, new);
203 /* Walk over all types reachable from tp in the sub/supertype
204 * retlation and compute the closure for the two downwards directed
207 * The walk in the dag formed by the relation is tricky: We must visit
208 * all subtypes before visiting the supertypes. So we first walk down.
209 * Then we can compute the closure for this type. Then we walk up.
210 * As we call ourselves recursive, and walk in both directions, there
211 * can be cycles. So we have to make sure, that if we visit a node
212 * a second time (in a walk up) we do nothing. For this we increment
213 * the master visited flag twice.
214 * If the type is marked with master_flag_visited-1 it is on the stack.
215 * If it is marked with master_flag_visited it is fully processed.
217 * Well, we still miss some candidates ... */
218 static void compute_down_closure(type *tp) {
219 pset *myset, *subset;
220 int i, n_subtypes, n_members, n_supertypes;
221 int master_visited = get_master_type_visited();
223 assert(is_Class_type(tp));
225 set_type_visited(tp, master_visited-1);
227 /* Recursive descend. */
228 n_subtypes = get_class_n_subtypes(tp);
229 for (i = 0; i < n_subtypes; ++i) {
230 type *stp = get_class_subtype(tp, i);
231 if (type_not_visited(stp)) {
232 assert(get_type_visited(tp) < master_visited-1);
233 compute_down_closure(stp);
238 myset = get_type_map(tp, d_down);
239 for (i = 0; i < n_subtypes; ++i) {
240 type *stp = get_class_subtype(tp, i);
241 subset = get_type_map(stp, d_down);
242 pset_insert_ptr(myset, stp);
243 pset_insert_pset_ptr(myset, subset);
247 n_members = get_class_n_members(tp);
248 for (i = 0; i < n_members; ++i) {
249 entity *mem = get_class_member(tp, i);
250 int j, n_overwrittenby = get_entity_n_overwrittenby(mem);
252 myset = get_entity_map(mem, d_down);
253 for (j = 0; j > n_overwrittenby; ++j) {
254 entity *ov = get_entity_overwrittenby(mem, j);
255 subset = get_entity_map(ov, d_down);
256 pset_insert_pset_ptr(myset, subset);
257 pset_insert_ptr(myset, ov);
261 mark_type_visited(tp);
264 n_supertypes = get_class_n_supertypes(tp);
265 for (i = 0; i < n_supertypes; ++i) {
266 type *stp = get_class_supertype(tp, i);
267 if (get_type_visited(tp) < master_visited-1) {
268 compute_down_closure(stp);
273 static void compute_up_closure(type *tp) {
274 pset *myset, *subset;
275 int i, n_subtypes, n_members, n_supertypes;
276 int master_visited = get_master_type_visited();
278 assert(is_Class_type(tp));
280 set_type_visited(tp, master_visited-1);
282 /* Recursive descend. */
283 n_supertypes = get_class_n_supertypes(tp);
284 for (i = 0; i < n_supertypes; ++i) {
285 type *stp = get_class_supertype(tp, i);
286 if (type_not_visited(stp)) {
287 assert(get_type_visited(tp) < get_master_type_visited()-1);
288 compute_up_closure(stp);
293 myset = get_type_map(tp, d_up);
294 for (i = 0; i < n_supertypes; ++i) {
295 type *stp = get_class_supertype(tp, i);
296 subset = get_type_map(stp, d_up);
297 pset_insert_ptr(myset, stp);
298 pset_insert_pset_ptr(myset, subset);
302 n_members = get_class_n_members(tp);
303 for (i = 0; i < n_members; ++i) {
304 entity *mem = get_class_member(tp, i);
305 int j, n_overwrites = get_entity_n_overwrites(mem);
307 myset = get_entity_map(mem, d_up);
308 for (j = 0; j > n_overwrites; ++j) {
309 entity *ov = get_entity_overwrites(mem, j);
310 subset = get_entity_map(ov, d_up);
311 pset_insert_pset_ptr(myset, subset);
312 pset_insert_ptr(myset, ov);
316 mark_type_visited(tp);
319 n_subtypes = get_class_n_subtypes(tp);
320 for (i = 0; i < n_subtypes; ++i) {
321 type *stp = get_class_subtype(tp, i);
322 if (get_type_visited(tp) < master_visited-1) {
323 compute_up_closure(stp);
328 /** Compute the transitive closure of the subclass/superclass and
329 * overwrites/overwrittenby relation.
331 * This function walks over the ir (O(#types+#entities)) to compute the
332 * transitive closure. */
333 void compute_inh_transitive_closure(void) {
334 int i, n_types = get_irp_n_types();
335 free_inh_transitive_closure();
337 /* The 'down' relation */
338 inc_master_type_visited(); /* Inc twice: one if on stack, second if values computed. */
339 inc_master_type_visited();
340 for (i = 0; i < n_types; ++i) {
341 type *tp = get_irp_type(i);
342 if (is_Class_type(tp) && type_not_visited(tp)) { /* For others there is nothing to accumulate. */
343 assert(get_type_visited(tp) < get_master_type_visited()-1);
344 int j, n_subtypes = get_class_n_subtypes(tp);
345 int has_unmarked_subtype = false;
346 for (j = 0; j < n_subtypes && !has_unmarked_subtype; ++j) {
347 type *stp = get_class_subtype(tp, j);
348 if (type_not_visited(stp)) has_unmarked_subtype = true;
351 /* This is a good starting point. */
352 if (!has_unmarked_subtype)
353 compute_down_closure(tp);
357 /* The 'up' relation */
358 inc_master_type_visited();
359 inc_master_type_visited();
360 for (i = 0; i < n_types; ++i) {
361 type *tp = get_irp_type(i);
362 if (is_Class_type(tp) && type_not_visited(tp)) { /* For others there is nothing to accumulate. */
363 assert(get_type_visited(tp) < get_master_type_visited()-1);
364 int j, n_supertypes = get_class_n_supertypes(tp);
365 int has_unmarked_supertype = false;
366 for (j = 0; j < n_supertypes && !has_unmarked_supertype; ++j) {
367 type *stp = get_class_supertype(tp, j);
368 if (type_not_visited(stp)) has_unmarked_supertype = true;
371 /* This is a good starting point. */
372 if (!has_unmarked_supertype)
373 compute_up_closure(tp);
377 irp->inh_trans_closure_state = inh_transitive_closure_valid;
380 /** Free memory occupied by the transitive closure information. */
381 void free_inh_transitive_closure(void) {
382 if (tr_inh_trans_set) {
383 tr_inh_trans_tp *elt;
384 for (elt = set_first(tr_inh_trans_set); elt; elt = set_next(tr_inh_trans_set)) {
388 del_set(tr_inh_trans_set);
389 tr_inh_trans_set = NULL;
391 irp->inh_trans_closure_state = inh_transitive_closure_none;
394 /* - subtype ------------------------------------------------------------- */
396 type *get_class_trans_subtype_first(type *tp) {
397 assert_valid_state();
398 return pset_first(get_type_map(tp, d_down));
401 type *get_class_trans_subtype_next (type *tp) {
402 assert_valid_state();
403 return pset_next(get_type_map(tp, d_down));
406 /* - supertype ----------------------------------------------------------- */
408 type *get_class_trans_supertype_first(type *tp) {
409 assert_valid_state();
410 return pset_first(get_type_map(tp, d_up));
413 type *get_class_trans_supertype_next (type *tp) {
414 assert_valid_state();
415 return pset_next(get_type_map(tp, d_up));
418 /* - overwrittenby ------------------------------------------------------- */
420 entity *get_entity_trans_overwrittenby_first(entity *ent) {
421 assert_valid_state();
422 return pset_first(get_entity_map(ent, d_down));
425 entity *get_entity_trans_overwrittenby_next (entity *ent) {
426 assert_valid_state();
427 return pset_next(get_entity_map(ent, d_down));
430 /* - overwrites ---------------------------------------------------------- */
433 /** Iterate over all transitive overwritten entities. */
434 entity *get_entity_trans_overwrites_first(entity *ent) {
435 assert_valid_state();
436 return pset_first(get_entity_map(ent, d_up));
439 entity *get_entity_trans_overwrites_next (entity *ent) {
440 assert_valid_state();
441 return pset_next(get_entity_map(ent, d_up));
448 /* ----------------------------------------------------------------------- */
449 /* Classify pairs of types/entities in the inheritance relations. */
450 /* ----------------------------------------------------------------------- */
452 /* Returns true if low is subclass of high. */
453 int is_subclass_of(type *low, type *high) {
455 assert(is_Class_type(low) && is_Class_type(high));
457 if (low == high) return 1;
459 if (get_irp_inh_transitive_closure_state() == inh_transitive_closure_valid) {
460 pset *m = get_type_map(high, d_down);
461 if (pset_find_ptr(m, low)) return 1;
465 /* depth first search from high downwards. */
466 n_subtypes = get_class_n_subtypes(high);
467 for (i = 0; i < n_subtypes; i++) {
468 type *stp = get_class_subtype(high, i);
469 if (low == stp) return 1;
470 if (is_subclass_of(low, stp))
476 int is_overwritten_by(entity *high, entity *low) {
477 int i, n_overwrittenby;
478 assert(is_entity(low) && is_entity(high));
480 if (get_irp_inh_transitive_closure_state() == inh_transitive_closure_valid) {
481 pset *m = get_entity_map(high, d_down);
482 if (pset_find_ptr(m, low)) return 1;
486 /* depth first search from high downwards. */
487 n_overwrittenby = get_entity_n_overwrittenby(high);
488 for (i = 0; i < n_overwrittenby; i++) {
489 entity *ov = get_entity_overwrittenby(high, i);
490 if (low == ov) return 1;
491 if (is_overwritten_by(low, ov))
498 /* Need two routines because I want to assert the result. */
499 static entity *resolve_ent_polymorphy2 (type *dynamic_class, entity *static_ent) {
500 int i, n_overwrittenby;
503 if (get_entity_owner(static_ent) == dynamic_class) return static_ent;
505 n_overwrittenby = get_entity_n_overwrittenby(static_ent);
506 for (i = 0; i < n_overwrittenby; ++i) {
507 res = resolve_ent_polymorphy2(dynamic_class, get_entity_overwrittenby(static_ent, i));
515 /* Resolve polymorphy in the inheritance relation.
517 * Returns the dynamically referenced entity if the static entity and the
518 * dynamic type are given.
519 * Search downwards in overwritten tree. */
520 entity *resolve_ent_polymorphy(type *dynamic_class, entity *static_ent) {
522 assert(static_ent && is_entity(static_ent));
524 res = resolve_ent_polymorphy2(dynamic_class, static_ent);