becopyopt: Remove the unnecessary attribute name from struct copy_opt_t.
[libfirm] / ir / tr / typewalk.c
index 629084a..c510a4e 100644 (file)
@@ -1,42 +1,22 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
- *
  * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
 /**
- * @file    typewalk.c
+ * @file
  * @brief   Functionality to modify the type graph.
  * @author  Goetz Lindenmaier
- * @version $Id$
- * @summary
+ * @brief
  *
  * 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
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
+#include "config.h"
 
+#include <stdlib.h>
 #include <stdio.h>
 
 #include "entity_t.h"
@@ -46,6 +26,8 @@
 #include "irgraph_t.h"
 #include "irnode_t.h"
 #include "irgwalk.h"
+#include "error.h"
+#include "ircons.h"
 
 /**
  * The walker environment
@@ -60,29 +42,58 @@ typedef struct type_walk_env {
 static void irn_type_walker(
        ir_node *node, type_walk_func *pre, type_walk_func *post, void *env);
 
+static void walk_initializer(ir_initializer_t *initializer,
+                             type_walk_func *pre, type_walk_func *post,
+                             void *env)
+{
+       switch (initializer->kind) {
+       case IR_INITIALIZER_CONST:
+               irn_type_walker(initializer->consti.value, pre, post, env);
+               return;
+       case IR_INITIALIZER_TARVAL:
+       case IR_INITIALIZER_NULL:
+               return;
+
+       case IR_INITIALIZER_COMPOUND: {
+               size_t i;
+               for (i = 0; i < initializer->compound.n_initializers; ++i) {
+                       ir_initializer_t *subinitializer
+                               = initializer->compound.initializers[i];
+                       walk_initializer(subinitializer, pre, post, env);
+               }
+               return;
+       }
+       }
+       panic("invalid initializer found");
+}
+
 /**
  * Main walker: walks over all used types/entities of a
  * type entity.
  */
-static void do_type_walk(type_or_ent *tore,
+static void do_type_walk(type_or_ent tore,
                          type_walk_func *pre,
                          type_walk_func *post,
                          void *env)
 {
-       int       i, n_types, n_mem;
-       ir_entity *ent = NULL;
-       ir_type   *tp = NULL;
-       ir_node   *n;
+       size_t      i, n_types, n_mem;
+       ir_entity   *ent = NULL;
+       ir_type     *tp = NULL;
+       type_or_ent cont;
 
        /* marked? */
-       switch (get_kind(tore)) {
+       switch (get_kind(tore.ent)) {
        case k_entity:
-               ent = (ir_entity *)tore;
-               if (entity_visited(ent)) return;
+               ent = tore.ent;
+               if (entity_visited(ent))
+                       return;
+               mark_entity_visited(ent);
                break;
        case k_type:
-               tp = skip_tid((ir_type *)tore);
-               if (type_visited(tp)) return;
+               tp = tore.typ;
+               if (type_visited(tp))
+                       return;
+               mark_type_visited(tp);
                break;
        default:
                break;
@@ -93,71 +104,72 @@ static void do_type_walk(type_or_ent *tore,
                pre(tore, env);
 
        /* iterate */
-       switch (get_kind(tore)) {
+       switch (get_kind(tore.ent)) {
        case k_entity:
-               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 {
-                               n_mem = get_compound_ent_n_values(ent);
-                               for (i = 0; i < n_mem; ++i) {
-                                       n = get_compound_ent_value(ent, i);
-                                       irn_type_walker(n, pre, post, env);
-                               }
-                       }
+               cont.typ = get_entity_owner(ent);
+               do_type_walk(cont, pre, post, env);
+               cont.typ = get_entity_type(ent);
+               do_type_walk(cont, pre, post, env);
+
+               /* walk over the value types */
+               if (ent->initializer != NULL) {
+                       walk_initializer(ent->initializer, pre, post, env);
                }
                break;
        case k_type:
-               mark_type_visited(tp);
                switch (get_type_tpop_code(tp)) {
-
                case tpo_class:
                        n_types = get_class_n_supertypes(tp);
-                       for (i = 0; i < n_types; ++i)
-                               do_type_walk((type_or_ent *)get_class_supertype(tp, i), pre, post, env);
-
+                       for (i = 0; i < n_types; ++i) {
+                               cont.typ = get_class_supertype(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        n_mem = get_class_n_members(tp);
-                       for (i = 0; i < n_mem; ++i)
-                               do_type_walk((type_or_ent *)get_class_member(tp, i), pre, post, env);
-
+                       for (i = 0; i < n_mem; ++i) {
+                               cont.ent = get_class_member(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        n_types = get_class_n_subtypes(tp);
-                       for (i = 0; i < n_types; ++i)
-                               do_type_walk((type_or_ent *)get_class_subtype(tp, i), pre, post, env);
+                       for (i = 0; i < n_types; ++i) {
+                               cont.typ = get_class_subtype(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        break;
 
                case tpo_struct:
                        n_mem = get_struct_n_members(tp);
-                       for (i = 0; i < n_mem; ++i)
-                               do_type_walk((type_or_ent *)get_struct_member(tp, i), pre, post, env);
+                       for (i = 0; i < n_mem; ++i) {
+                               cont.ent = get_struct_member(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        break;
 
                case tpo_method:
                        n_mem = get_method_n_params(tp);
-                       for (i = 0; i < n_mem; ++i)
-                               do_type_walk((type_or_ent *)get_method_param_type(tp, i), pre, post, env);
-
+                       for (i = 0; i < n_mem; ++i) {
+                               cont.typ = get_method_param_type(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        n_mem = get_method_n_ress(tp);
-                       for (i = 0; i < n_mem; ++i)
-                               do_type_walk((type_or_ent *)get_method_res_type(tp, i), pre, post, env);
+                       for (i = 0; i < n_mem; ++i) {
+                               cont.typ = get_method_res_type(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        break;
 
                case tpo_union:
                        n_mem = get_union_n_members(tp);
-                       for (i = 0; i < n_mem; ++i)
-                               do_type_walk((type_or_ent *)get_union_member(tp, i), pre, post, env);
+                       for (i = 0; i < n_mem; ++i) {
+                               cont.ent = get_union_member(tp, i);
+                               do_type_walk(cont, pre, post, env);
+                       }
                        break;
 
                case tpo_array:
-                       do_type_walk((type_or_ent *)get_array_element_type(tp),
-                               pre, post, env);
-                       do_type_walk((type_or_ent *)get_array_element_entity(tp),
-                               pre, post, env);
+                       cont.typ = get_array_element_type(tp);
+                       do_type_walk(cont, pre, post, env);
+                       cont.ent = get_array_element_entity(tp);
+                       do_type_walk(cont, pre, post, env);
                        break;
 
                case tpo_enumeration:
@@ -165,17 +177,17 @@ static void do_type_walk(type_or_ent *tore,
                        break;
 
                case tpo_pointer:
-                       do_type_walk((type_or_ent *)get_pointer_points_to_type(tp),
-                               pre, post, env);
+                       cont.typ = get_pointer_points_to_type(tp);
+                       do_type_walk(cont, pre, post, env);
                        break;
 
+               case tpo_code:
                case tpo_primitive:
-               case tpo_id:
                case tpo_none:
                case tpo_unknown:
                        /* a leave. */
                        break;
-               default:
+               case tpo_uninitialized:
                        assert(0 && "Faulty type");
                        break;
                }
@@ -189,8 +201,6 @@ static void do_type_walk(type_or_ent *tore,
        /* execute post method */
        if (post)
                post(tore, env);
-
-       return;
 }
 
 /**  Check whether node contains types or entities as an attribute.
@@ -198,23 +208,23 @@ static void do_type_walk(type_or_ent *tore,
 static void irn_type_walker(
   ir_node *node, type_walk_func *pre, type_walk_func *post, void *env)
 {
-       ir_entity *ent;
-       ir_type *tp;
+       type_or_ent cont;
 
        assert(node);
 
-       ent = get_irn_entity_attr(node);
-       if (ent)
-               do_type_walk((type_or_ent *)ent, pre, post, env);
-       tp  = get_irn_type_attr(node);
-       if (tp)
-               do_type_walk((type_or_ent *)tp, pre, post, env);
+       cont.ent = get_irn_entity_attr(node);
+       if (cont.ent)
+               do_type_walk(cont, pre, post, env);
+       cont.typ = get_irn_type_attr(node);
+       if (cont.typ)
+               do_type_walk(cont, pre, post, env);
 }
 
 /**  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;
+static void start_type_walk(ir_node *node, void *ctx)
+{
+       type_walk_env *env = (type_walk_env*)ctx;
        type_walk_func *pre;
        type_walk_func *post;
        void *envi;
@@ -226,15 +236,20 @@ static void start_type_walk(ir_node *node, void *ctx) {
        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();
+void type_walk(type_walk_func *pre, type_walk_func *post, void *env)
+{
+       size_t      i, n_types = get_irp_n_types();
+       type_or_ent cont;
 
+       irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
        inc_master_type_visited();
        for (i = 0; i < n_types; ++i) {
-               do_type_walk((type_or_ent *)get_irp_type(i), pre, post, env);
+               cont.typ = get_irp_type(i);
+               do_type_walk(cont, pre, post, env);
        }
-       do_type_walk((type_or_ent *)get_glob_type(), pre, post, env);
+       cont.typ = get_glob_type();
+       do_type_walk(cont, pre, post, env);
+       irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
 }
 
 void type_walk_irg(ir_graph *irg,
@@ -246,6 +261,7 @@ void type_walk_irg(ir_graph *irg,
        /* this is needed to pass the parameters to the walker that actually
           walks the type information */
        type_walk_env type_env;
+       type_or_ent   cont;
 
        type_env.pre  = pre;
        type_env.post = post;
@@ -253,70 +269,72 @@ void type_walk_irg(ir_graph *irg,
 
        current_ir_graph = irg;
 
-       /* We walk over the irg to find all irnodes that contain an attribute
+       /* We walk over the irg to find all IR-nodes 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
+          The same type can be referenced by several IR-nodes.  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 do_type_walk that does
           not increase the flag.
        */
+       irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
        inc_master_type_visited();
        irg_walk(get_irg_end(irg), start_type_walk, NULL, &type_env);
 
-       do_type_walk((type_or_ent *)get_irg_entity(irg), pre, post, env);
+       cont.ent = get_irg_entity(irg);
+       do_type_walk(cont, pre, post, env);
 
-       do_type_walk((type_or_ent *)get_irg_frame_type(irg), pre, post, env);
+       cont.typ = get_irg_frame_type(irg);
+       do_type_walk(cont, pre, post, env);
 
        current_ir_graph = rem;
-       return;
+       irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
 }
 
-static void type_walk_s2s_2(type_or_ent *tore,
+static void type_walk_s2s_2(type_or_ent tore,
                             type_walk_func *pre,
                             type_walk_func *post,
                             void *env)
 {
-       int i, n;
+       type_or_ent cont;
 
        /* marked? */
-       switch (get_kind(tore)) {
+       switch (get_kind(tore.ent)) {
        case k_entity:
-               if (entity_visited((ir_entity *)tore)) return;
+               if (entity_visited(tore.ent)) return;
                break;
        case k_type:
-               if (type_id == get_type_tpop((ir_type*)tore)) {
-                       type_walk_s2s_2((type_or_ent *)skip_tid((ir_type *)tore), pre, post, env);
-                       return;
-               }
-               if (type_visited((ir_type *)tore)) return;
+               if (type_visited(tore.typ)) return;
                break;
        default:
                break;
        }
 
        /* iterate */
-       switch (get_kind(tore)) {
+       switch (get_kind(tore.typ)) {
        case k_type:
                {
-                       ir_type *tp = (ir_type *)tore;
+                       ir_type *tp = tore.typ;
                        mark_type_visited(tp);
                        switch (get_type_tpop_code(tp)) {
                        case tpo_class:
                                {
+                                       size_t i, n;
+
                                        n = get_class_n_supertypes(tp);
                                        for (i = 0; i < n; ++i) {
-                                               type_walk_s2s_2((type_or_ent *)get_class_supertype(tp, i), pre, post, env);
+                                               cont.typ = get_class_supertype(tp, i);
+                                               type_walk_s2s_2(cont, pre, post, env);
                                        }
                                        /* execute pre method */
                                        if (pre)
                                                pre(tore, env);
-                                       tp = skip_tid((ir_type*)tore);
 
                                        n = get_class_n_subtypes(tp);
                                        for (i = 0; i < n; ++i) {
-                                               type_walk_s2s_2((type_or_ent *)get_class_subtype(tp, i), pre, post, env);
+                                               cont.typ = get_class_subtype(tp, i);
+                                               type_walk_s2s_2(cont, pre, post, env);
                                        }
 
                                        /* execute post method */
@@ -331,7 +349,6 @@ static void type_walk_s2s_2(type_or_ent *tore,
                        case tpo_enumeration:
                        case tpo_pointer:
                        case tpo_primitive:
-                       case tpo_id:
                                /* dont care */
                                break;
                        default:
@@ -340,73 +357,72 @@ static void type_walk_s2s_2(type_or_ent *tore,
                        }
                } break; /* end case k_type */
        case k_entity:
-               /* dont care */
+               /* don't care */
                break;
        default:
                printf(" *** Faulty type or entity! \n");
                break;
        }
-       return;
 }
 
 void type_walk_super2sub(type_walk_func *pre,
                          type_walk_func *post,
                          void *env)
 {
-       int i, n_types = get_irp_n_types();
-       ir_type *tp;
+       type_or_ent cont;
+       size_t      i, n_types = get_irp_n_types();
 
+       irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
        inc_master_type_visited();
-       type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env);
+       cont.typ = get_glob_type();
+       type_walk_s2s_2(cont, pre, post, env);
        for (i = 0; i < n_types; ++i) {
-               tp = get_irp_type(i);
-               type_walk_s2s_2((type_or_ent *)tp, pre, post, env);
+               cont.typ = get_irp_type(i);
+               type_walk_s2s_2(cont, pre, post, env);
        }
+       irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
 }
 
 /*****************************************************************************/
 
-static void
-type_walk_super_2(type_or_ent *tore,
-                  type_walk_func *pre,
-                  type_walk_func *post,
-                  void *env) {
-       int i, n;
+static void type_walk_super_2(type_or_ent tore, type_walk_func *pre,
+                              type_walk_func *post, void *env)
+{
+       type_or_ent cont;
 
        /* marked? */
-       switch (get_kind(tore)) {
+       switch (get_kind(tore.ent)) {
        case k_entity:
-               if (entity_visited((ir_entity *)tore)) return;
+               if (entity_visited(tore.ent))
+                       return;
                break;
        case k_type:
-               if (type_id == get_type_tpop((ir_type*)tore)) {
-                       type_walk_super_2((type_or_ent *)skip_tid((ir_type *)tore), pre, post, env);
+               if (type_visited(tore.typ))
                        return;
-               }
-               if (type_visited((ir_type *)tore)) return;
                break;
        default:
                break;
        }
 
        /* iterate */
-       switch (get_kind(tore)) {
+       switch (get_kind(tore.typ)) {
        case k_type:
                {
-                       ir_type *tp = (ir_type *)tore;
+                       ir_type *tp = tore.typ;
                        mark_type_visited(tp);
                        switch (get_type_tpop_code(tp)) {
                        case tpo_class:
                                {
+                                       size_t i, n;
+
                                        /* execute pre method */
                                        if (pre)
                                                pre(tore, env);
-                                       tp = skip_tid((ir_type*)tore);
 
                                        n = get_class_n_supertypes(tp);
                                        for (i = 0; i < n; ++i) {
-                                               type_walk_super_2((type_or_ent *)get_class_supertype(tp, i), pre,
-                                                       post, env);
+                                               cont.typ = get_class_supertype(tp, i);
+                                               type_walk_super_2(cont, pre, post, env);
                                        }
 
                                        /* execute post method */
@@ -421,8 +437,7 @@ type_walk_super_2(type_or_ent *tore,
                        case tpo_enumeration:
                        case tpo_pointer:
                        case tpo_primitive:
-                       case tpo_id:
-                               /* dont care */
+                               /* don't care */
                                break;
                        default:
                                printf(" *** Faulty type! \n");
@@ -430,44 +445,41 @@ type_walk_super_2(type_or_ent *tore,
                        }
                } break; /* end case k_type */
        case k_entity:
-               /* dont care */
+               /* don't care */
                break;
        default:
                printf(" *** Faulty type or entity! \n");
                break;
        }
-       return;
 }
 
-void type_walk_super(type_walk_func *pre,
-                     type_walk_func *post,
-                     void *env) {
-       int i, n_types = get_irp_n_types();
-       ir_type *tp;
+void type_walk_super(type_walk_func *pre, type_walk_func *post, void *env)
+{
+       size_t      i, n_types = get_irp_n_types();
+       type_or_ent cont;
 
+       irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
        inc_master_type_visited();
-       type_walk_super_2((type_or_ent *)get_glob_type(), pre, post, env);
+       cont.typ = get_glob_type();
+       type_walk_super_2(cont, pre, post, env);
        for (i = 0; i < n_types; ++i) {
-               tp = get_irp_type(i);
-               type_walk_super_2((type_or_ent *)tp, pre, post, env);
+               cont.typ = get_irp_type(i);
+               type_walk_super_2(cont, pre, post, env);
        }
+       irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
 }
 
 /*****************************************************************************/
 
 
-static void
-class_walk_s2s_2(ir_type *tp,
-                 class_walk_func *pre,
-                 class_walk_func *post,
-                 void *env)
+static void class_walk_s2s_2(ir_type *tp, class_walk_func *pre,
+                             class_walk_func *post, void *env)
 {
-       int i, n;
+       size_t i, n;
 
        /* marked? */
        if (type_visited(tp)) return;
 
-       assert(is_Class_type(tp));
        /* Assure all supertypes are visited before */
        n = get_class_n_supertypes(tp);
        for (i = 0; i < n; ++i) {
@@ -481,7 +493,6 @@ class_walk_s2s_2(ir_type *tp,
        if (pre)
                pre(tp, env);
 
-       tp = skip_tid(tp);
        n = get_class_n_subtypes(tp);
        for (i = 0; i < n; ++i) {
                class_walk_s2s_2(get_class_subtype(tp, i), pre, post, env);
@@ -489,37 +500,36 @@ class_walk_s2s_2(ir_type *tp,
        /* execute post method */
        if (post)
                post(tp, env);
-
-       return;
 }
 
 void class_walk_super2sub(class_walk_func *pre,
                           class_walk_func *post,
                           void *env)
 {
-       int i, n_types = get_irp_n_types();
+       size_t i, n_types = get_irp_n_types();
        ir_type *tp;
 
+       irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
        inc_master_type_visited();
        for (i = 0; i < n_types; i++) {
                tp = get_irp_type(i);
                if (is_Class_type(tp) &&
                    (get_class_n_supertypes(tp) == 0) &&
-                   type_not_visited(tp)) {
-                       assert(! is_frame_type(tp));
-                       assert(tp != get_glob_type());
+                   type_not_visited(tp) &&
+                   (! is_frame_type(tp)) &&
+                   (tp != get_glob_type())) {
                        class_walk_s2s_2(tp, pre, post, env);
                }
        }
+       irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
 }
 
 
-/* Walks over all entities in the type */
 void walk_types_entities(ir_type *tp,
                          entity_walk_func *doit,
                          void *env)
 {
-       int i, n;
+       size_t i, n;
 
        switch (get_type_tpop_code(tp)) {
        case tpo_class:
@@ -544,7 +554,6 @@ void walk_types_entities(ir_type *tp,
        case tpo_enumeration:
        case tpo_pointer:
        case tpo_primitive:
-       case tpo_id:
        default:
                break;
        }