irtypeinfo.c 4.86 KB
Newer Older
Matthias Braun's avatar
Matthias Braun committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3
 *
Matthias Braun's avatar
Matthias Braun committed
4
 * This file is part of libFirm.
5
 *
Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
 * 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.
10
 *
Matthias Braun's avatar
Matthias Braun committed
11
12
13
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
14
 *
Matthias Braun's avatar
Matthias Braun committed
15
16
17
18
19
20
21
22
23
24
25
26
27
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief     Data structure to hold type information for nodes.
 * @author    Goetz Lindenmaier
 * @date      28.8.2003
 * @version   $Id$
 * @summary
 *  Data structure to hold type information for nodes.
28
 *
Matthias Braun's avatar
Matthias Braun committed
29
30
31
 *  This module defines a field "type" of type "type *" for each ir node.
 *  It defines a flag for irgraphs to mark whether the type info of the
 *  graph is valid.  Further it defines an auxiliary type "initial_type".
32
 *
Matthias Braun's avatar
Matthias Braun committed
33
34
35
36
 *  The module defines a map that contains pairs (irnode, type).  If an irnode
 *  is not in the map it is assumed to be initialized, i.e., the initialization
 *  requires no compute time.  As firm nodes can not be freed and reallocated
 *  pointers for nodes are unique (until a call of dead_node_elimination).
37
 */
Michael Beck's avatar
Michael Beck committed
38
39
#include "config.h"

40
41
42
43
44
#include "irtypeinfo.h"

#include <stddef.h>

#include "irgraph_t.h"   /* for setting the state flag. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
45
#include "irprog_t.h"
46
#include "irnode_t.h"
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "pmap.h"

/* ------------ The map. ---------------------------------------------- */


static pmap *type_node_map = NULL;


/* ------------ Auxiliary type. --------------------------------------- */

/*  This auxiliary type expresses that a field is uninitialized.  The
 *  variable is set by init_irtypeinfo.  The type is freed by
 *  free_irtypeinfo.
 */
61
ir_type *initial_type = NULL;
62
63
64
65
66
67
68
69
70

/* ------------ Initializing this module. ----------------------------- */

/*  Initializes the type information module.
 *  Generates a type "initial_type" and sets the type of all nodes to this type.
 *  Calling set/get_irn_type is invalid before calling init. Requires memory
 *  in the order of MIN(<calls to set_irn_type>, #irnodes).
 */
void init_irtypeinfo(void) {
Michael Beck's avatar
Michael Beck committed
71
	int i;
72

Michael Beck's avatar
Michael Beck committed
73
74
	if (initial_type == NULL)
		initial_type = new_type_class(new_id_from_str("initial_type"));
75

Michael Beck's avatar
Michael Beck committed
76
77
78
79
	/* We need a new, empty map. */
	if (type_node_map != NULL)
		pmap_destroy(type_node_map);
	type_node_map = pmap_create();
80

Michael Beck's avatar
Michael Beck committed
81
82
	for (i = get_irp_n_irgs() - 1; i >= 0; --i)
		set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
83
84
85
}

void free_irtypeinfo(void) {
Michael Beck's avatar
Michael Beck committed
86
87
88
89
90
91
92
93
94
95
96
97
98
99
	int i;

	if (initial_type != NULL) {
		free_type(initial_type);
		initial_type = NULL;
	}

	if (type_node_map != NULL) {
		pmap_destroy(type_node_map);
		type_node_map = NULL;
	}

	for (i = get_irp_n_irgs() - 1; i >= 0; --i)
		set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
100
101
102
103
104
}


/* ------------ Irgraph state handling. ------------------------------- */

Götz Lindenmaier's avatar
Götz Lindenmaier committed
105
void set_irg_typeinfo_state(ir_graph *irg, ir_typeinfo_state s) {
Michael Beck's avatar
Michael Beck committed
106
107
108
109
110
111
	assert(is_ir_graph(irg));
	irg->typeinfo_state = s;
	if ((irg->typeinfo_state == ir_typeinfo_consistent) &&
	    (irp->typeinfo_state == ir_typeinfo_consistent) &&
	    (s                   != ir_typeinfo_consistent)   )
		irp->typeinfo_state = ir_typeinfo_inconsistent;
112
113
}

Michael Beck's avatar
Michael Beck committed
114
ir_typeinfo_state get_irg_typeinfo_state(const ir_graph *irg) {
Michael Beck's avatar
Michael Beck committed
115
116
	assert(is_ir_graph(irg));
	return irg->typeinfo_state;
117
118
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
119
120
121
122
123
124
125
126

/* Returns accumulated type information state information.
 *
 * Returns ir_typeinfo_consistent if the type information of all irgs is
 * consistent.  Returns ir_typeinfo_inconsistent if at least one irg has inconsistent
 * or no type information.  Returns ir_typeinfo_none if no irg contains type information.
 */
ir_typeinfo_state get_irp_typeinfo_state(void) {
Michael Beck's avatar
Michael Beck committed
127
	return irp->typeinfo_state;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
128
129
}
void set_irp_typeinfo_state(ir_typeinfo_state s) {
Michael Beck's avatar
Michael Beck committed
130
	irp->typeinfo_state = s;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
131
132
133
}
/* If typeinfo is consistent, sets it to inconsistent. */
void set_irp_typeinfo_inconsistent(void) {
Michael Beck's avatar
Michael Beck committed
134
135
	if (irp->typeinfo_state == ir_typeinfo_consistent)
		irp->typeinfo_state = ir_typeinfo_inconsistent;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
136
137
138
}


139
140
141
/* ------------ Irnode type information. ------------------------------ */

/* These routines only work properly if the ir_graph is in state
Götz Lindenmaier's avatar
Götz Lindenmaier committed
142
 * ir_typeinfo_consistent or ir_typeinfo_inconsistent.  They
143
144
 * assume current_ir_graph set properly.
 */
Michael Beck's avatar
Michael Beck committed
145
ir_type *get_irn_typeinfo_type(const ir_node *n) {
Michael Beck's avatar
Michael Beck committed
146
147
148
149
	ir_type *res = initial_type;
	pmap_entry *entry;

	assert(get_irg_typeinfo_state(get_irn_irg(n)) != ir_typeinfo_none);
150

Michael Beck's avatar
Michael Beck committed
151
152
153
	entry = pmap_find(type_node_map, n);
	if (entry != NULL)
		res = entry->value;
154

Michael Beck's avatar
Michael Beck committed
155
	return res;
156
157
}

158
void set_irn_typeinfo_type(ir_node *n, ir_type *tp) {
Michael Beck's avatar
Michael Beck committed
159
	assert(get_irg_typeinfo_state(current_ir_graph) != ir_typeinfo_none);
160

Michael Beck's avatar
Michael Beck committed
161
	pmap_insert(type_node_map, (void *)n, (void *)tp);
162
}