1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19 
20 /**
21  * @file
22  * @brief     Data structure to hold type information for nodes.
23  * @author    Goetz Lindenmaier
24  * @date      28.8.2003
25  * @brief
26  *  Data structure to hold type information for nodes.
27  *
28  *  This module defines a field "type" of type "type *" for each ir node.
29  *  It defines a flag for irgraphs to mark whether the type info of the
30  *  graph is valid.  Further it defines an auxiliary type "initial_type".
31  *
32  *  The module defines a map that contains pairs (irnode, type).  If an irnode
33  *  is not in the map it is assumed to be initialized, i.e., the initialization
34  *  requires no compute time.  As firm nodes can not be freed and reallocated
35  *  pointers for nodes are unique (until a call of dead_node_elimination).
36  */
37 #include "config.h"
38 
39 #include "irtypeinfo.h"
40 
41 #include <stddef.h>
42 
43 #include "irgraph_t.h"
44 #include "irprog_t.h"
45 #include "irnode_t.h"
46 #include "pmap.h"
47 
48 static pmap *type_node_map = NULL;
49 
50 
51 ir_type *initial_type = NULL;
52 
init_irtypeinfo(void)53 void init_irtypeinfo(void)
54 {
55 	size_t i, n;
56 
57 	if (initial_type == NULL)
58 		initial_type = new_type_class(new_id_from_str("initial_type"));
59 
60 	/* We need a new, empty map. */
61 	if (type_node_map != NULL)
62 		pmap_destroy(type_node_map);
63 	type_node_map = pmap_create();
64 
65 	for (i = 0, n = get_irp_n_irgs(); i < n; ++i)
66 		set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
67 }
68 
free_irtypeinfo(void)69 void free_irtypeinfo(void)
70 {
71 	size_t i, n;
72 
73 	if (initial_type != NULL) {
74 		free_type(initial_type);
75 		initial_type = NULL;
76 	}
77 
78 	if (type_node_map != NULL) {
79 		pmap_destroy(type_node_map);
80 		type_node_map = NULL;
81 	}
82 
83 	for (i = 0, n = get_irp_n_irgs(); i < n; ++i)
84 		set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
85 }
86 
87 
set_irg_typeinfo_state(ir_graph * irg,ir_typeinfo_state s)88 void set_irg_typeinfo_state(ir_graph *irg, ir_typeinfo_state s)
89 {
90 	assert(is_ir_graph(irg));
91 	irg->typeinfo_state = s;
92 	if ((irg->typeinfo_state == ir_typeinfo_consistent) &&
93 	    (irp->typeinfo_state == ir_typeinfo_consistent) &&
94 	    (s                   != ir_typeinfo_consistent)   )
95 		irp->typeinfo_state = ir_typeinfo_inconsistent;
96 }
97 
get_irg_typeinfo_state(const ir_graph * irg)98 ir_typeinfo_state get_irg_typeinfo_state(const ir_graph *irg)
99 {
100 	assert(is_ir_graph(irg));
101 	return irg->typeinfo_state;
102 }
103 
104 
get_irp_typeinfo_state(void)105 ir_typeinfo_state get_irp_typeinfo_state(void)
106 {
107 	return irp->typeinfo_state;
108 }
set_irp_typeinfo_state(ir_typeinfo_state s)109 void set_irp_typeinfo_state(ir_typeinfo_state s)
110 {
111 	irp->typeinfo_state = s;
112 }
set_irp_typeinfo_inconsistent(void)113 void set_irp_typeinfo_inconsistent(void)
114 {
115 	if (irp->typeinfo_state == ir_typeinfo_consistent)
116 		irp->typeinfo_state = ir_typeinfo_inconsistent;
117 }
118 
119 
get_irn_typeinfo_type(const ir_node * n)120 ir_type *get_irn_typeinfo_type(const ir_node *n)
121 {
122 	ir_type *res;
123 	assert(get_irg_typeinfo_state(get_irn_irg(n)) != ir_typeinfo_none);
124 
125 	res = pmap_get(ir_type, type_node_map, n);
126 	if (res == NULL) {
127 		res = initial_type;
128 	}
129 
130 	return res;
131 }
132 
set_irn_typeinfo_type(ir_node * n,ir_type * tp)133 void set_irn_typeinfo_type(ir_node *n, ir_type *tp)
134 {
135 	assert(get_irg_typeinfo_state(get_irn_irg(n)) != ir_typeinfo_none);
136 
137 	pmap_insert(type_node_map, (void *)n, (void *)tp);
138 }
139