68f671ec12030461d328a4dfbecd6f46cbdf3411
[libfirm] / ir / be / belive_t.h
1 /**
2  * Internal headers for liveness analysis.
3  * @author Sebastian Hack
4  * @date 6.12.2004
5  */
6
7 #ifndef _BELIVE_T_H
8 #define _BELIVE_T_H
9
10 #include "config.h"
11
12 #include "irgraph_t.h"
13 #include "iredges_t.h"
14
15 #include "belive.h"
16 #include "pset.h"
17 #include "set.h"
18 #include "list.h"
19 #include "hashptr.h"
20
21 typedef enum _live_state_t {
22     live_state_in = 1,
23     live_state_end = 2,
24     live_state_out = 4,
25     live_state_block = 8,
26 } live_state_t;
27
28 typedef struct _irn_live_t {
29     const ir_node *block;
30     const ir_node *irn;
31     unsigned state;
32     struct _irn_live_t *next;
33 } irn_live_t;
34
35 typedef struct _irg_live_info_t {
36     set *live;
37 } irg_live_info_t;
38
39 extern size_t live_irg_data_offset;
40
41 #define get_irg_live_info(irg) (get_irg_data(irg, irg_live_info_t, live_irg_data_offset))
42
43 #define live_is_in(live) (((live)->state & live_state_in) != 0)
44 #define live_is_end(live) (((live)->state & live_state_end) != 0)
45 #define live_is_out(live) (((live)->state & live_state_out) != 0)
46
47 static INLINE irn_live_t *_get_or_set_live(const ir_node *block,
48     const ir_node *irn, int state)
49 {
50   irg_live_info_t *live_info = get_irg_live_info(get_irn_irg(block));
51   irn_live_t *live, templ;
52   unsigned hash = HASH_PTR(block) + 37 * HASH_PTR(irn);
53
54   templ.block = block;
55   templ.irn = irn;
56   templ.state = -1;
57   templ.next = NULL;
58
59   live = set_insert(live_info->live, &templ, sizeof(templ), hash);
60   if(live->state == -1) {
61
62     if(!is_Block(irn)) {
63       irn_live_t *bl_live = _get_or_set_live(block, block, live_state_block);
64       live->next = bl_live->next;
65       bl_live->next = live;
66     }
67
68     live->state = state;
69   }
70
71   live->state |= state;
72
73   return live;
74 }
75
76 static INLINE int _is_live_in(const ir_node *block, const ir_node *irn)
77 {
78     return (_get_or_set_live(block, irn, 0)->state & live_state_in) != 0;
79 }
80
81 static INLINE int _is_live_out(const ir_node *block, const ir_node *irn)
82 {
83     return (_get_or_set_live(block, irn, 0)->state & live_state_out) != 0;
84 }
85
86 static INLINE int _is_live_end(const ir_node *block, const ir_node *irn)
87 {
88     return (_get_or_set_live(block, irn, 0)->state & live_state_end) != 0;
89 }
90
91 #define live_foreach(block, live_info) \
92         for(live_info = _get_or_set_live(block, block, 0)->next; live_info; live_info = live_info->next)
93
94 static INLINE void _put_live(const ir_node *block, int state, pset *s)
95 {
96     irn_live_t *live;
97
98     live_foreach(block, live) {
99         if(live->state & state)
100             pset_insert_ptr(s, live->irn);
101     }
102 }
103
104 static INLINE pset *_put_live_in(const ir_node *block, pset *s)
105 {
106     _put_live(block, live_state_in, s);
107     return s;
108 }
109
110 static INLINE pset *_put_live_out(const ir_node *block, pset *s)
111 {
112     _put_live(block, live_state_out, s);
113     return s;
114 }
115
116 static INLINE pset *_put_live_end(const ir_node *block, pset *s)
117 {
118     _put_live(block, live_state_end, s);
119     return s;
120 }
121
122 static INLINE int _is_phi_arg(const ir_node *irn)
123 {
124   const ir_edge_t *edge;
125
126   assert(edges_activated(get_irn_irg(irn)) && "Please compute the out edges");
127   foreach_out_edge(irn, edge)
128     if(is_Phi(edge->src))
129       return 1;
130
131   return 0;
132 }
133
134
135 #define is_live_in(bl,irn)                      _is_live_in(bl, irn)
136 #define is_live_out(bl,irn)             _is_live_out(bl, irn)
137 #define is_live_end(bl,irn)             _is_live_end(bl, irn)
138 #define put_live_in(bl,s)                         _put_live_in(bl, s)
139 #define put_live_out(bl,s)                      _put_live_out(bl, s)
140 #define put_live_end(bl,s)                      _put_live_end(bl, s)
141 #define is_phi_arg(irn)         _is_phi_arg(irn)
142
143 /**
144  * Initialize the liveness module.
145  * To be called from be_init().
146  */
147 void be_liveness_init(void);
148
149 #endif