Improved marking of dead blocks
[libfirm] / ir / ana / irtypeinfo.c
1 /**
2  *
3  * @file irtypeinfo.c
4  *
5  * Project:     libFIRM
6  * File name:   ir/ana/irtypeinfo.c
7  * Purpose:     Data structure to hold type information for nodes.
8  * Author:      Goetz Lindenmaier
9  * Modified by:
10  * Created:     28.8.2003
11  * CVS-ID:      $Id$
12  * Copyright:   (c) 2003 Universität Karlsruhe
13  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
14  *
15  * Data structure to hold type information for nodes.
16  *
17  * This module defines a field "type" of type "type *" for each ir node.
18  * It defines a flag for irgraphs to mark whether the type info of the
19  * graph is valid.  Further it defines an auxiliary type "initial_type".
20  *
21  * The module defines a map that contains pairs (irnode, type).  If an irnode
22  * is not in the map it is assumed to be initialized, i.e., the initialization
23  * requires no compute time.  As firm nodes can not be freed and reallocated
24  * pointers for nodes are unique (until a call of dead_node_elimination).
25  *
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "irtypeinfo.h"
33
34 #include <stddef.h>
35
36 #include "irgraph_t.h"   /* for setting the state flag. */
37 #include "irprog_t.h"
38 #include "irnode_t.h"
39 #include "pmap.h"
40
41 /* ------------ The map. ---------------------------------------------- */
42
43
44 static pmap *type_node_map = NULL;
45
46
47 /* ------------ Auxiliary type. --------------------------------------- */
48
49 /*  This auxiliary type expresses that a field is uninitialized.  The
50  *  variable is set by init_irtypeinfo.  The type is freed by
51  *  free_irtypeinfo.
52  */
53 ir_type *initial_type = NULL;
54
55 /* ------------ Initializing this module. ----------------------------- */
56
57 /*  Initializes the type information module.
58  *  Generates a type "initial_type" and sets the type of all nodes to this type.
59  *  Calling set/get_irn_type is invalid before calling init. Requires memory
60  *  in the order of MIN(<calls to set_irn_type>, #irnodes).
61  */
62 void init_irtypeinfo(void) {
63   int i, n;
64
65   if (!initial_type)
66     initial_type = new_type_class(new_id_from_str("initial_type"));
67
68   /* We need a new, empty map. */
69   if (type_node_map) pmap_destroy(type_node_map);
70   type_node_map = pmap_create();
71
72   n = get_irp_n_irgs();
73   for (i = 0; i < n; ++i)
74     set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
75 }
76
77 void free_irtypeinfo(void) {
78   int i, n;
79
80   if (initial_type) {
81     free_type(initial_type);
82     initial_type = NULL;
83   }
84   //else assert(0 && "call init_type_info before freeing");
85
86   if (type_node_map) {
87     pmap_destroy(type_node_map);
88     type_node_map = NULL;
89   }
90   //else assert(0 && "call init_type_info before freeing");
91
92   n = get_irp_n_irgs();
93   for (i = 0; i < n; ++i)
94     set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
95 }
96
97
98 /* ------------ Irgraph state handling. ------------------------------- */
99
100 void set_irg_typeinfo_state(ir_graph *irg, ir_typeinfo_state s) {
101   assert(is_ir_graph(irg));
102   irg->typeinfo_state = s;
103   if ((irg->typeinfo_state == ir_typeinfo_consistent) &&
104       (irp->typeinfo_state == ir_typeinfo_consistent) &&
105       (s                   != ir_typeinfo_consistent)   )
106     irp->typeinfo_state = ir_typeinfo_inconsistent;
107 }
108
109 ir_typeinfo_state get_irg_typeinfo_state(ir_graph *irg) {
110   assert(is_ir_graph(irg));
111   return irg->typeinfo_state;
112 }
113
114
115 /* Returns accumulated type information state information.
116  *
117  * Returns ir_typeinfo_consistent if the type information of all irgs is
118  * consistent.  Returns ir_typeinfo_inconsistent if at least one irg has inconsistent
119  * or no type information.  Returns ir_typeinfo_none if no irg contains type information.
120  */
121 ir_typeinfo_state get_irp_typeinfo_state(void) {
122   return irp->typeinfo_state;
123 }
124 void set_irp_typeinfo_state(ir_typeinfo_state s) {
125   irp->typeinfo_state = s;
126 }
127 /* If typeinfo is consistent, sets it to inconsistent. */
128 void set_irp_typeinfo_inconsistent(void) {
129   if (irp->typeinfo_state == ir_typeinfo_consistent)
130     irp->typeinfo_state = ir_typeinfo_inconsistent;
131 }
132
133
134 /* ------------ Irnode type information. ------------------------------ */
135
136 /* These routines only work properly if the ir_graph is in state
137  * ir_typeinfo_consistent or ir_typeinfo_inconsistent.  They
138  * assume current_ir_graph set properly.
139  */
140 ir_type *get_irn_typeinfo_type(ir_node *n) {
141   ir_type *res = initial_type;
142   pmap_entry *entry;
143   assert(get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_consistent  ||
144          get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_inconsistent  );
145
146   entry = pmap_find(type_node_map, n);
147   if (entry)
148     res = entry->value;
149
150   return res;
151 }
152
153 void set_irn_typeinfo_type(ir_node *n, ir_type *tp) {
154   assert(get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_consistent  ||
155          get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_inconsistent  );
156
157   pmap_insert(type_node_map, (void *)n, (void *)tp);
158 }