irtypeinfo.c 4.67 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 *
 * @file irtypeinfo.c
 *
 * Project:     libFIRM
 * File name:   ir/ana/irtypeinfo.c
 * Purpose:     Data structure to hold type information for nodes.
 * Author:      Goetz Lindenmaier
 * Modified by:
 * Created:     28.8.2003
 * CVS-ID:      $Id$
 * Copyright:   (c) 2003 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 *
 * Data structure to hold type information for nodes.
 *
 * 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".
 *
 * 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).
 *
 */

Michael Beck's avatar
Michael Beck committed
28
29
30
31
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

32
33
34
35
36
#include "irtypeinfo.h"

#include <stddef.h>

#include "irgraph_t.h"   /* for setting the state flag. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
37
#include "irprog_t.h"
38
#include "irnode_t.h"
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#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.
 */
type *initial_type = NULL;

/* ------------ 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) {
  int i;

  if (!initial_type)
    initial_type = new_type_class(new_id_from_str("initial_type"));

  /* We need a new, empty map. */
  if (type_node_map) pmap_destroy(type_node_map);
  type_node_map = pmap_create();

  for (i = 0; i < get_irp_n_irgs(); ++i)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
73
    set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
}

void free_irtypeinfo(void) {
  int i;

  if (initial_type) {
    free_type(initial_type);
    initial_type = NULL;
  } else
    assert(0 && "call init_type_info before freeing");

  if (type_node_map) {
    pmap_destroy(type_node_map);
    type_node_map = NULL;
  } else
    assert(0 && "call init_type_info before freeing");

  for (i = 0; i < get_irp_n_irgs(); ++i)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
92
    set_irg_typeinfo_state(get_irp_irg(i), ir_typeinfo_none);
93
94
95
96
97
}


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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
98
void set_irg_typeinfo_state(ir_graph *irg, ir_typeinfo_state s) {
99
100
  assert(is_ir_graph(irg));
  irg->typeinfo_state = s;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
101
102
103
104
  if ((irg->typeinfo_state == ir_typeinfo_consistent) &&
      (irp->typeinfo_state == ir_typeinfo_consistent) &&
      (s                   != ir_typeinfo_consistent)   )
    irp->typeinfo_state = ir_typeinfo_inconsistent;
105
106
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
107
ir_typeinfo_state get_irg_typeinfo_state(ir_graph *irg) {
108
109
110
111
  assert(is_ir_graph(irg));
  return irg->typeinfo_state;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

/* 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) {
  return irp->typeinfo_state;
}
void set_irp_typeinfo_state(ir_typeinfo_state s) {
  irp->typeinfo_state = s;
}
/* If typeinfo is consistent, sets it to inconsistent. */
void set_irp_typeinfo_inconsistent(void) {
  if (irp->typeinfo_state == ir_typeinfo_consistent)
    irp->typeinfo_state = ir_typeinfo_inconsistent;
}


132
133
134
/* ------------ Irnode type information. ------------------------------ */

/* These routines only work properly if the ir_graph is in state
Götz Lindenmaier's avatar
Götz Lindenmaier committed
135
 * ir_typeinfo_consistent or ir_typeinfo_inconsistent.  They
136
137
 * assume current_ir_graph set properly.
 */
138
type *get_irn_typeinfo_type(ir_node *n) {
139
  type *res = initial_type;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
140
141
  assert(get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_consistent  ||
	 get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_inconsistent  );
142
143
144
145
146
147
148

  if (pmap_contains(type_node_map, (void *)n))
    res = (type *) pmap_get(type_node_map, (void *)n);

  return res;
}

149
void set_irn_typeinfo_type(ir_node *n, type *tp) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
150
151
  assert(get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_consistent  ||
  	 get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_inconsistent  );
152
153
154

  pmap_insert(type_node_map, (void *)n, (void *)tp);
}