X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbelive.c;h=acf32c238e02ef56b7dd2bcf0730b1cca5b7b1ab;hb=df2faee01a5832057bb3ca0ba5f67e979c916e19;hp=3129520630fcc8719015320490d2b36ffd8b0ea2;hpb=3c2c8da0b29805ca3ce8a17cc23a60ffaa6e0ec1;p=libfirm diff --git a/ir/be/belive.c b/ir/be/belive.c index 312952063..acf32c238 100644 --- a/ir/be/belive.c +++ b/ir/be/belive.c @@ -30,44 +30,23 @@ #include "iredges_t.h" #include "irgwalk.h" -#include "irprintf_t.h" +#include "irprintf.h" #include "irdump_t.h" #include "irnodeset.h" #include "absgraph.h" -#include "statev.h" - +#include "statev_t.h" +#include "be_t.h" +#include "bearch.h" #include "beutil.h" #include "belive_t.h" -#include "beirg.h" #include "besched.h" #include "bemodule.h" -#include "bedump.h" DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) #define LV_STD_SIZE 64 -/** - * Filter out some nodes for which we never need liveness. - * - * @param irn the node t check - * @return 0 if no liveness info is needed, 1 else - */ -static inline int is_liveness_node(const ir_node *irn) -{ - switch (get_irn_opcode(irn)) { - case iro_Block: - case iro_Bad: - case iro_End: - case iro_Anchor: - case iro_NoMem: - return 0; - default: - return 1; - } -} - int (be_is_live_in)(const be_lv_t *lv, const ir_node *block, const ir_node *irn) { return _be_is_live_xxx(lv, block, irn, be_lv_state_in); @@ -83,7 +62,7 @@ int (be_is_live_end)(const be_lv_t *lv, const ir_node *block, const ir_node *irn return _be_is_live_xxx(lv, block, irn, be_lv_state_end); } -static inline unsigned _be_liveness_bsearch(be_lv_info_t *arr, unsigned idx) +static inline unsigned _be_liveness_bsearch(be_lv_info_t *arr, const ir_node *node) { be_lv_info_t *payload = arr + 1; @@ -96,16 +75,15 @@ static inline unsigned _be_liveness_bsearch(be_lv_info_t *arr, unsigned idx) return 0; do { - int md = lo + ((hi - lo) >> 1); - unsigned md_idx = payload[md].node.idx; + int md = lo + ((hi - lo) >> 1); + ir_node *md_node = payload[md].node.node; - if (idx > md_idx) + if (node > md_node) lo = md + 1; - else if (idx < md_idx) + else if (node < md_node) hi = md; else { res = md; - assert(payload[res].node.idx == idx); break; } @@ -124,16 +102,14 @@ be_lv_info_node_t *be_lv_get(const be_lv_t *li, const ir_node *bl, stat_ev_tim_push(); irn_live = ir_nodehashmap_get(be_lv_info_t, &li->map, bl); if (irn_live != NULL) { - unsigned idx = get_irn_idx(irn); - /* Get the position of the index in the array. */ - int pos = _be_liveness_bsearch(irn_live, idx); + int pos = _be_liveness_bsearch(irn_live, irn); /* Get the record in question. 1 must be added, since the first record contains information about the array and must be skipped. */ be_lv_info_node_t *rec = &irn_live[pos + 1].node; /* Check, if the irn is in deed in the array. */ - if (rec->idx == idx) + if (rec->node == irn) res = rec; } stat_ev_tim_pop("be_lv_get"); @@ -151,16 +127,14 @@ static be_lv_info_node_t *be_lv_get_or_set(be_lv_t *li, ir_node *bl, ir_nodehashmap_insert(&li->map, bl, irn_live); } - unsigned idx = get_irn_idx(irn); - /* Get the position of the index in the array. */ - unsigned pos = _be_liveness_bsearch(irn_live, idx); + unsigned pos = _be_liveness_bsearch(irn_live, irn); /* Get the record in question. 1 must be added, since the first record contains information about the array and must be skipped. */ be_lv_info_node_t *res = &irn_live[pos + 1].node; /* Check, if the irn is in deed in the array. */ - if (res->idx != idx) { + if (res->node != irn) { be_lv_info_t *payload; unsigned n_members = irn_live[0].head.n_members; unsigned n_size = irn_live[0].head.n_size; @@ -188,9 +162,9 @@ static be_lv_info_node_t *be_lv_get_or_set(be_lv_t *li, ir_node *bl, ++irn_live[0].head.n_members; - res = &payload[pos].node; - res->idx = idx; - res->flags = 0; + res = &payload[pos].node; + res->node = irn; + res->flags = 0; } return res; @@ -207,19 +181,18 @@ static int be_lv_remove(be_lv_t *li, const ir_node *bl, if (irn_live != NULL) { unsigned n = irn_live[0].head.n_members; - unsigned idx = get_irn_idx(irn); - unsigned pos = _be_liveness_bsearch(irn_live, idx); + unsigned pos = _be_liveness_bsearch(irn_live, irn); be_lv_info_t *payload = irn_live + 1; be_lv_info_node_t *res = &payload[pos].node; /* The node is in deed in the block's array. Let's remove it. */ - if (res->idx == idx) { + if (res->node == irn) { unsigned i; for (i = pos + 1; i < n; ++i) payload[i - 1] = payload[i]; - payload[n - 1].node.idx = 0; + payload[n - 1].node.node = NULL; payload[n - 1].node.flags = 0; --irn_live[0].head.n_members; @@ -390,7 +363,6 @@ static void collect_liveness_nodes(ir_node *irn, void *data) void be_liveness_compute_sets(be_lv_t *lv) { - ir_node **nodes; int i; int n; @@ -402,8 +374,7 @@ void be_liveness_compute_sets(be_lv_t *lv) obstack_init(&lv->obst); n = get_irg_last_idx(lv->irg); - nodes = NEW_ARR_F(ir_node *, n); - memset(nodes, 0, sizeof(nodes[0]) * n); + ir_node **const nodes = NEW_ARR_FZ(ir_node*, n); /* inserting the variables sorted by their ID is probably * more efficient since the binary sorted set insertion @@ -420,7 +391,6 @@ void be_liveness_compute_sets(be_lv_t *lv) DEL_ARR_F(nodes); free(re.visited); - register_hook(hook_node_info, &lv->hook_info); be_timer_pop(T_LIVE); @@ -438,7 +408,6 @@ void be_liveness_invalidate_sets(be_lv_t *lv) { if (!lv->sets_valid) return; - unregister_hook(hook_node_info, &lv->hook_info); obstack_free(&lv->obst, NULL); ir_nodehashmap_destroy(&lv->map); lv->sets_valid = false; @@ -459,8 +428,6 @@ be_lv_t *be_liveness_new(ir_graph *irg) be_lv_t *lv = XMALLOCZ(be_lv_t); lv->irg = irg; - lv->hook_info.context = lv; - lv->hook_info.hook._hook_node_info = be_dump_liveness_block; return lv; } @@ -509,31 +476,17 @@ void be_liveness_update(be_lv_t *lv, ir_node *irn) void be_liveness_transfer(const arch_register_class_t *cls, ir_node *node, ir_nodeset_t *nodeset) { - int i, arity; - /* You should better break out of your loop when hitting the first phi * function. */ assert(!is_Phi(node) && "liveness_transfer produces invalid results for phi nodes"); - if (get_irn_mode(node) == mode_T) { - foreach_out_edge(node, edge) { - ir_node *proj = get_edge_src_irn(edge); + be_foreach_definition(node, cls, value, req, + ir_nodeset_remove(nodeset, value); + ); - if (arch_irn_consider_in_reg_alloc(cls, proj)) { - ir_nodeset_remove(nodeset, proj); - } - } - } else if (arch_irn_consider_in_reg_alloc(cls, node)) { - ir_nodeset_remove(nodeset, node); - } - - arity = get_irn_arity(node); - for (i = 0; i < arity; ++i) { - ir_node *op = get_irn_n(node, i); - - if (arch_irn_consider_in_reg_alloc(cls, op)) - ir_nodeset_insert(nodeset, op); - } + be_foreach_use(node, cls, in_req, op, op_req, + ir_nodeset_insert(nodeset, op); + ); } @@ -543,32 +496,21 @@ void be_liveness_end_of_block(const be_lv_t *lv, const ir_node *block, ir_nodeset_t *live) { assert(lv->sets_valid && "live sets must be computed"); - be_lv_foreach(lv, block, be_lv_state_end, node) { - if (!arch_irn_consider_in_reg_alloc(cls, node)) - continue; - + be_lv_foreach_cls(lv, block, be_lv_state_end, cls, node) { ir_nodeset_insert(live, node); } } -void be_liveness_nodes_live_at(const be_lv_t *lv, - const arch_register_class_t *cls, - const ir_node *pos, ir_nodeset_t *live) +void be_liveness_nodes_live_before(be_lv_t const *const lv, arch_register_class_t const *const cls, ir_node const *const pos, ir_nodeset_t *const live) { - const ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos); - + ir_node const *const bl = get_nodes_block(pos); be_liveness_end_of_block(lv, cls, bl, live); sched_foreach_reverse(bl, irn) { - /* - * If we encounter the node we want to insert the Perm after, - * exit immediately, so that this node is still live - */ + be_liveness_transfer(cls, irn, live); if (irn == pos) return; - - be_liveness_transfer(cls, irn, live); } }