From: Michael Beck Date: Tue, 26 Jul 2005 15:46:34 +0000 (+0000) Subject: used functions from entity_t.h and type_t.h to access fields of type and entity. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=78981649ac1ba4b03e440a96606e122c07ac87da;p=libfirm used functions from entity_t.h and type_t.h to access fields of type and entity. walks to the initialization values of a entity (to visit entities that are initializers for other entities first). [r6306] --- diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c index 961e66889..92499827d 100644 --- a/ir/tr/typewalk.c +++ b/ir/tr/typewalk.c @@ -10,14 +10,15 @@ * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ -/* - * traverse the type information. The walker walks the whole ir graph +/** + * @file typewalk.c + * + * Traverse the type information. The walker walks the whole ir graph * to find the distinct type trees in the type graph forest. * - execute the pre function before recursion * - execute the post function after recursion */ - #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -39,169 +40,203 @@ #include "irnode_t.h" #include "irgwalk.h" +/** + * The walker environment + */ typedef struct type_walk_env { - type_walk_func *pre; - type_walk_func *post; - void *env; + type_walk_func *pre; /**< Pre-walker function */ + type_walk_func *post; /**< Post-walker function */ + void *env; /**< environment for walker functions */ } type_walk_env; +/* a walker for irn's */ +static void irn_type_walker( + ir_node *node, type_walk_func *pre, type_walk_func *post, void *env); -static void type_walk_2(type_or_ent *tore, - void (*pre) (type_or_ent*, void*), - void (*post)(type_or_ent*, void*), +/** + * Main walker: walks over all used types/entities of a + * type entity. + */ +static void do_type_walk(type_or_ent *tore, + type_walk_func *pre, + type_walk_func *post, void *env) { - int i; + int i; + entity *ent; + type *tp; + ir_node *n; /* marked? */ switch (get_kind(tore)) { case k_entity: - if (((entity *)tore)->visit >= type_visited) return; + ent = (entity *)tore; + if (entity_visited(ent)) 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; + tp = skip_tid((type *)tore); + if (type_visited(tp)) return; break; default: break; } /* execute pre method */ - if(pre) + if (pre) pre(tore, env); /* 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); + mark_entity_visited(ent); + do_type_walk((type_or_ent *)get_entity_owner(ent), pre, post, env); + do_type_walk((type_or_ent *)get_entity_type(ent), pre, post, env); + + if (get_entity_variability(ent) != variability_uninitialized) { + /* walk over the value types */ + if (is_atomic_entity(ent)) { + n = get_atomic_ent_value(ent); + irn_type_walker(n, pre, post, env); + } + else { + for (i = 0; i < get_compound_ent_n_values(ent); ++i) { + n = get_compound_ent_value(ent, i); + irn_type_walker(n, pre, post, 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; - post = ((type_walk_env *)env)->post; - envi = ((type_walk_env *)env)->env; +static void irn_type_walker( + ir_node *node, type_walk_func *pre, type_walk_func *post, void *env) +{ + symconst_kind kind; assert(node); switch (get_irn_opcode(node)) { /* node label */ case iro_SymConst: - if ( (get_SymConst_kind(node) ==symconst_type_tag) - || (get_SymConst_kind(node) ==symconst_size)) - type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi); + kind = get_SymConst_kind(node); + if (kind == symconst_type_tag || kind == symconst_size) + do_type_walk((type_or_ent *)get_SymConst_type(node), pre, post, env); + else if (kind == symconst_addr_ent) + do_type_walk((type_or_ent *)get_SymConst_entity(node), pre, post, env); break; case iro_Sel: - type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi); + do_type_walk((type_or_ent *)get_Sel_entity(node), pre, post, env); break; case iro_Call: - type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi); + do_type_walk((type_or_ent *)get_Call_type(node), pre, post, env); break; case iro_Alloc: - type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi); + do_type_walk((type_or_ent *)get_Alloc_type(node), pre, post, env); break; case iro_Free: - type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi); + do_type_walk((type_or_ent *)get_Free_type(node), pre, post, env); break; case iro_Cast: - type_walk_2((type_or_ent *)get_Cast_type(node), pre, post, envi); + do_type_walk((type_or_ent *)get_Cast_type(node), pre, post, env); break; default: break; } } +/** Check whether node contains types or entities as an attribute. + If so start a walk over that information. */ +static void start_type_walk(ir_node *node, void *ctx) { + type_walk_env *env = ctx; + type_walk_func *pre; + type_walk_func *post; + void *envi; + + pre = env->pre; + post = env->post; + envi = env->env; + + irn_type_walker(node, pre, post, envi); +} + +/* walker: walks over all types */ void type_walk(type_walk_func *pre, type_walk_func *post, void *env) { int i, n_types = get_irp_n_types(); ++type_visited; for (i = 0; i < n_types; i++) { - type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env); + do_type_walk((type_or_ent *)get_irp_type(i), pre, post, env); } - type_walk_2((type_or_ent *)get_glob_type(), pre, post, env); + do_type_walk((type_or_ent *)get_glob_type(), pre, post, env); } void type_walk_irg (ir_graph *irg, @@ -226,15 +261,15 @@ void type_walk_irg (ir_graph *irg, The same type can be referenced by several irnodes. To avoid repeated visits of the same type node we must decrease the type visited flag for each walk. This is done in start_type_walk(). - Here we initially increase the flag. We only call type_walk_2 that does + Here we initially increase the flag. We only call do_type_walk that does not increase the flag. */ - ++type_visited; + inc_master_type_visited(); irg_walk(get_irg_end(irg), start_type_walk, NULL, &type_env); - type_walk_2((type_or_ent *)get_irg_entity(irg), pre, post, env); + do_type_walk((type_or_ent *)get_irg_entity(irg), pre, post, env); - type_walk_2((type_or_ent *)get_irg_frame_type(irg), pre, post, env); + do_type_walk((type_or_ent *)get_irg_frame_type(irg), pre, post, env); current_ir_graph = rem; return;