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"
27 /* Make types visible to allow most efficient access */
31 typedef struct type_walk_env {
38 static void type_walk_2(type_or_ent *tore,
39 void (*pre)(type_or_ent*, void*),
40 void (*post)(type_or_ent*, void*),
46 switch (get_kind(tore)) {
48 if (((entity *)tore)->visit >= type_visited) return;
51 if(type_id == get_type_tpop((type*)tore)) {
52 type_walk_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
55 if (((type *)tore)->visit >= type_visited) return;
61 /* execute pre method */
66 switch (get_kind(tore)) {
70 entity *ent = (entity *)tore;
71 ent->visit = type_visited;
72 type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env);
73 type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env);
78 type *tp = (type *)tore;
79 mark_type_visited(tp);
80 switch (get_type_tpop_code(tp)) {
83 for (i=0; i<get_class_n_supertypes(tp); i++)
84 type_walk_2((type_or_ent *)get_class_supertype(tp, i), pre, post, env);
85 for (i=0; i<get_class_n_members(tp); i++)
86 type_walk_2((type_or_ent *)get_class_member(tp, i), pre, post, env);
87 for (i=0; i<get_class_n_subtypes(tp); i++)
88 type_walk_2((type_or_ent *)get_class_subtype(tp, i), pre, post, env);
93 for (i=0; i<get_struct_n_members(tp); i++)
94 type_walk_2((type_or_ent *)get_struct_member(tp, i), pre, post, env);
99 for (i = 0; i < get_method_n_params(tp); i++)
100 type_walk_2((type_or_ent *)get_method_param_type(tp, i), pre, post, env);
101 for (i = 0; i < get_method_n_ress(tp); i++)
102 type_walk_2((type_or_ent *)get_method_res_type(tp, i), pre, post, env);
107 for (i = 0; i < get_union_n_members(tp); i++)
108 type_walk_2((type_or_ent *)get_union_member(tp, i), pre, post, env);
112 type_walk_2((type_or_ent *)get_array_element_type(tp),
114 type_walk_2((type_or_ent *)get_array_element_entity(tp),
117 case tpo_enumeration:
121 type_walk_2((type_or_ent *)get_pointer_points_to_type(tp),
129 printf(" *** Faulty type! \n");
132 } break; /* end case k_type */
134 printf(" *** Faulty type or entity! \n");
138 /* execute post method */
145 /** Check wether node contains types or entities as an attribute.
146 If so start a walk over that information. */
147 static void start_type_walk(ir_node *node, void *env) {
148 void *pre = ((type_walk_env *)env)->pre;
149 void *post = ((type_walk_env *)env)->post;
150 void *envi = ((type_walk_env *)env)->env;
154 switch (get_irn_opcode(node)) { /* node label */
156 if ( (get_SymConst_kind(node) == type_tag)
157 || (get_SymConst_kind(node) == size))
158 type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi);
161 type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi);
164 type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi);
167 type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi);
170 type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi);
177 void type_walk(void (pre)(type_or_ent*, void*),
178 void (post)(type_or_ent*, void*),
182 /*type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
183 global type is on the list visited below, too. */
184 for (i = 0; i < get_irp_n_types(); i++) {
185 type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env);
187 type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
190 void type_walk_irg (ir_graph *irg,
191 void (*pre)(type_or_ent*, void*),
192 void (*post)(type_or_ent*, void*),
195 ir_graph *rem = current_ir_graph;
196 /* this is needed to pass the parameters to the walker that actually
197 walks the type information */
198 type_walk_env type_env;
201 type_env.post = post;
204 current_ir_graph = irg;
206 /* We walk over the irg to find all irnodes that contain an attribute
207 with type information. If we find one we call a type walker to
208 touch the reachable type information.
209 The same type can be referenced by several irnodes. To avoid
210 repeated visits of the same type node we must decrease the
211 type visited flag for each walk. This is done in start_type_walk().
212 Here we initially increase the flag. We only call type_walk_2 that does
213 not increase the flag.
216 irg_walk(get_irg_end(irg), start_type_walk, NULL, &type_env);
218 type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env);
220 type_walk_2((type_or_ent *)get_irg_frame_type(irg), pre, post, env);
222 current_ir_graph = rem;
226 static void type_walk_s2s_2(type_or_ent *tore,
227 void (*pre)(type_or_ent*, void*),
228 void (*post)(type_or_ent*, void*),
234 switch (get_kind(tore)) {
236 if (((entity *)tore)->visit >= type_visited) return;
239 if(type_id == get_type_tpop((type*)tore)) {
240 type_walk_s2s_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
243 if (((type *)tore)->visit >= type_visited) return;
250 switch (get_kind(tore)) {
253 type *tp = (type *)tore;
254 mark_type_visited(tp);
255 switch (get_type_tpop_code(tp)) {
258 for (i = 0; i < get_class_n_supertypes(tp); i++) {
259 type_walk_s2s_2((type_or_ent *)get_class_supertype(tp, i), pre,
262 /* execute pre method */
265 tp = skip_tid((type*)tore);
267 for (i = 0; i < get_class_n_subtypes(tp); i++) {
268 type_walk_s2s_2((type_or_ent *)get_class_subtype(tp, i), pre,
272 /* execute post method */
281 case tpo_enumeration:
288 printf(" *** Faulty type! \n");
291 } break; /* end case k_type */
296 printf(" *** Faulty type or entity! \n");
302 void type_walk_super2sub(
303 void (*pre)(type_or_ent*, void*),
304 void (*post)(type_or_ent*, void*),
310 type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env);
311 for (i = 0; i < get_irp_n_types(); i++) {
312 tp = get_irp_type(i);
313 type_walk_s2s_2((type_or_ent *)tp, pre, post, env);
317 /*****************************************************************************/
320 type_walk_super_2(type_or_ent *tore,
321 void (*pre)(type_or_ent*, void*),
322 void (*post)(type_or_ent*, void*),
328 switch (get_kind(tore)) {
330 if (((entity *)tore)->visit >= type_visited) return;
333 if(type_id == get_type_tpop((type*)tore)) {
334 type_walk_super_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
337 if (((type *)tore)->visit >= type_visited) return;
344 switch (get_kind(tore)) {
347 type *tp = (type *)tore;
348 mark_type_visited(tp);
349 switch (get_type_tpop_code(tp)) {
352 /* execute pre method */
355 tp = skip_tid((type*)tore);
357 for (i = 0; i < get_class_n_supertypes(tp); i++) {
358 type_walk_super_2((type_or_ent *)get_class_supertype(tp, i), pre,
362 /* execute post method */
371 case tpo_enumeration:
378 printf(" *** Faulty type! \n");
381 } break; /* end case k_type */
386 printf(" *** Faulty type or entity! \n");
392 void type_walk_super(
393 void (*pre)(type_or_ent*, void*),
394 void (*post)(type_or_ent*, void*),
399 type_walk_super_2((type_or_ent *)get_glob_type(), pre, post, env);
400 for (i = 0; i < get_irp_n_types(); i++) {
401 tp = get_irp_type(i);
402 type_walk_super_2((type_or_ent *)tp, pre, post, env);
406 /*****************************************************************************/
410 class_walk_s2s_2(type *tp,
411 void (*pre)(type*, void*),
412 void (*post)(type*, void*),
418 if (tp->visit >= type_visited) return;
420 assert(is_class_type(tp));
421 /* Assure all supertypes are visited before */
422 for (i=0; i < get_class_n_supertypes(tp); i++) {
423 if (get_type_visited(get_class_supertype(tp, i)) < type_visited)
427 mark_type_visited(tp);
429 /* execute pre method */
433 tp = skip_tid((type*)tp);
434 for (i=0; i<get_class_n_subtypes(tp); i++) {
435 class_walk_s2s_2(get_class_subtype(tp, i), pre, post, env);
437 /* execute post method */
445 void class_walk_super2sub(
446 void (*pre)(type*, void*),
447 void (*post)(type*, void*),
454 for (i = 0; i < get_irp_n_types(); i++) {
455 tp = get_irp_type(i);
456 if (is_class_type(tp) &&
457 (get_class_n_supertypes(tp) == 0) &&
458 (tp->visit < type_visited) &&
459 (!is_frame_type(tp)) &&
460 (tp != get_glob_type())) {
461 class_walk_s2s_2(tp, pre, post, env);
466 void class_walk_super2sub(
467 void (*pre)(type*, void*),
468 void (post)(type*, void*),
475 for (i = 0; i < get_irp_n_types(); i++) {
476 tp = get_irp_type(i);
477 if (is_class_type(tp) &&
478 (get_class_n_supertypes(tp) == 0) &&
479 (tp->visit < type_visited)) {
480 assert(!is_frame_type(tp));
481 assert(tp != get_glob_type());
482 class_walk_s2s_2(tp, pre, post, env);
488 /* Walks over all entities in the type */
489 void walk_types_entities(
491 void (*doit)(entity*, void*),
495 switch(get_type_tpop_code(tp)) {
497 for (i=0; i<get_class_n_members(tp); i++)
498 doit(get_class_member(tp, i), env);
501 for (i=0; i<get_struct_n_members(tp); i++)
502 doit(get_struct_member(tp, i), env);
505 for (i = 0; i < get_union_n_members(tp); i++)
506 doit(get_union_member(tp, i), env);
509 doit(get_array_element_entity(tp), env);
512 case tpo_enumeration: