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);
178 type_walk_2((type_or_ent *)get_Cast_type(node), pre, post, envi);
185 void type_walk(void (pre)(type_or_ent*, void*),
186 void (post)(type_or_ent*, void*),
190 /*type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
191 global type is on the list visited below, too. */
192 for (i = 0; i < get_irp_n_types(); i++) {
193 type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env);
195 type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
198 void type_walk_irg (ir_graph *irg,
199 void (*pre)(type_or_ent*, void*),
200 void (*post)(type_or_ent*, void*),
203 ir_graph *rem = current_ir_graph;
204 /* this is needed to pass the parameters to the walker that actually
205 walks the type information */
206 type_walk_env type_env;
209 type_env.post = post;
212 current_ir_graph = irg;
214 /* We walk over the irg to find all irnodes that contain an attribute
215 with type information. If we find one we call a type walker to
216 touch the reachable type information.
217 The same type can be referenced by several irnodes. To avoid
218 repeated visits of the same type node we must decrease the
219 type visited flag for each walk. This is done in start_type_walk().
220 Here we initially increase the flag. We only call type_walk_2 that does
221 not increase the flag.
224 irg_walk(get_irg_end(irg), start_type_walk, NULL, &type_env);
226 type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env);
228 type_walk_2((type_or_ent *)get_irg_frame_type(irg), pre, post, env);
230 current_ir_graph = rem;
234 static void type_walk_s2s_2(type_or_ent *tore,
235 void (*pre)(type_or_ent*, void*),
236 void (*post)(type_or_ent*, void*),
242 switch (get_kind(tore)) {
244 if (((entity *)tore)->visit >= type_visited) return;
247 if(type_id == get_type_tpop((type*)tore)) {
248 type_walk_s2s_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
251 if (((type *)tore)->visit >= type_visited) return;
258 switch (get_kind(tore)) {
261 type *tp = (type *)tore;
262 mark_type_visited(tp);
263 switch (get_type_tpop_code(tp)) {
266 for (i = 0; i < get_class_n_supertypes(tp); i++) {
267 type_walk_s2s_2((type_or_ent *)get_class_supertype(tp, i), pre,
270 /* execute pre method */
273 tp = skip_tid((type*)tore);
275 for (i = 0; i < get_class_n_subtypes(tp); i++) {
276 type_walk_s2s_2((type_or_ent *)get_class_subtype(tp, i), pre,
280 /* execute post method */
289 case tpo_enumeration:
296 printf(" *** Faulty type! \n");
299 } break; /* end case k_type */
304 printf(" *** Faulty type or entity! \n");
310 void type_walk_super2sub(
311 void (*pre)(type_or_ent*, void*),
312 void (*post)(type_or_ent*, void*),
318 type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env);
319 for (i = 0; i < get_irp_n_types(); i++) {
320 tp = get_irp_type(i);
321 type_walk_s2s_2((type_or_ent *)tp, pre, post, env);
325 /*****************************************************************************/
328 type_walk_super_2(type_or_ent *tore,
329 void (*pre)(type_or_ent*, void*),
330 void (*post)(type_or_ent*, void*),
336 switch (get_kind(tore)) {
338 if (((entity *)tore)->visit >= type_visited) return;
341 if(type_id == get_type_tpop((type*)tore)) {
342 type_walk_super_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
345 if (((type *)tore)->visit >= type_visited) return;
352 switch (get_kind(tore)) {
355 type *tp = (type *)tore;
356 mark_type_visited(tp);
357 switch (get_type_tpop_code(tp)) {
360 /* execute pre method */
363 tp = skip_tid((type*)tore);
365 for (i = 0; i < get_class_n_supertypes(tp); i++) {
366 type_walk_super_2((type_or_ent *)get_class_supertype(tp, i), pre,
370 /* execute post method */
379 case tpo_enumeration:
386 printf(" *** Faulty type! \n");
389 } break; /* end case k_type */
394 printf(" *** Faulty type or entity! \n");
400 void type_walk_super(
401 void (*pre)(type_or_ent*, void*),
402 void (*post)(type_or_ent*, void*),
407 type_walk_super_2((type_or_ent *)get_glob_type(), pre, post, env);
408 for (i = 0; i < get_irp_n_types(); i++) {
409 tp = get_irp_type(i);
410 type_walk_super_2((type_or_ent *)tp, pre, post, env);
414 /*****************************************************************************/
418 class_walk_s2s_2(type *tp,
419 void (*pre)(type*, void*),
420 void (*post)(type*, void*),
426 if (tp->visit >= type_visited) return;
428 assert(is_class_type(tp));
429 /* Assure all supertypes are visited before */
430 for (i=0; i < get_class_n_supertypes(tp); i++) {
431 if (get_type_visited(get_class_supertype(tp, i)) < type_visited)
435 mark_type_visited(tp);
437 /* execute pre method */
441 tp = skip_tid((type*)tp);
442 for (i=0; i<get_class_n_subtypes(tp); i++) {
443 class_walk_s2s_2(get_class_subtype(tp, i), pre, post, env);
445 /* execute post method */
453 void class_walk_super2sub(
454 void (*pre)(type*, void*),
455 void (*post)(type*, void*),
462 for (i = 0; i < get_irp_n_types(); i++) {
463 tp = get_irp_type(i);
464 if (is_class_type(tp) &&
465 (get_class_n_supertypes(tp) == 0) &&
466 (tp->visit < type_visited) &&
467 (!is_frame_type(tp)) &&
468 (tp != get_glob_type())) {
469 class_walk_s2s_2(tp, pre, post, env);
474 void class_walk_super2sub(
475 void (*pre)(type*, void*),
476 void (post)(type*, void*),
483 for (i = 0; i < get_irp_n_types(); i++) {
484 tp = get_irp_type(i);
485 if (is_class_type(tp) &&
486 (get_class_n_supertypes(tp) == 0) &&
487 (tp->visit < type_visited)) {
488 assert(!is_frame_type(tp));
489 assert(tp != get_glob_type());
490 class_walk_s2s_2(tp, pre, post, env);
496 /* Walks over all entities in the type */
497 void walk_types_entities(
499 void (*doit)(entity*, void*),
503 switch(get_type_tpop_code(tp)) {
505 for (i=0; i<get_class_n_members(tp); i++)
506 doit(get_class_member(tp, i), env);
509 for (i=0; i<get_struct_n_members(tp); i++)
510 doit(get_struct_member(tp, i), env);
513 for (i = 0; i < get_union_n_members(tp); i++)
514 doit(get_union_member(tp, i), env);
517 doit(get_array_element_entity(tp), env);
520 case tpo_enumeration: