1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
4 * Author: Goetz Lindenmaier
6 * traverse the type information. The walker walks the whole ir graph
7 * to find the distinct type trees in the type graph forest.
8 * - execute the pre function before recursion
9 * - execute the post function after recursion
21 #include "irgraph_t.h"
24 #include "type_or_entity.h"
28 /* Make types visible to allow most efficient access */
32 typedef struct type_walk_env {
39 static void type_walk_2(type_or_ent *tore,
40 void (*pre)(type_or_ent*, void*),
41 void (*post)(type_or_ent*, void*),
47 switch (get_kind(tore)) {
49 if (((entity *)tore)->visit >= type_visited) return;
52 if(type_id == get_type_tpop((type*)tore)) {
53 type_walk_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
56 if (((type *)tore)->visit >= type_visited) return;
62 /* execute pre method */
67 switch (get_kind(tore)) {
71 entity *ent = (entity *)tore;
72 ent->visit = type_visited;
73 type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env);
74 type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env);
79 type *tp = (type *)tore;
80 mark_type_visited(tp);
81 switch (get_type_tpop_code(tp)) {
84 for (i=0; i<get_class_n_supertypes(tp); i++)
85 type_walk_2((type_or_ent *)get_class_supertype(tp, i), pre, post, env);
86 for (i=0; i<get_class_n_members(tp); i++)
87 type_walk_2((type_or_ent *)get_class_member(tp, i), pre, post, env);
88 for (i=0; i<get_class_n_subtypes(tp); i++)
89 type_walk_2((type_or_ent *)get_class_subtype(tp, i), pre, post, env);
94 for (i=0; i<get_struct_n_members(tp); i++)
95 type_walk_2((type_or_ent *)get_struct_member(tp, i), pre, post, env);
100 for (i = 0; i < get_method_n_params(tp); i++)
101 type_walk_2((type_or_ent *)get_method_param_type(tp, i), pre, post, env);
102 for (i = 0; i < get_method_n_ress(tp); i++)
103 type_walk_2((type_or_ent *)get_method_res_type(tp, i), pre, post, env);
108 for (i = 0; i < get_union_n_members(tp); i++)
109 type_walk_2((type_or_ent *)get_union_member(tp, i), pre, post, env);
113 type_walk_2((type_or_ent *)get_array_element_type(tp),
115 type_walk_2((type_or_ent *)get_array_element_entity(tp),
118 case tpo_enumeration:
122 type_walk_2((type_or_ent *)get_pointer_points_to_type(tp),
130 printf(" *** Faulty type! \n");
133 } break; /* end case k_type */
135 printf(" *** Faulty type or entity! \n");
139 /* execute post method */
146 /** Check wether node contains types or entities as an attribute.
147 If so start a walk over that information. */
148 static void start_type_walk(ir_node *node, void *env) {
150 type_walk_func *post;
153 pre = ((type_walk_env *)env)->pre;
154 post = ((type_walk_env *)env)->post;
155 envi = ((type_walk_env *)env)->env;
159 switch (get_irn_opcode(node)) { /* node label */
161 if ( (get_SymConst_kind(node) == type_tag)
162 || (get_SymConst_kind(node) == size))
163 type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi);
166 type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi);
169 type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi);
172 type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi);
175 type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi);
182 void type_walk(void (pre)(type_or_ent*, void*),
183 void (post)(type_or_ent*, void*),
187 /*type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
188 global type is on the list visited below, too. */
189 for (i = 0; i < get_irp_n_types(); i++) {
190 type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env);
192 type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
195 void type_walk_irg (ir_graph *irg,
196 void (*pre)(type_or_ent*, void*),
197 void (*post)(type_or_ent*, void*),
200 ir_graph *rem = current_ir_graph;
201 /* this is needed to pass the parameters to the walker that actually
202 walks the type information */
203 type_walk_env type_env;
206 type_env.post = post;
209 current_ir_graph = irg;
211 /* We walk over the irg to find all irnodes that contain an attribute
212 with type information. If we find one we call a type walker to
213 touch the reachable type information.
214 The same type can be referenced by several irnodes. To avoid
215 repeated visits of the same type node we must decrease the
216 type visited flag for each walk. This is done in start_type_walk().
217 Here we initially increase the flag. We only call type_walk_2 that does
218 not increase the flag.
221 irg_walk(get_irg_end(irg), start_type_walk, NULL, &type_env);
223 type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env);
225 type_walk_2((type_or_ent *)get_irg_frame_type(irg), pre, post, env);
227 current_ir_graph = rem;
231 static void type_walk_s2s_2(type_or_ent *tore,
232 void (*pre)(type_or_ent*, void*),
233 void (*post)(type_or_ent*, void*),
239 switch (get_kind(tore)) {
241 if (((entity *)tore)->visit >= type_visited) return;
244 if(type_id == get_type_tpop((type*)tore)) {
245 type_walk_s2s_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
248 if (((type *)tore)->visit >= type_visited) return;
255 switch (get_kind(tore)) {
258 type *tp = (type *)tore;
259 mark_type_visited(tp);
260 switch (get_type_tpop_code(tp)) {
263 for (i = 0; i < get_class_n_supertypes(tp); i++) {
264 type_walk_s2s_2((type_or_ent *)get_class_supertype(tp, i), pre,
267 /* execute pre method */
270 tp = skip_tid((type*)tore);
272 for (i = 0; i < get_class_n_subtypes(tp); i++) {
273 type_walk_s2s_2((type_or_ent *)get_class_subtype(tp, i), pre,
277 /* execute post method */
286 case tpo_enumeration:
293 printf(" *** Faulty type! \n");
296 } break; /* end case k_type */
301 printf(" *** Faulty type or entity! \n");
307 void type_walk_super2sub(
308 void (*pre)(type_or_ent*, void*),
309 void (*post)(type_or_ent*, void*),
315 type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env);
316 for (i = 0; i < get_irp_n_types(); i++) {
317 tp = get_irp_type(i);
318 type_walk_s2s_2((type_or_ent *)tp, pre, post, env);
322 /*****************************************************************************/
325 type_walk_super_2(type_or_ent *tore,
326 void (*pre)(type_or_ent*, void*),
327 void (*post)(type_or_ent*, void*),
333 switch (get_kind(tore)) {
335 if (((entity *)tore)->visit >= type_visited) return;
338 if(type_id == get_type_tpop((type*)tore)) {
339 type_walk_super_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
342 if (((type *)tore)->visit >= type_visited) return;
349 switch (get_kind(tore)) {
352 type *tp = (type *)tore;
353 mark_type_visited(tp);
354 switch (get_type_tpop_code(tp)) {
357 /* execute pre method */
360 tp = skip_tid((type*)tore);
362 for (i = 0; i < get_class_n_supertypes(tp); i++) {
363 type_walk_super_2((type_or_ent *)get_class_supertype(tp, i), pre,
367 /* execute post method */
376 case tpo_enumeration:
383 printf(" *** Faulty type! \n");
386 } break; /* end case k_type */
391 printf(" *** Faulty type or entity! \n");
397 void type_walk_super(
398 void (*pre)(type_or_ent*, void*),
399 void (*post)(type_or_ent*, void*),
404 type_walk_super_2((type_or_ent *)get_glob_type(), pre, post, env);
405 for (i = 0; i < get_irp_n_types(); i++) {
406 tp = get_irp_type(i);
407 type_walk_super_2((type_or_ent *)tp, pre, post, env);
411 /*****************************************************************************/
415 class_walk_s2s_2(type *tp,
416 void (*pre)(type*, void*),
417 void (*post)(type*, void*),
423 if (tp->visit >= type_visited) return;
425 assert(is_class_type(tp));
426 /* Assure all supertypes are visited before */
427 for (i=0; i < get_class_n_supertypes(tp); i++) {
428 if (get_type_visited(get_class_supertype(tp, i)) < type_visited)
432 mark_type_visited(tp);
434 /* execute pre method */
438 tp = skip_tid((type*)tp);
439 for (i=0; i<get_class_n_subtypes(tp); i++) {
440 class_walk_s2s_2(get_class_subtype(tp, i), pre, post, env);
442 /* execute post method */
450 void class_walk_super2sub(
451 void (*pre)(type*, void*),
452 void (*post)(type*, void*),
459 for (i = 0; i < get_irp_n_types(); i++) {
460 tp = get_irp_type(i);
461 if (is_class_type(tp) &&
462 (get_class_n_supertypes(tp) == 0) &&
463 (tp->visit < type_visited) &&
464 (!is_frame_type(tp)) &&
465 (tp != get_glob_type())) {
466 class_walk_s2s_2(tp, pre, post, env);
471 void class_walk_super2sub(
472 void (*pre)(type*, void*),
473 void (post)(type*, void*),
480 for (i = 0; i < get_irp_n_types(); i++) {
481 tp = get_irp_type(i);
482 if (is_class_type(tp) &&
483 (get_class_n_supertypes(tp) == 0) &&
484 (tp->visit < type_visited)) {
485 assert(!is_frame_type(tp));
486 assert(tp != get_glob_type());
487 class_walk_s2s_2(tp, pre, post, env);
493 /* Walks over all entities in the type */
494 void walk_types_entities(
496 void (*doit)(entity*, void*),
500 switch(get_type_tpop_code(tp)) {
502 for (i=0; i<get_class_n_members(tp); i++)
503 doit(get_class_member(tp, i), env);
506 for (i=0; i<get_struct_n_members(tp); i++)
507 doit(get_struct_member(tp, i), env);
510 for (i = 0; i < get_union_n_members(tp); i++)
511 doit(get_union_member(tp, i), env);
514 doit(get_array_element_entity(tp), env);
517 case tpo_enumeration: