X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftypewalk.c;h=4dcae5ac653d2f6dabe0e1187dbdbc44618ce32c;hb=ec68b2aaadb9504d101e6cbc4a58c69f3897f489;hp=54d5efad25dcca6a0267a5ed821cfb931a27cddd;hpb=d98727840128960a4a36c3ccabb56d1653bb5f8a;p=libfirm diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c index 54d5efad2..4dcae5ac6 100644 --- a/ir/tr/typewalk.c +++ b/ir/tr/typewalk.c @@ -1,44 +1,55 @@ -/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe -* All rights reserved. -* -* Author: Goetz Lindenmaier -* -* 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 -*/ - -/* $Id$ */ +/* + * Project: libFIRM + * File name: ir/tr/typewalk.c + * Purpose: Traverse the type information. + * Author: Goetz Lindenmaier + * Modified by: + * Created: + * CVS-ID: $Id$ + * Copyright: (c) 1999-2003 Universität Karlsruhe + * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + */ + +/* + * 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 +# include "config.h" +#endif + +#ifdef HAVE_STDLIB_H +# include #endif -#include #include -#include "irgwalk.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 "typewalk.h" #include "entity_t.h" #include "type_t.h" +#include "type_or_entity.h" +#include "typegmod.h" + +#include "irprog_t.h" +#include "irgraph_t.h" +#include "irnode_t.h" +#include "irgwalk.h" typedef struct type_walk_env { - void *pre; - void *post; + type_walk_func *pre; + type_walk_func *post; void *env; } type_walk_env; static 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; @@ -123,10 +134,12 @@ static void type_walk_2(type_or_ent *tore, break; case tpo_primitive: case tpo_id: + case tpo_none: + case tpo_unknown: /* a leave. */ break; default: - printf(" *** Faulty type! \n"); + assert(0 && "Faulty type"); break; } } break; /* end case k_type */ @@ -142,17 +155,23 @@ static void type_walk_2(type_or_ent *tore, return; } +/** Check wether 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 *env) { - void *pre = ((type_walk_env *)env)->pre; - void *post = ((type_walk_env *)env)->post; - void *envi = ((type_walk_env *)env)->env; + type_walk_func *pre; + type_walk_func *post; + void *envi; + + pre = ((type_walk_env *)env)->pre; + post = ((type_walk_env *)env)->post; + 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)) + 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); break; case iro_Sel: @@ -167,45 +186,57 @@ static void start_type_walk(ir_node *node, void *env) { case iro_Free: type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi); break; + case iro_Cast: + type_walk_2((type_or_ent *)get_Cast_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; +void type_walk(type_walk_func *pre, type_walk_func *post, void *env) { + int i, n_types = get_irp_n_types(); + ++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++) { + for (i = 0; i < 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_irg (ir_graph *irg, - void (pre)(type_or_ent*, void*), - void (post)(type_or_ent*, void*), + void (*pre)(type_or_ent*, void*), + void (*post)(type_or_ent*, void*), void *env) { + ir_graph *rem = current_ir_graph; /* this is needed to pass the parameters to the walker that actually walks the type information */ - type_walk_env* type_env; - type_env = (type_walk_env *) malloc (sizeof(type_walk_env)); - type_env->pre = pre; - type_env->post = post; - type_env->env = env; - + type_walk_env type_env; + + type_env.pre = pre; + type_env.post = post; + type_env.env = env; + + current_ir_graph = irg; + + /* We walk over the irg to find all irnodes that contain an attribute + with type information. If we find one we call a type walker to + touch the reachable type information. + 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 + not increase the flag. + */ ++type_visited; - irg_walk(get_irg_end(irg), start_type_walk, NULL, type_env); + irg_walk(get_irg_end(irg), start_type_walk, NULL, &type_env); - type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env); + type_walk_2((type_or_ent *)get_irg_entity(irg), pre, post, env); type_walk_2((type_or_ent *)get_irg_frame_type(irg), pre, post, env); - free(type_env); + current_ir_graph = rem; return; } @@ -290,11 +321,11 @@ void type_walk_super2sub( void (*post)(type_or_ent*, void*), void *env) { - int i; + int i, n_types = get_irp_n_types(); 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++) { + for (i = 0; i < n_types; i++) { tp = get_irp_type(i); type_walk_s2s_2((type_or_ent *)tp, pre, post, env); } @@ -379,11 +410,11 @@ void type_walk_super( void (*pre)(type_or_ent*, void*), void (*post)(type_or_ent*, void*), void *env) { - int i; + int i, n_types = get_irp_n_types(); 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++) { + for (i = 0; i < n_types; i++) { tp = get_irp_type(i); type_walk_super_2((type_or_ent *)tp, pre, post, env); } @@ -427,38 +458,16 @@ class_walk_s2s_2(type *tp, return; } -#if 0 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) && - (!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; + int i, n_types = get_irp_n_types(); type *tp; ++type_visited; - for (i = 0; i < get_irp_n_types(); i++) { + for (i = 0; i < n_types; i++) { tp = get_irp_type(i); if (is_class_type(tp) && (get_class_n_supertypes(tp) == 0) &&