X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbechordal.c;h=a83c52a897e862deb4bcf8be5feed340206bf1eb;hb=6e3e499d6c68aee0c6a9ada6a99f16c4f6f8445b;hp=9a7066d15e16107166853c20eb5352f59c70b9be;hpb=0fa5bccd8fbbb9b1bd57c363d7c21cc5190e4d26;p=libfirm diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index 9a7066d15..a83c52a89 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -44,6 +44,7 @@ #include "belive_t.h" #include "benode_t.h" #include "bearch.h" +#include "beirgmod.h" #include "beifg.h" #include "bechordal_t.h" @@ -65,6 +66,7 @@ typedef struct _be_chordal_alloc_env_t { firm_dbg_module_t *constr_dbg; /**< Debug output for the constraint handler. */ pset *pre_colored; /**< Set of precolored nodes. */ bitset_t *live; /**< A liveness bitset. */ + bitset_t *tmp_colors; /**< An auxiliary bitset which is as long as the number of colors in the class. */ bitset_t *colors; /**< The color mask. */ bitset_t *in_colors; /**< Colors used by live in values. */ bitset_t *ignore_regs; /**< A bitset of all ignore registers in the current class. */ @@ -174,8 +176,10 @@ static INLINE int has_reg_class(const be_chordal_env_t *env, const ir_node *irn) static int get_next_free_reg(const be_chordal_alloc_env_t *alloc_env, bitset_t *colors) { - bitset_or(colors, alloc_env->ignore_regs); - return bitset_next_clear(colors, 0); + bitset_t *tmp = alloc_env->tmp_colors; + bitset_copy(tmp, colors); + bitset_or(tmp, alloc_env->ignore_regs); + return bitset_next_clear(tmp, 0); } typedef struct _operand_t operand_t; @@ -205,9 +209,10 @@ typedef struct { #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_env_t *env, ir_node *irn, struct obstack *obst) +static insn_t *scan_insn(be_chordal_alloc_env_t *alloc_env, ir_node *irn, struct obstack *obst) { - const arch_env_t *arch_env = env->birg->main_env->arch_env; + 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; @@ -258,7 +263,7 @@ static insn_t *scan_insn(be_chordal_env_t *env, ir_node *irn, struct obstack *ob 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, irn, i, env->cls)) { + 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; @@ -319,12 +324,9 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, co static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *insn) { const be_chordal_env_t *env = alloc_env->chordal_env; - const arch_env_t *aenv = env->birg->main_env->arch_env; - firm_dbg_module_t *dbg = alloc_env->constr_dbg; int n_uses = insn_n_uses(insn); int n_defs = insn_n_defs(insn); - int max_pairs = MIN(n_uses, n_defs); 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])); @@ -408,7 +410,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ */ for(i = insn->use_start; i < insn->n_ops; ++i) { operand_t *op = &insn->ops[i]; - if(op->has_constraints && values_interfere(op->carrier, insn->irn)) { + 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); @@ -448,20 +450,21 @@ 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(env, insn->irn, &env->obst); + *the_insn = insn = scan_insn(alloc_env, insn->irn, &env->obst); /* 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) { - ir_node *proj = insn->ops[i].carrier; + operand_t *op = &insn->ops[i]; + ir_node *proj = op->carrier; /* Note that the predecessor must not be a Proj of the Perm, since ignore-nodes are not Perm'ed. */ - if(is_Proj(proj) && get_Proj_pred(proj) == perm) { - be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), &insn->ops[i].req); + if(op->has_constraints && is_Proj(proj) && get_Proj_pred(proj) == perm) { + be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), &op->req); } } } @@ -469,12 +472,13 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ return perm; } -static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn) +static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn, int *silent) { be_chordal_env_t *env = alloc_env->chordal_env; void *base = obstack_base(&env->obst); - insn_t *insn = scan_insn(env, irn, &env->obst); + insn_t *insn = scan_insn(alloc_env, irn, &env->obst); ir_node *res = insn->next_insn; + int be_silent = *silent; if(insn->pre_colored) { int i; @@ -482,7 +486,17 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i pset_insert_ptr(alloc_env->pre_colored, insn->ops[i].carrier); } - if(be_is_Perm(irn) || be_is_RegParams(irn) || (be_is_Barrier(irn) && !insn->in_constraints)) + /* + If the current node is a barrier toggle the silent flag. + If we are in the start block, we are ought to be silent at the beginning, + so the toggling activates the constraint handling but skips the barrier. + If we are in the end block we handle the in requirements of the barrier + and set the rest to silent. + */ + if(be_is_Barrier(irn)) + *silent = !*silent; + + if(be_silent) goto end; /* @@ -494,7 +508,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i const arch_env_t *aenv = env->birg->main_env->arch_env; int n_regs = env->cls->n_regs; bitset_t *bs = bitset_alloca(n_regs); - bitset_t *non_ignore = bitset_alloca(n_regs); ir_node **alloc_nodes = alloca(n_regs * sizeof(alloc_nodes[0])); bipartite_t *bp = bipartite_new(n_regs, n_regs); int *assignment = alloca(n_regs * sizeof(assignment[0])); @@ -557,7 +570,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i assert(is_Proj(proj)); - if(values_interfere(proj, irn)) { + if(values_interfere(proj, irn) && !pmap_contains(partners, proj)) { assert(n_alloc < n_regs); alloc_nodes[n_alloc] = proj; pmap_insert(partners, proj, NULL); @@ -640,20 +653,30 @@ end: /** * Handle constraint nodes in each basic block. - * be_insert_constr_perms() inserts Perm nodes which perm + * handle_constraints() inserts Perm nodes which perm * over all values live at the constrained node right in front * of the constrained node. These Perms signal a constrained node. - * For further comments, refer to handle_constraints_at_perm(). + * For further comments, refer to handle_constraints(). */ static void constraints(ir_node *bl, void *data) { - firm_dbg_module_t *dbg = firm_dbg_register("firm.be.chordal.constr"); be_chordal_alloc_env_t *env = data; - arch_env_t *arch_env = env->chordal_env->birg->main_env->arch_env; + + /* + Start silent in the start block. + The silence remains until the first barrier is seen. + Each other block is begun loud. + */ + int silent = bl == get_irg_start_block(get_irn_irg(bl)); ir_node *irn; + /* + If the block is the start block search the barrier and + start handling constraints from there. + */ + for(irn = sched_first(bl); !sched_is_end(irn);) { - irn = handle_constraints(env, irn); + irn = handle_constraints(env, irn, &silent); } } @@ -675,7 +698,6 @@ static void pressure(ir_node *block, void *env_ptr) be_chordal_alloc_env_t *alloc_env = env_ptr; be_chordal_env_t *env = alloc_env->chordal_env; - const arch_env_t *arch_env = env->birg->main_env->arch_env; bitset_t *live = alloc_env->live; firm_dbg_module_t *dbg = env->dbg; ir_node *irn; @@ -845,11 +867,10 @@ static void assign(ir_node *block, void *env_ptr) col = get_next_free_reg(alloc_env, colors); reg = arch_register_for_index(env->cls, col); assert(arch_get_irn_register(arch_env, irn) == NULL && "This node must not have been assigned a register yet"); + assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register"); } bitset_set(colors, col); - - assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register"); arch_set_irn_register(arch_env, irn, reg); DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n", @@ -892,11 +913,12 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env) env.chordal_env = chordal_env; env.colors_n = colors_n; - env.colors = bitset_malloc(colors_n); - env.in_colors = bitset_malloc(colors_n); - env.ignore_regs = bitset_malloc(colors_n); + env.colors = bitset_alloca(colors_n); + env.tmp_colors = bitset_alloca(colors_n); + env.in_colors = bitset_alloca(colors_n); + env.ignore_regs = bitset_alloca(colors_n); env.pre_colored = pset_new_ptr_default(); - env.constr_dbg = firm_dbg_register("firm.be.chordal.constr"); + FIRM_DBG_REGISTER(env.constr_dbg, "firm.be.chordal.constr"); for(i = 0; i < colors_n; ++i) if(arch_register_type_is(&chordal_env->cls->regs[i], ignore)) @@ -929,9 +951,5 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env) plotter_free(plotter); } - free(env.live); - free(env.colors); - free(env.in_colors); - free(env.ignore_regs); del_pset(env.pre_colored); }