2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Data structure to hold type information for nodes.
23 * @author Goetz Lindenmaier
27 * Data structure to hold type information for nodes.
29 * This module defines a field "type" of type "type *" for each ir node.
30 * It defines a flag for irgraphs to mark whether the type info of the
31 * graph is valid. Further it defines an auxiliary type "initial_type".
33 * The module defines a map that contains pairs (irnode, type). If an irnode
34 * is not in the map it is assumed to be initialized, i.e., the initialization
35 * requires no compute time. As firm nodes can not be freed and reallocated
36 * pointers for nodes are unique (until a call of dead_node_elimination).
42 #include "irtypeinfo.h"
46 #include "irgraph_t.h" /* for setting the state flag. */
51 /* ------------ The map. ---------------------------------------------- */
54 static pmap *type_node_map = NULL;
57 /* ------------ Auxiliary type. --------------------------------------- */
59 /* This auxiliary type expresses that a field is uninitialized. The
60 * variable is set by init_irtypeinfo. The type is freed by
63 ir_type *initial_type = NULL;
65 /* ------------ Initializing this module. ----------------------------- */
67 /* Initializes the type information module.
68 * Generates a type "initial_type" and sets the type of all nodes to this type.
69 * Calling set/get_irn_type is invalid before calling init. Requires memory
70 * in the order of MIN(<calls to set_irn_type>, #irnodes).
72 void init_irtypeinfo(void) {
76 initial_type = new_type_class(new_id_from_str("initial_type"));
78 /* We need a new, empty map. */
79 if (type_node_map) pmap_destroy(type_node_map);
80 type_node_map = pmap_create();
83 for (i = 0; i < n; ++i)
84 set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
87 void free_irtypeinfo(void) {
91 free_type(initial_type);
94 //else assert(0 && "call init_type_info before freeing");
97 pmap_destroy(type_node_map);
100 //else assert(0 && "call init_type_info before freeing");
102 n = get_irp_n_irgs();
103 for (i = 0; i < n; ++i)
104 set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
108 /* ------------ Irgraph state handling. ------------------------------- */
110 void set_irg_typeinfo_state(ir_graph *irg, ir_typeinfo_state s) {
111 assert(is_ir_graph(irg));
112 irg->typeinfo_state = s;
113 if ((irg->typeinfo_state == ir_typeinfo_consistent) &&
114 (irp->typeinfo_state == ir_typeinfo_consistent) &&
115 (s != ir_typeinfo_consistent) )
116 irp->typeinfo_state = ir_typeinfo_inconsistent;
119 ir_typeinfo_state get_irg_typeinfo_state(ir_graph *irg) {
120 assert(is_ir_graph(irg));
121 return irg->typeinfo_state;
125 /* Returns accumulated type information state information.
127 * Returns ir_typeinfo_consistent if the type information of all irgs is
128 * consistent. Returns ir_typeinfo_inconsistent if at least one irg has inconsistent
129 * or no type information. Returns ir_typeinfo_none if no irg contains type information.
131 ir_typeinfo_state get_irp_typeinfo_state(void) {
132 return irp->typeinfo_state;
134 void set_irp_typeinfo_state(ir_typeinfo_state s) {
135 irp->typeinfo_state = s;
137 /* If typeinfo is consistent, sets it to inconsistent. */
138 void set_irp_typeinfo_inconsistent(void) {
139 if (irp->typeinfo_state == ir_typeinfo_consistent)
140 irp->typeinfo_state = ir_typeinfo_inconsistent;
144 /* ------------ Irnode type information. ------------------------------ */
146 /* These routines only work properly if the ir_graph is in state
147 * ir_typeinfo_consistent or ir_typeinfo_inconsistent. They
148 * assume current_ir_graph set properly.
150 ir_type *get_irn_typeinfo_type(ir_node *n) {
151 ir_type *res = initial_type;
153 assert(get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_consistent ||
154 get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_inconsistent );
156 entry = pmap_find(type_node_map, n);
163 void set_irn_typeinfo_type(ir_node *n, ir_type *tp) {
164 assert(get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_consistent ||
165 get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_inconsistent );
167 pmap_insert(type_node_map, (void *)n, (void *)tp);