-/* 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 <stdlib.h>
#include <stdio.h>
-#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;
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 */
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 *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_entity(irg), pre, post, env);
- type_walk_2((type_or_ent *)get_irg_ent(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;
}
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) {
- int i;
+void type_walk_super2sub(
+ void (*pre)(type_or_ent*, void*),
+ void (*post)(type_or_ent*, void*),
+ void *env)
+{
+ 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);
}
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) {
- int i;
+void type_walk_super(
+ void (*pre)(type_or_ent*, void*),
+ void (*post)(type_or_ent*, void*),
+ void *env) {
+ 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);
}
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;
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;
+void class_walk_super2sub(
+ void (*pre)(type*, void*),
+ void (*post)(type*, void*),
+ void *env)
+{
+ 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) &&
/* 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: {