From 1631f8aca0f030511c4078f346e9a2117c8279b6 Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Thu, 6 Apr 2006 11:20:46 +0000 Subject: [PATCH] Added included support for be_insn_t --- ir/be/beabi.h | 1 + ir/be/bechordal.c | 153 ++++++++------------------------------------- ir/be/beraextern.c | 68 +++++++++++++++++++- 3 files changed, 92 insertions(+), 130 deletions(-) diff --git a/ir/be/beabi.h b/ir/be/beabi.h index 004abc14e..aa3f05901 100644 --- a/ir/be/beabi.h +++ b/ir/be/beabi.h @@ -122,6 +122,7 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env); void be_abi_free(be_abi_irg_t *abi); void be_abi_put_ignore_regs(be_abi_irg_t *abi, const arch_register_class_t *cls, bitset_t *bs); + ir_node *be_abi_get_callee_save_irn(be_abi_irg_t *abi, const arch_register_t *reg); #define be_abi_reg_map_get(map, reg) pmap_get((map), (void *) (reg)) diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index e810eda24..d17225359 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -46,6 +46,7 @@ #include "bearch.h" #include "beirgmod.h" #include "beifg.h" +#include "beinsn_t.h" #include "bechordal_t.h" #include "bechordal_draw.h" @@ -181,120 +182,7 @@ static int get_next_free_reg(const be_chordal_alloc_env_t *alloc_env, bitset_t * return bitset_next_clear(tmp, 0); } -typedef struct _operand_t operand_t; - -struct _operand_t { - ir_node *irn; - ir_node *carrier; - operand_t *partner; - bitset_t *regs; - int pos; - arch_register_req_t req; - unsigned has_constraints : 1; -}; - -typedef struct { - operand_t *ops; - int n_ops; - int use_start; - ir_node *next_insn; - ir_node *irn; - unsigned in_constraints : 1; - unsigned out_constraints : 1; - unsigned has_constraints : 1; - unsigned pre_colored : 1; -} insn_t; - -#define insn_n_defs(insn) ((insn)->use_start) -#define insn_n_uses(insn) ((insn)->n_ops - (insn)->use_start) - -static insn_t *scan_insn(be_chordal_alloc_env_t *alloc_env, ir_node *irn, struct obstack *obst) -{ - const be_chordal_env_t *env = alloc_env->chordal_env; - const arch_env_t *arch_env = env->birg->main_env->arch_env; - operand_t o; - insn_t *insn; - int i, n; - int pre_colored = 0; - - insn = obstack_alloc(obst, sizeof(insn[0])); - memset(insn, 0, sizeof(insn[0])); - - insn->irn = irn; - insn->next_insn = sched_next(irn); - if(get_irn_mode(irn) == mode_T) { - ir_node *p; - - for(p = sched_next(irn); is_Proj(p); p = sched_next(p)) { - if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, p)) { - arch_get_register_req(arch_env, &o.req, p, -1); - o.carrier = p; - o.irn = irn; - o.pos = -(get_Proj_proj(p) + 1); - o.partner = NULL; - o.has_constraints = arch_register_req_is(&o.req, limited); - obstack_grow(obst, &o, sizeof(o)); - insn->n_ops++; - insn->out_constraints |= o.has_constraints; - pre_colored += arch_get_irn_register(arch_env, p) != NULL; - } - } - - insn->next_insn = p; - } - - else if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, irn)) { - arch_get_register_req(arch_env, &o.req, irn, -1); - o.carrier = irn; - o.irn = irn; - o.pos = -1; - o.partner = NULL; - o.has_constraints = arch_register_req_is(&o.req, limited); - obstack_grow(obst, &o, sizeof(o)); - insn->n_ops++; - insn->out_constraints |= o.has_constraints; - pre_colored += arch_get_irn_register(arch_env, irn) != NULL; - } - - insn->pre_colored = pre_colored == insn->n_ops && insn->n_ops > 0; - insn->use_start = insn->n_ops; - - for(i = 0, n = get_irn_arity(irn); i < n; ++i) { - ir_node *op = get_irn_n(irn, i); - - if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, op)) { - arch_get_register_req(arch_env, &o.req, irn, i); - o.carrier = op; - o.irn = irn; - o.pos = i; - o.partner = NULL; - o.has_constraints = arch_register_req_is(&o.req, limited); - obstack_grow(obst, &o, sizeof(o)); - insn->n_ops++; - insn->in_constraints |= o.has_constraints; - } - } - - insn->has_constraints = insn->in_constraints | insn->out_constraints; - insn->ops = obstack_finish(obst); - - /* Compute the admissible registers bitsets. */ - for(i = 0; i < insn->n_ops; ++i) { - operand_t *op = &insn->ops[i]; - - assert(op->req.cls == env->cls); - op->regs = bitset_obstack_alloc(obst, env->cls->n_regs); - - if(arch_register_req_is(&op->req, limited)) - op->req.limited(op->req.limited_env, op->regs); - else - arch_put_non_ignore_regs(env->birg->main_env->arch_env, env->cls, op->regs); - } - - return insn; -} - -static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, const operand_t *o2) +static bitset_t *get_decisive_partner_regs(bitset_t *bs, const be_operand_t *o1, const be_operand_t *o2) { bitset_t *res = bs; @@ -320,12 +208,23 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, co return res; } -static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *insn) +static be_insn_t *chordal_scan_insn(be_chordal_alloc_env_t *env, ir_node *irn) +{ + be_insn_env_t ie; + + ie.ignore_colors = env->chordal_env->ignore_colors; + ie.aenv = env->chordal_env->birg->main_env->arch_env; + ie.obst = &env->chordal_env->obst; + ie.cls = env->chordal_env->cls; + return be_scan_insn(&ie, irn); +} + +static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t *insn) { const be_chordal_env_t *env = alloc_env->chordal_env; - int n_uses = insn_n_uses(insn); - int n_defs = insn_n_defs(insn); + int n_uses = be_insn_n_uses(insn); + int n_defs = be_insn_n_defs(insn); bitset_t *bs = bitset_alloca(env->cls->n_regs); bipartite_t *bp = bipartite_new(n_defs, n_uses); int *pairing = alloca(MAX(n_defs, n_uses) * sizeof(pairing[0])); @@ -337,11 +236,11 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *in same register as the out operand. */ for(j = 0; j < insn->use_start; ++j) { - operand_t *out_op = &insn->ops[j]; + be_operand_t *out_op = &insn->ops[j]; /* Try to find an in operand which has ... */ for(i = insn->use_start; i < insn->n_ops; ++i) { - const operand_t *op = &insn->ops[i]; + const be_operand_t *op = &insn->ops[i]; /* The in operand can only be paired with a def, if the node defining the @@ -375,11 +274,11 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *in } -static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_t **the_insn) +static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_insn_t **the_insn) { be_chordal_env_t *env = alloc_env->chordal_env; const arch_env_t *aenv = env->birg->main_env->arch_env; - insn_t *insn = *the_insn; + be_insn_t *insn = *the_insn; ir_node *bl = get_nodes_block(insn->irn); ir_node *copy = NULL; ir_node *perm = NULL; @@ -398,7 +297,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ be copied. */ for(i = 0; i < insn->use_start; ++i) { - operand_t *op = &insn->ops[i]; + be_operand_t *op = &insn->ops[i]; if(op->has_constraints) bitset_or(out_constr, op->regs); } @@ -408,7 +307,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ constraints which are also output constraints. */ for(i = insn->use_start; i < insn->n_ops; ++i) { - operand_t *op = &insn->ops[i]; + be_operand_t *op = &insn->ops[i]; if(op->has_constraints && (values_interfere(op->carrier, insn->irn) || arch_irn_is(aenv, op->carrier, ignore))) { bitset_copy(bs, op->regs); bitset_and(bs, out_constr); @@ -449,14 +348,14 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ */ be_liveness(env->irg); obstack_free(&env->obst, insn); - *the_insn = insn = scan_insn(alloc_env, insn->irn, &env->obst); + *the_insn = insn = chordal_scan_insn(alloc_env, insn->irn); /* Copy the input constraints of the insn to the Perm as output constraints. Succeeding phases (coalescing will need that). */ for(i = insn->use_start; i < insn->n_ops; ++i) { - operand_t *op = &insn->ops[i]; + be_operand_t *op = &insn->ops[i]; ir_node *proj = op->carrier; /* Note that the predecessor must not be a Proj of the Perm, @@ -475,7 +374,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i { be_chordal_env_t *env = alloc_env->chordal_env; void *base = obstack_base(&env->obst); - insn_t *insn = scan_insn(alloc_env, irn, &env->obst); + be_insn_t *insn = chordal_scan_insn(alloc_env, irn); ir_node *res = insn->next_insn; int be_silent = *silent; @@ -532,7 +431,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i to a bipartite graph (left: nodes with partners, right: admissible colors). */ for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) { - operand_t *op = &insn->ops[i]; + be_operand_t *op = &insn->ops[i]; /* If the operand has no partner or the partner has not been marked diff --git a/ir/be/beraextern.c b/ir/be/beraextern.c index 0153afbd0..7a2304554 100644 --- a/ir/be/beraextern.c +++ b/ir/be/beraextern.c @@ -94,6 +94,7 @@ alloc ::= node-nr reg-nr . #include "besched_t.h" #include "beutil.h" #include "belive_t.h" +#include "beinsn_t.h" #define DBG_LEVEL 2 @@ -193,14 +194,17 @@ static int get_loop_weight(ir_node *irn) { |_| *****************************************************************************/ -static void handle_constraints_walker(ir_node *irn, void *env) { - be_raext_env_t *raenv = env; +#if 0 +static void handle_constraints_insn(be_raext_env_t *raenv, be_insn_t *insn) +{ arch_register_req_t req; int pos, max; /* handle output constraints * user -> irn becomes user -> cpy -> irn */ + if(get_irn_mode(irn) == mode_T) { + } arch_get_register_req(raenv->aenv, &req, irn, -1); if (arch_register_req_is(&req, limited)) { ir_node *cpy = be_new_Copy(req.cls, raenv->irg, get_nodes_block(irn), irn); @@ -230,9 +234,67 @@ static void handle_constraints_walker(ir_node *irn, void *env) { } } } +#endif + +static void handle_constraints_insn(be_raext_env_t *env, be_insn_t *insn) +{ + ir_node *bl = get_nodes_block(insn->irn); + int i; + + for(i = 0; i < insn->use_start; ++i) { + be_operand_t *op = &insn->ops[i]; + + if(op->has_constraints) { + ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier); + sched_add_before(insn->next_insn, cpy); + edges_reroute(op->carrier, cpy, env->irg); + } + } + + for(i = insn->use_start; i < insn->n_ops; ++i) { + be_operand_t *op = &insn->ops[i]; + + if(op->has_constraints) { + ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier); + sched_add_before(insn->irn, cpy); + set_irn_n(insn->irn, op->pos, cpy); + be_set_constr_limited(cpy, BE_OUT_POS(0), &op->req); + } + } +} + +static void handle_constraints_block(ir_node *bl, void *data) +{ + be_raext_env_t *raenv = data; + int active = bl != get_irg_start_block(raenv->irg); + + ir_node *irn; + be_insn_env_t ie; + struct obstack obst; + + ie.cls = raenv->cls; + ie.aenv = raenv->aenv; + ie.obst = &obst; + ie.ignore_colors = NULL; + obstack_init(&obst); + + irn = sched_first(bl); + while(!sched_is_end(irn)) { + be_insn_t *insn = be_scan_insn(&ie, irn); + + if(insn->has_constraints) + handle_constraints_insn(raenv, insn); + + if(be_is_Barrier(irn)) + active = !active; + + irn = insn->next_insn; + obstack_free(&obst, insn); + } +} static void handle_constraints(be_raext_env_t *raenv) { - irg_walk_graph(raenv->irg, NULL, handle_constraints_walker, raenv); + irg_block_walk_graph(raenv->irg, NULL, handle_constraints_block, raenv); } -- 2.20.1