replaced variable args macros by functions to make it c89 compatible
[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 #include "irtypeinfo.h"
29
30 #include <stddef.h>
31
32 #include "irgraph_t.h"   /* for setting the state flag. */
33 #include "irprog.h"
34 #include "pmap.h"
35
36 /* ------------ The map. ---------------------------------------------- */
37
38
39 static pmap *type_node_map = NULL;
40
41
42 /* ------------ Auxiliary type. --------------------------------------- */
43
44 /*  This auxiliary type expresses that a field is uninitialized.  The
45  *  variable is set by init_irtypeinfo.  The type is freed by
46  *  free_irtypeinfo.
47  */
48 type *initial_type = NULL;
49
50
51 /* ------------ Initializing this module. ----------------------------- */
52
53 /*  Initializes the type information module.
54  *  Generates a type "initial_type" and sets the type of all nodes to this type.
55  *  Calling set/get_irn_type is invalid before calling init. Requires memory
56  *  in the order of MIN(<calls to set_irn_type>, #irnodes).
57  */
58 void init_irtypeinfo(void) {
59   int i;
60
61   if (!initial_type)
62     initial_type = new_type_class(new_id_from_str("initial_type"));
63
64   /* We need a new, empty map. */
65   if (type_node_map) pmap_destroy(type_node_map);
66   type_node_map = pmap_create();
67
68   for (i = 0; i < get_irp_n_irgs(); ++i)
69     set_irg_typeinfo_state(get_irp_irg(i), irg_typeinfo_none);
70
71 }
72
73 void free_irtypeinfo(void) {
74   int i;
75
76   if (initial_type) {
77     free_type(initial_type);
78     initial_type = NULL;
79   } else
80     assert(0 && "call init_type_info before freeing");
81
82
83   if (type_node_map) {
84     pmap_destroy(type_node_map);
85     type_node_map = NULL;
86   } else
87     assert(0 && "call init_type_info before freeing");
88
89   for (i = 0; i < get_irp_n_irgs(); ++i)
90     set_irg_typeinfo_state(get_irp_irg(i), irg_typeinfo_none);
91 }
92
93
94 /* ------------ Irgraph state handling. ------------------------------- */
95
96 void set_irg_typeinfo_state(ir_graph *irg, irg_typeinfo_state s) {
97   assert(is_ir_graph(irg));
98   irg->typeinfo_state = s;
99 }
100
101 irg_typeinfo_state get_irg_typeinfo_state(ir_graph *irg) {
102   assert(is_ir_graph(irg));
103   return irg->typeinfo_state;
104 }
105
106 /* ------------ Irnode type information. ------------------------------ */
107
108 /* These routines only work properly if the ir_graph is in state
109  * irg_typeinfo_consistent or irg_typeinfo_inconsistent.  They
110  * assume current_ir_graph set properly.
111  */
112 type *get_irn_type(ir_node *n) {
113   type *res = initial_type;
114   assert(get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent  ||
115          get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent  );
116
117   if (pmap_contains(type_node_map, (void *)n))
118     res = (type *) pmap_get(type_node_map, (void *)n);
119
120   return res;
121 }
122
123 void set_irn_type(ir_node *n, type *tp) {
124   assert(get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent  ||
125          get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent  );
126
127   pmap_insert(type_node_map, (void *)n, (void *)tp);
128 }