-/* 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 <config.h>
#include "irprog.h"
#include "type_or_entity.h"
#include "typegmod.h"
+#include "typewalk.h"
/* Make types visible to allow most efficient access */
#include "entity_t.h"
#include "type_t.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 (*pre)(type_or_ent*, void*),
+ void (*post)(type_or_ent*, void*),
void *env)
{
int i;
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:
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 type_walk(type_walk_func *pre,
+ type_walk_func *post,
void *env) {
int i;
++type_visited;
}
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);
- free(type_env);
+ type_walk_2((type_or_ent *)get_irg_frame_type(irg), pre, post, env);
+
+ current_ir_graph = rem;
return;
}
static void type_walk_s2s_2(type_or_ent *tore,
- 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)
{
int i;
return;
}
-void type_walk_super2sub(void (pre)(type_or_ent*, void*),
- void (post)(type_or_ent*, void*),
- void *env) {
+void type_walk_super2sub(
+ void (*pre)(type_or_ent*, void*),
+ void (*post)(type_or_ent*, void*),
+ void *env)
+{
int i;
type *tp;
++type_visited;
static void
type_walk_super_2(type_or_ent *tore,
- 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)
{
int i;
return;
}
-void type_walk_super(void (pre)(type_or_ent*, void*),
- void (post)(type_or_ent*, void*),
- void *env) {
+void type_walk_super(
+ void (*pre)(type_or_ent*, void*),
+ void (*post)(type_or_ent*, void*),
+ void *env) {
int i;
type *tp;
++type_visited;
static void
class_walk_s2s_2(type *tp,
- void (pre)(type*, void*),
- void (post)(type*, void*),
+ void (*pre)(type*, void*),
+ void (*post)(type*, void*),
void *env)
{
int i;
}
#if 0
-void class_walk_super2sub(void (pre)(type*, void*),
- void (post)(type*, void*),
- void *env) {
+void class_walk_super2sub(
+ void (*pre)(type*, void*),
+ void (*post)(type*, void*),
+ void *env)
+{
int i;
type *tp;
}
}
#endif
-void class_walk_super2sub(void (pre)(type*, void*),
- void (post)(type*, void*),
- void *env) {
+void class_walk_super2sub(
+ void (*pre)(type*, void*),
+ void (*post)(type*, void*),
+ void *env)
+{
int i;
type *tp;
/* Walks over all entities in the type */
-void walk_types_entities(type *tp,
- void (doit)(entity*, void*),
- void *env) {
+void walk_types_entities(
+ type *tp,
+ void (*doit)(entity*, void*),
+ void *env)
+{
int i;
switch(get_type_tpop_code(tp)) {
case tpo_class: {