X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fbe%2Fbelive_t.h;h=2d20088a8132c17966ad44b9968d7f8e33d1ce11;hb=b1ba3383b1807b7b506b394eb5b3e0992ad60f34;hp=61ce41236a65e1a7a68f48f98182da7b5ddd15b9;hpb=afd4d9d4b9cc42d04f8d3b8bb79bb0673a05c51e;p=libfirm diff --git a/ir/be/belive_t.h b/ir/be/belive_t.h index 61ce41236..2d20088a8 100644 --- a/ir/be/belive_t.h +++ b/ir/be/belive_t.h @@ -7,92 +7,137 @@ #ifndef _BELIVE_T_H #define _BELIVE_T_H -#include "config.h" +#include "firm_config.h" + +#include "irgraph_t.h" +#include "iredges_t.h" #include "belive.h" #include "pset.h" +#include "set.h" +#include "list.h" +#include "hashptr.h" -typedef struct _block_live_info_t { - pset *in; /**< The set of all values live in at that block. */ - pset *out; /**< The set of all values live out. */ - pset *end; /**< The set of all values live at the end - of the block (contains all live out). */ -} block_live_info_t; +typedef enum _live_state_t { + live_state_in = 1, + live_state_end = 2, + live_state_out = 4, + live_state_block = 8, +} live_state_t; -typedef struct _node_live_info_t { - int is_phi_op; /**< Marks the node as a phi operand. */ -} node_live_info_t; +typedef struct _irn_live_t { + const ir_node *block; + const ir_node *irn; + unsigned state; + struct _irn_live_t *next; +} irn_live_t; -typedef struct _live_info_t { - union { - block_live_info_t block; - node_live_info_t node; - } v; -} live_info_t; +typedef struct _irg_live_info_t { + set *live; +} irg_live_info_t; -extern size_t live_irn_data_offset; +extern size_t live_irg_data_offset; -#define get_irn_live_info(irn) get_irn_data(irn, live_info_t, live_irn_data_offset) -#define get_live_info_irn(inf) get_irn_data_base(inf, live_irn_data_offset) +#define get_irg_live_info(irg) (get_irg_data(irg, irg_live_info_t, live_irg_data_offset)) -#define get_block_live_info(irn) (&(get_irn_live_info(irn)->v.block)) -#define get_node_live_info(irn) (&(get_irn_live_info(irn)->v.node)) +#define live_is_in(live) (((live)->state & live_state_in) != 0) +#define live_is_end(live) (((live)->state & live_state_end) != 0) +#define live_is_out(live) (((live)->state & live_state_out) != 0) -static INLINE int __is_phi_operand(const ir_node *irn) +static INLINE irn_live_t *_get_or_set_live(const ir_node *block, const ir_node *irn, int state) { - assert(!is_Block(irn) && "No block node allowed here"); - return get_node_live_info(irn)->is_phi_op; + irg_live_info_t *live_info = get_irg_live_info(get_irn_irg(block)); + unsigned hash = HASH_PTR(block) + 37 * HASH_PTR(irn); + irn_live_t *live, templ; + + templ.block = block; + templ.irn = irn; + templ.state = -1; + templ.next = NULL; + + live = set_insert(live_info->live, &templ, sizeof(templ), hash); + if(live->state == -1) { + + if(!is_Block(irn)) { + irn_live_t *bl_live = _get_or_set_live(block, block, live_state_block); + live->next = bl_live->next; + bl_live->next = live; + } + + live->state = state; + } + + live->state |= state; + + return live; } -static INLINE int __is_live_in(const ir_node *block, const ir_node *irn) +static INLINE int _is_live_in(const ir_node *block, const ir_node *irn) { - block_live_info_t *info = get_block_live_info(block); - - assert(is_Block(block) && "Need a block here"); - return pset_find_ptr(info->in, irn) != NULL; + return (_get_or_set_live(block, irn, 0)->state & live_state_in) != 0; } -static INLINE int __is_live_out(const ir_node *block, const ir_node *irn) +static INLINE int _is_live_out(const ir_node *block, const ir_node *irn) { - block_live_info_t *info = get_block_live_info(block); + return (_get_or_set_live(block, irn, 0)->state & live_state_out) != 0; +} - assert(is_Block(block) && "Need a block here"); - return pset_find_ptr(info->out, irn) != NULL; +static INLINE int _is_live_end(const ir_node *block, const ir_node *irn) +{ + return (_get_or_set_live(block, irn, 0)->state & live_state_end) != 0; } -static INLINE int __is_live_end(const ir_node *block, const ir_node *irn) +#define live_foreach(block, live_info) \ + for(live_info = _get_or_set_live(block, block, 0)->next; live_info; live_info = live_info->next) + +static INLINE void _put_live(const ir_node *block, int state, pset *s) { - block_live_info_t *info = get_block_live_info(block); + irn_live_t *live; + + live_foreach(block, live) { + if(live->state & state) + pset_insert_ptr(s, live->irn); + } +} - assert(is_Block(block) && "Need a block here"); - return pset_find_ptr(info->end, irn) != NULL; +static INLINE pset *_put_live_in(const ir_node *block, pset *s) +{ + _put_live(block, live_state_in, s); + return s; } -static INLINE pset *__get_live_in(const ir_node *block) +static INLINE pset *_put_live_out(const ir_node *block, pset *s) { - assert(is_Block(block) && "Need a block here"); - return get_block_live_info(block)->in; + _put_live(block, live_state_out, s); + return s; } -static INLINE pset *__get_live_out(const ir_node *block) +static INLINE pset *_put_live_end(const ir_node *block, pset *s) { - assert(is_Block(block) && "Need a block here"); - return get_block_live_info(block)->out; + _put_live(block, live_state_end, s); + return s; } -static INLINE pset *__get_live_end(const ir_node *block) +static INLINE int _is_phi_arg(const ir_node *irn) { - assert(is_Block(block) && "Need a block here"); - return get_block_live_info(block)->end; + const ir_edge_t *edge; + + assert(edges_activated(get_irn_irg(irn)) && "Please compute the out edges"); + foreach_out_edge(irn, edge) + if(is_Phi(edge->src)) + return 1; + + return 0; } -#define is_phi_operand(irn) __is_phi_operand(irn) -#define is_live_in(bl,irn) __is_live_in(bl, irn) -#define is_live_out(bl,irn) __is_live_out(bl, irn) -#define is_live_end(bl,irn) __is_live_end(bl, irn) -#define get_live_in(bl) __get_live_in(bl) -#define get_live_out(bl) __get_live_out(bl) -#define get_live_end(bl) __get_live_end(bl) + +#define is_live_in(bl,irn) _is_live_in(bl, irn) +#define is_live_out(bl,irn) _is_live_out(bl, irn) +#define is_live_end(bl,irn) _is_live_end(bl, irn) +#define put_live_in(bl,s) _put_live_in(bl, s) +#define put_live_out(bl,s) _put_live_out(bl, s) +#define put_live_end(bl,s) _put_live_end(bl, s) +#define is_phi_arg(irn) _is_phi_arg(irn) /** * Initialize the liveness module.