X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftypewalk.c;h=ba916896aafb558f9cd3186aa8a2ca75da0965b8;hb=2e3dc475cf5d9edd3ecd6143f44fb1a45f7630d5;hp=362ff9e7294bdeba3dda9de7dbb50b9b74a44aad;hpb=fe9e69fb8335fb3d5b2231c4a3743dfcbcb6275a;p=libfirm diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c index 362ff9e72..ba916896a 100644 --- a/ir/tr/typewalk.c +++ b/ir/tr/typewalk.c @@ -9,15 +9,24 @@ ** - execute the post function after recursion */ -#include +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +# include +#endif + #include +#include #include "irgwalk.h" -#include "irgraph.h" +#include "irgraph_t.h" #include "irnode.h" +#include "irprog.h" #include "type_or_entity.h" +#include "typegmod.h" /* Make types visible to allow most efficient access */ -# include "entity_t.h" +#include "entity_t.h" +#include "type_t.h" typedef struct type_walk_env { void *pre; @@ -27,137 +36,159 @@ typedef struct type_walk_env { void type_walk_2(type_or_ent *tore, - void (pre)(type_or_ent*, void*), void (post)(type_or_ent*, void*), - void *env) + void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) { - int i, visited = 0; + int i; /* marked? */ switch (get_kind(tore)) { case k_entity: - if (((entity *)tore)->visit >= type_visited) visited = 1; break; - case k_type_class: - if (((type_class *)tore)->visit >= type_visited) visited = 1; break; - case k_type_strct: - if (((type_strct *)tore)->visit >= type_visited) visited = 1; break; - case k_type_method: - if (((type_method *)tore)->visit >= type_visited) visited = 1; break; - case k_type_union: - if (((type_union *)tore)->visit >= type_visited) visited = 1; break; - case k_type_array: - if (((type_array *)tore)->visit >= type_visited) visited = 1; break; - case k_type_enumeration: - if (((type_enumeration *)tore)->visit >= type_visited) visited = 1; break; - case k_type_pointer: - if (((type_pointer *)tore)->visit >= type_visited) visited = 1; break; - case k_type_primitive: - if (((type_primitive *)tore)->visit >= type_visited) visited = 1; break; + if (((entity *)tore)->visit >= type_visited) return; + break; + case k_type: + if(type_id == get_type_tpop((type*)tore)) { + type_walk_2((type_or_ent *)skip_tid((type *)tore), pre, post, env); + return; + } + if (((type *)tore)->visit >= type_visited) return; + break; default: break; } - if (!visited) { /* not marked. */ + /* execute pre method */ + if(pre) + pre(tore, env); - /* execute pre method */ - if(pre) - pre(tore, env); + /* iterate */ + switch (get_kind(tore)) { + case k_entity: + { - /* iterate */ - switch (get_kind(tore)) { - case k_entity: - { - entity *ent = (entity *)tore; - ent->visit = type_visited; - type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env); - type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env); - } - break; - case k_type_class: - ((type_class *)tore)->visit = type_visited; - /* !!!!! */ - break; - case k_type_strct: - ((type_strct *)tore)->visit = type_visited; - /* !!!!! */ - break; - case k_type_method: - { - type_method *meth = (type_method *)tore; - meth->visit = type_visited; - for (i = 0; i < get_method_arity(meth); i++) - type_walk_2((type_or_ent *)get_method_param_type(meth, i), pre, post, env); - for (i = 0; i < get_method_n_res(meth); i++) - type_walk_2((type_or_ent *)get_method_res_type(meth, i), pre, post, env); - } - break; - case k_type_union: - ((type_union *)tore)->visit = type_visited; - break; - case k_type_array: - ((type_array *)tore)->visit = type_visited; - type_walk_2((type_or_ent *)get_array_element_type((type_array *)tore), - pre, post, env); - break; - case k_type_enumeration: - ((type_enumeration *)tore)->visit = type_visited; - /* a leave */ - break; - case k_type_pointer: - ((type_pointer *)tore)->visit = type_visited; - type_walk_2((type_or_ent *)get_pointer_points_to_type((type_pointer *)tore), - pre, post, env); - break; - case k_type_primitive: - ((type_primitive *)tore)->visit = type_visited; - /* a leave. */ - break; - default: - break; + entity *ent = (entity *)tore; + ent->visit = type_visited; + type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env); + type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env); } - - /* execute post method */ - if(post) - post(tore, env); + break; + case k_type: + { + type *tp = (type *)tore; + mark_type_visited(tp); + switch (get_type_tpop_code(tp)) { + case tpo_class: + { + for (i=0; ipre; void *post = ((type_walk_env *)env)->post; - void *envi = ((type_walk_env *)env)->env; + void *envi = ((type_walk_env *)env)->env; assert(node); - switch (get_irn_opcode(node)) { /* node label */ - case iro_SymConst: - if ( (get_SymConst_kind(node) == type_tag) - || (get_SymConst_kind(node) == size)) - type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi); - break; - case iro_Sel: - type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi); - break; - case iro_Call: - type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi); - break; - case iro_Alloc: - type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi); - break; - case iro_Free: - printf("here in typewalk\n"); - type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi); - break; - assert(node); - default: - break; - } + switch (get_irn_opcode(node)) { /* node label */ + case iro_SymConst: + if ( (get_SymConst_kind(node) == type_tag) + || (get_SymConst_kind(node) == size)) + type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi); + break; + case iro_Sel: + type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi); + break; + case iro_Call: + type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi); + break; + case iro_Alloc: + type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi); + break; + case iro_Free: + type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi); + break; + default: + break; + } +} + +void type_walk(void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) { + int i; + ++type_visited; + /*type_walk_2((type_or_ent *)get_glob_type(), pre, post, env); + global type is on the list visited below, too. */ + for (i = 0; i < get_irp_n_types(); i++) { + type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env); + } + type_walk_2((type_or_ent *)get_glob_type(), pre, post, env); } -void type_walk(ir_graph *irg, - void (pre)(type_or_ent*, void*), void (post)(type_or_ent*, void*), - void *env) +void type_walk_irg (ir_graph *irg, + void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) { /* this is needed to pass the parameters to the walker that actually walks the type information */ @@ -172,6 +203,291 @@ void type_walk(ir_graph *irg, type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env); - /* @@@ free type_walk_env!! */ + free(type_env); + return; +} + +void type_walk_s2s_2(type_or_ent *tore, + void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) +{ + int i; + + /* marked? */ + switch (get_kind(tore)) { + case k_entity: + if (((entity *)tore)->visit >= type_visited) return; + break; + case k_type: + if(type_id == get_type_tpop((type*)tore)) { + type_walk_s2s_2((type_or_ent *)skip_tid((type *)tore), pre, post, env); + return; + } + if (((type *)tore)->visit >= type_visited) return; + break; + default: + break; + } + + /* iterate */ + switch (get_kind(tore)) { + case k_type: + { + type *tp = (type *)tore; + mark_type_visited(tp); + switch (get_type_tpop_code(tp)) { + case tpo_class: + { + for (i = 0; i < get_class_n_supertypes(tp); i++) { + type_walk_s2s_2((type_or_ent *)get_class_supertype(tp, i), pre, + post, env); + } + /* execute pre method */ + if(pre) + pre(tore, env); + tp = skip_tid((type*)tore); + + for (i = 0; i < get_class_n_subtypes(tp); i++) { + type_walk_s2s_2((type_or_ent *)get_class_subtype(tp, i), pre, + post, env); + } + + /* execute post method */ + if(post) + post(tore, env); + } + break; + case tpo_struct: + case tpo_method: + case tpo_union: + case tpo_array: + case tpo_enumeration: + case tpo_pointer: + case tpo_primitive: + case tpo_id: + /* dont care */ + break; + default: + printf(" *** Faulty type! \n"); + break; + } + } break; /* end case k_type */ + case k_entity: + /* dont care */ + break; + default: + printf(" *** Faulty type or entity! \n"); + break; + } + return; +} + +void type_walk_super2sub(void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) { + int i; + type *tp; + ++type_visited; + type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env); + for (i = 0; i < get_irp_n_types(); i++) { + tp = get_irp_type(i); + type_walk_s2s_2((type_or_ent *)tp, pre, post, env); + } +} + +/*****************************************************************************/ + +static +void type_walk_super_2(type_or_ent *tore, + void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) +{ + int i; + + /* marked? */ + switch (get_kind(tore)) { + case k_entity: + if (((entity *)tore)->visit >= type_visited) return; + break; + case k_type: + if(type_id == get_type_tpop((type*)tore)) { + type_walk_super_2((type_or_ent *)skip_tid((type *)tore), pre, post, env); + return; + } + if (((type *)tore)->visit >= type_visited) return; + break; + default: + break; + } + + /* iterate */ + switch (get_kind(tore)) { + case k_type: + { + type *tp = (type *)tore; + mark_type_visited(tp); + switch (get_type_tpop_code(tp)) { + case tpo_class: + { + /* execute pre method */ + if(pre) + pre(tore, env); + tp = skip_tid((type*)tore); + + for (i = 0; i < get_class_n_supertypes(tp); i++) { + type_walk_super_2((type_or_ent *)get_class_supertype(tp, i), pre, + post, env); + } + + /* execute post method */ + if(post) + post(tore, env); + } + break; + case tpo_struct: + case tpo_method: + case tpo_union: + case tpo_array: + case tpo_enumeration: + case tpo_pointer: + case tpo_primitive: + case tpo_id: + /* dont care */ + break; + default: + printf(" *** Faulty type! \n"); + break; + } + } break; /* end case k_type */ + case k_entity: + /* dont care */ + break; + default: + printf(" *** Faulty type or entity! \n"); + break; + } + return; +} + +void type_walk_super(void (pre)(type_or_ent*, void*), + void (post)(type_or_ent*, void*), + void *env) { + int i; + type *tp; + ++type_visited; + type_walk_super_2((type_or_ent *)get_glob_type(), pre, post, env); + for (i = 0; i < get_irp_n_types(); i++) { + tp = get_irp_type(i); + type_walk_super_2((type_or_ent *)tp, pre, post, env); + } +} + +/*****************************************************************************/ + + +void class_walk_s2s_2(type *tp, + void (pre)(type*, void*), + void (post)(type*, void*), + void *env) +{ + int i; + + /* marked? */ + if (tp->visit >= type_visited) return; + + assert(is_class_type(tp)); + /* Assure all supertypes are visited before */ + for (i=0; i < get_class_n_supertypes(tp); i++) { + if (get_type_visited(get_class_supertype(tp, i)) < type_visited) + return; + } + + mark_type_visited(tp); + + /* execute pre method */ + if(pre) + pre(tp, env); + + tp = skip_tid((type*)tp); + for (i=0; ivisit < type_visited) && + (!is_frame_type(tp)) && + (tp != get_glob_type())) { + class_walk_s2s_2(tp, pre, post, env); + } + } +} +#endif +void class_walk_super2sub(void (pre)(type*, void*), + void (post)(type*, void*), + void *env) { + int i; + type *tp; + + ++type_visited; + for (i = 0; i < get_irp_n_types(); i++) { + tp = get_irp_type(i); + if (is_class_type(tp) && + (get_class_n_supertypes(tp) == 0) && + (tp->visit < type_visited)) { + assert(!is_frame_type(tp)); + assert(tp != get_glob_type()); + class_walk_s2s_2(tp, pre, post, env); + } + } +} + + +/* Walks over all entities in the type */ +void walk_types_entities(type *tp, + void (doit)(entity*, void*), + void *env) { + int i; + switch(get_type_tpop_code(tp)) { + case tpo_class: { + for (i=0; i