X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbenode.c;h=85392494c455e338e08b9468a929cd35e3c14007;hb=ab5a59d5ee2de51336777a0396153acfa3e70f41;hp=b7a37494d18b4533ccd8d746c37d1ed58c76d1b1;hpb=03ffa62ef4f525aa0c45dbe766a17bc94b161695;p=libfirm diff --git a/ir/be/benode.c b/ir/be/benode.c index b7a37494d..85392494c 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -8,31 +8,29 @@ * Copyright (C) 2005 Universitaet Karlsruhe * Released under the GPL */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include "obst.h" #include "set.h" #include "pmap.h" -#include "offset.h" +#include "util.h" +#include "debug.h" #include "irop_t.h" #include "irmode_t.h" #include "irnode_t.h" +#include "ircons_t.h" +#include "be_t.h" +#include "belive_t.h" +#include "besched_t.h" #include "benode_t.h" -struct _be_node_factory_t { - const arch_isa_if_t *isa; - - struct obstack obst; - set *ops; - pmap *irn_op_map; - pmap *reg_req_map; - - arch_irn_handler_t handler; - arch_irn_ops_t irn_ops; -}; +#include "beirgmod.h" typedef enum _node_kind_t { node_kind_spill, @@ -99,17 +97,15 @@ ir_node *new_Spill(const be_node_factory_t *factory, } ir_node *new_Reload(const be_node_factory_t *factory, - const arch_register_class_t *cls, - ir_graph *irg, ir_node *bl, ir_node *spill_node) + const arch_register_class_t *cls, ir_graph *irg, + ir_node *bl, ir_mode *mode, ir_node *spill_node) { - ir_mode *mode; ir_node *in[1]; ir_op *op = get_op(factory, cls, node_kind_reload)->op; assert(op && "Reload opcode must be present for this register class"); - assert(is_Spill(factory, spill_node) && "Operand of Reload must be a Spill"); + // assert(is_Spill(factory, spill_node) && "Operand of Reload must be a Spill"); in[0] = spill_node; - mode = get_irn_mode(get_irn_n(spill_node, 0)); return new_ir_node(NULL, irg, bl, op, mode, 1, in); } @@ -259,13 +255,12 @@ int is_Spill(const be_node_factory_t *f, const ir_node *irn) return bo->kind == node_kind_spill; } -be_node_factory_t *be_new_node_factory(const arch_isa_if_t *isa) +be_node_factory_t *be_node_factory_init(be_node_factory_t *factory, + const arch_isa_if_t *isa) { - be_node_factory_t *factory; char buf[256]; int i, j, n; - factory = malloc(sizeof(*factory)); factory->ops = new_set(cmp_op_map, 64); factory->irn_op_map = pmap_create(); obstack_init(&factory->obst); @@ -323,25 +318,73 @@ be_node_factory_t *be_new_node_factory(const arch_isa_if_t *isa) return factory; } -#if 0 -ir_node *be_spill(const be_node_factory_t *factory, - const arch_env_t *env, ir_node *node_to_spill) +ir_node *insert_Perm_after(const be_main_session_env_t *env, + const arch_register_class_t *cls, ir_node *pos) { - ir_node *res; - if(is_Reload(node_to_spill)) - res = get_irn_n(node_to_spill, 0); - else { - ir_node *bl = get_nodes_block(node_to_spill); - ir_graph *irg = get_irn_irg(bl); - - res = new_Spill(factory, cls, irg, bl, node_to_spill); + const arch_env_t *arch_env = env->main_env->arch_env; + ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos); + ir_graph *irg = get_irn_irg(bl); + pset *live = put_live_end(bl, pset_new_ptr_default()); + ir_node *curr, *irn, *perm, **nodes; + firm_dbg_module_t *dbg = firm_dbg_register("firm.be.node"); + int i, n; + + firm_dbg_set_mask(dbg, -1); + DBG((dbg, LEVEL_1, "Insert Perm after: %+F\n", pos)); + + sched_foreach_reverse(bl, irn) { + ir_node *x; + + /* + * If we encounter the node we want to insert the Perm after, + * exit immediately, so that this node is still live + */ + if(irn == pos) + break; + + DBG((dbg, LEVEL_1, "%+F\n", irn)); + for(x = pset_first(live); x; x = pset_next(live)) + DBG((dbg, LEVEL_1, "\tlive: %+F\n", x)); + + if(arch_irn_has_reg_class(arch_env, irn, arch_pos_make_out(0), cls)) + pset_remove_ptr(live, irn); + + for(i = 0, n = get_irn_arity(irn); i < n; ++i) { + ir_node *op = get_irn_n(irn, i); + + if(arch_irn_has_reg_class(arch_env, op, arch_pos_make_out(0), cls)) + pset_insert_ptr(live, op); + } } - return res; -} + n = pset_count(live); + nodes = malloc(n * sizeof(nodes[0])); -ir_node *be_reload(const be_node_factory_t *factory, - const arch_env_t *env, ir_node *spill) -{ + DBG((dbg, LEVEL_1, "live:\n")); + for(irn = pset_first(live), i = 0; irn; irn = pset_next(live), i++) { + DBG((dbg, LEVEL_1, "\t%+F\n", irn)); + nodes[i] = irn; + } + + perm = new_Perm(env->main_env->node_factory, cls, irg, bl, n, nodes); + sched_add_after(pos, perm); + free(nodes); + + curr = perm; + for(i = 0; i < n; ++i) { + ir_node *copies[1]; + ir_node *perm_op = get_irn_n(perm, i); + const arch_register_t *reg = arch_get_irn_register(arch_env, perm_op, 0); + + ir_mode *mode = get_irn_mode(perm_op); + ir_node *proj = new_r_Proj(irg, bl, perm, mode, i); + arch_set_irn_register(arch_env, proj, 0, reg); + + sched_add_after(curr, proj); + curr = proj; + + copies[0] = proj; + be_introduce_copies(env->dom_front, perm_op, array_size(copies), copies); + } + return perm; } -#endif