6 * File name: ir/ana/irtypeinfo.c
7 * Purpose: Data structure to hold type information for nodes.
8 * Author: Goetz Lindenmaier
12 * Copyright: (c) 2003 Universität Karlsruhe
13 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
15 * Data structure to hold type information for nodes.
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".
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).
32 #include "irtypeinfo.h"
36 #include "irgraph_t.h" /* for setting the state flag. */
40 /* ------------ The map. ---------------------------------------------- */
43 static pmap *type_node_map = NULL;
46 /* ------------ Auxiliary type. --------------------------------------- */
48 /* This auxiliary type expresses that a field is uninitialized. The
49 * variable is set by init_irtypeinfo. The type is freed by
52 type *initial_type = NULL;
55 /* ------------ Initializing this module. ----------------------------- */
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).
62 void init_irtypeinfo(void) {
66 initial_type = new_type_class(new_id_from_str("initial_type"));
68 /* We need a new, empty map. */
69 if (type_node_map) pmap_destroy(type_node_map);
70 type_node_map = pmap_create();
72 for (i = 0; i < get_irp_n_irgs(); ++i)
73 set_irg_typeinfo_state(get_irp_irg(i), irg_typeinfo_none);
76 void free_irtypeinfo(void) {
80 free_type(initial_type);
83 assert(0 && "call init_type_info before freeing");
86 pmap_destroy(type_node_map);
89 assert(0 && "call init_type_info before freeing");
91 for (i = 0; i < get_irp_n_irgs(); ++i)
92 set_irg_typeinfo_state(get_irp_irg(i), irg_typeinfo_none);
96 /* ------------ Irgraph state handling. ------------------------------- */
98 void set_irg_typeinfo_state(ir_graph *irg, irg_typeinfo_state s) {
99 assert(is_ir_graph(irg));
100 irg->typeinfo_state = s;
103 irg_typeinfo_state get_irg_typeinfo_state(ir_graph *irg) {
104 assert(is_ir_graph(irg));
105 return irg->typeinfo_state;
108 /* ------------ Irnode type information. ------------------------------ */
110 /* These routines only work properly if the ir_graph is in state
111 * irg_typeinfo_consistent or irg_typeinfo_inconsistent. They
112 * assume current_ir_graph set properly.
114 type *get_irn_typeinfo_type(ir_node *n) {
115 type *res = initial_type;
116 assert(get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
117 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent );
119 if (pmap_contains(type_node_map, (void *)n))
120 res = (type *) pmap_get(type_node_map, (void *)n);
125 void set_irn_typeinfo_type(ir_node *n, type *tp) {
126 assert(get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
127 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent );
129 pmap_insert(type_node_map, (void *)n, (void *)tp);
132 type *get_irn_type(ir_node *n) {
134 switch(get_irn_opcode(n)) {
135 case iro_Const: tp = get_Const_type(n); break;
136 case iro_SymConst: tp = get_SymConst_value_type(n); break;
137 case iro_Cast: tp = get_Cast_type(n); break;
139 ir_node *pred = get_Proj_pred(n);
140 switch (get_irn_opcode(pred)) {
143 /* Deal with Start / Call here: we need to know the Proj Nr. */
144 assert(get_irn_mode(pred) == mode_T);
145 pred_pred = get_Proj_pred(pred);
146 if (get_irn_op(pred_pred) == op_Start) {
147 type *mtp = get_entity_type(get_irg_entity(get_irn_irg(pred_pred)));
148 tp = get_method_param_type(mtp, get_Proj_proj(n));
149 } else if (get_irn_op(pred_pred) == op_Call) {
150 type *mtp = get_Call_type(pred_pred);
151 tp = get_method_res_type(mtp, get_Proj_proj(n));
154 case iro_Start: break;
155 case iro_Call: break;
157 ir_node *a = get_Load_ptr(pred);
158 if (get_irn_op(a) == op_Sel)
159 tp = get_entity_type(get_Sel_entity(a));
164 } break; /* iro_Proj */