2 * Internal headers for liveness analysis.
3 * @author Sebastian Hack
10 #include "firm_config.h"
12 #include "irgraph_t.h"
13 #include "iredges_t.h"
21 typedef enum _live_state_t {
28 typedef struct _irn_live_t {
32 struct _irn_live_t *next;
35 typedef struct _irg_live_info_t {
39 extern size_t live_irg_data_offset;
41 #define get_irg_live_info(irg) (get_irg_data(irg, irg_live_info_t, live_irg_data_offset))
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)
47 static INLINE irn_live_t *_get_or_set_live(const ir_node *block, const ir_node *irn, int state)
49 irg_live_info_t *live_info = get_irg_live_info(get_irn_irg(block));
50 unsigned hash = HASH_PTR(block) + 37 * HASH_PTR(irn);
51 irn_live_t *live, templ;
58 live = set_insert(live_info->live, &templ, sizeof(templ), hash);
59 if(live->state == -1) {
62 irn_live_t *bl_live = _get_or_set_live(block, block, live_state_block);
63 live->next = bl_live->next;
75 static INLINE int _is_live_in(const ir_node *block, const ir_node *irn)
77 return (_get_or_set_live(block, irn, 0)->state & live_state_in) != 0;
80 static INLINE int _is_live_out(const ir_node *block, const ir_node *irn)
82 return (_get_or_set_live(block, irn, 0)->state & live_state_out) != 0;
85 static INLINE int _is_live_end(const ir_node *block, const ir_node *irn)
87 return (_get_or_set_live(block, irn, 0)->state & live_state_end) != 0;
90 #define live_foreach(block, live_info) \
91 for(live_info = _get_or_set_live(block, block, 0)->next; live_info; live_info = live_info->next)
93 static INLINE void _put_live(const ir_node *block, int state, pset *s)
97 live_foreach(block, live) {
98 if(live->state & state)
99 pset_insert_ptr(s, live->irn);
103 static INLINE pset *_put_live_in(const ir_node *block, pset *s)
105 _put_live(block, live_state_in, s);
109 static INLINE pset *_put_live_out(const ir_node *block, pset *s)
111 _put_live(block, live_state_out, s);
115 static INLINE pset *_put_live_end(const ir_node *block, pset *s)
117 _put_live(block, live_state_end, s);
121 static INLINE int _is_phi_arg(const ir_node *irn)
123 const ir_edge_t *edge;
125 assert(edges_activated(get_irn_irg(irn)) && "Please compute the out edges");
126 foreach_out_edge(irn, edge)
127 if(is_Phi(edge->src))
134 #define is_live_in(bl,irn) _is_live_in(bl, irn)
135 #define is_live_out(bl,irn) _is_live_out(bl, irn)
136 #define is_live_end(bl,irn) _is_live_end(bl, irn)
137 #define put_live_in(bl,s) _put_live_in(bl, s)
138 #define put_live_out(bl,s) _put_live_out(bl, s)
139 #define put_live_end(bl,s) _put_live_end(bl, s)
140 #define is_phi_arg(irn) _is_phi_arg(irn)
143 * Initialize the liveness module.
144 * To be called from be_init().
146 void be_liveness_init(void);