if (smallest >= 0) {
be_operand_t *partner = &insn->ops[smallest];
+
+ for(i = insn->use_start; i < insn->n_ops; ++i) {
+ if(insn->ops[i].carrier == partner->carrier)
+ insn->ops[i].partner = out_op;
+ }
+
out_op->partner = partner;
partner->partner = out_op;
}
return perm;
}
-static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn, int *silent)
+static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env,
+ ir_node *irn, int *silent)
{
const arch_env_t *aenv;
int n_regs;
int *assignment;
pmap *partners;
int i, n_alloc;
- long col;
+ bitset_pos_t col;
const ir_edge_t *edge;
ir_node *perm = NULL;
int match_res, cost;
set of admissible registers via a bipartite graph.
*/
if(!op->partner || !pmap_contains(partners, op->partner->carrier)) {
+ ir_node *partner = op->partner ? op->partner->carrier : NULL;
+ pmap_insert(partners, op->carrier, partner);
+ if(partner != NULL)
+ pmap_insert(partners, partner, op->carrier);
+
+ /* don't insert a node twice */
+ int i;
+ for(i = 0; i < n_alloc; ++i) {
+ if(alloc_nodes[i] == op->carrier) {
+ break;
+ }
+ }
+ if(i < n_alloc)
+ continue;
- pmap_insert(partners, op->carrier, op->partner ? op->partner->carrier : NULL);
alloc_nodes[n_alloc] = op->carrier;
- DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, op->partner ? op->partner->carrier : NULL));
+ DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier,
+ partner));
bitset_clear_all(bs);
get_decisive_partner_regs(bs, op, op->partner);
- DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs));
+ DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier,
+ bs));
bitset_foreach(bs, col) {
hungarian_add(bp, n_alloc, col, 1);
*/
if(perm != NULL) {
foreach_out_edge(perm, edge) {
+ int i;
ir_node *proj = get_edge_src_irn(edge);
assert(is_Proj(proj));
if(!values_interfere(birg, proj, irn) || pmap_contains(partners, proj))
continue;
+ /* don't insert a node twice */
+ for(i = 0; i < n_alloc; ++i) {
+ if(alloc_nodes[i] == proj) {
+ break;
+ }
+ }
+ if(i < n_alloc)
+ continue;
+
+
assert(n_alloc < n_regs);
+
alloc_nodes[n_alloc] = proj;
pmap_insert(partners, proj, NULL);
if(!nodes[j])
continue;
+ assert(! (reg->type & arch_register_type_ignore));
arch_set_irn_register(aenv, nodes[j], reg);
(void) pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]);
DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name));
be_lv_t *lv = env->birg->lv;
int i, n;
+ bitset_pos_t elm;
unsigned step = 0;
unsigned pressure = 0;
struct list_head *head;
- pset *live_in = be_lv_pset_put_in(lv, block, pset_new_ptr_default());
- pset *live_end = be_lv_pset_put_end(lv, block, pset_new_ptr_default());
DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
bitset_clear_all(live);
* Make final uses of all values live out of the block.
* They are necessary to build up real intervals.
*/
- foreach_pset(live_end, irn) {
+ be_lv_foreach(lv, block, be_lv_state_end, i) {
+ ir_node *irn = be_lv_get_irn(lv, block, i);
if(has_reg_class(env, irn)) {
DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_idx(irn)));
bitset_set(live, get_irn_idx(irn));
DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
DBG((dbg, LEVEL_2, "\tlive: %B\n", live));
+#ifndef SCHEDULE_PROJS
+ if (get_irn_mode(irn) == mode_T) {
+ const ir_edge_t *edge;
+
+ foreach_out_edge(irn, edge) {
+ ir_node *proj = get_edge_src_irn(edge);
+
+ /*
+ * If the node defines some value, which can put into a
+ * register of the current class, make a border for it.
+ */
+ if(has_reg_class(env, proj)) {
+ int nr = get_irn_idx(proj);
+
+ bitset_clear(live, nr);
+ border_def(proj, step, 1);
+ }
+ }
+ }
+#endif
/*
* If the node defines some value, which can put into a
* register of the current class, make a border for it.
++step;
}
- /*
- * Add initial defs for all values live in.
- */
- foreach_pset(live_in, irn) {
- if(has_reg_class(env, irn)) {
-
- /* Mark the value live in. */
- bitset_set(live, get_irn_idx(irn));
-
- /* Add the def */
+ bitset_foreach(live, elm) {
+ ir_node *irn = get_idx_irn(env->irg, elm);
+ if (be_is_live_in(lv, block, irn))
border_def(irn, step, 0);
- }
}
-
- del_pset(live_in);
- del_pset(live_end);
}
static void assign(ir_node *block, void *env_ptr)
bitset_t *live = bitset_irg_malloc(env->irg);
const arch_env_t *arch_env = env->birg->main_env->arch_env;
be_irg_t *birg = env->birg;
- lv_chk_t *lv = be_get_birg_liveness_chk(birg);
bitset_pos_t elm;
ir_node *irn;
*/
bitset_foreach (live_end_dom, elm) {
ir_node *irn = get_idx_irn(env->irg, elm);
- if (lv_chk_bl_in(lv, block, irn)) {
+ if (be_is_live_in(birg->lv, block, irn)) {
const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
int col;
{
be_chordal_alloc_env_t env;
char buf[256];
+ be_lv_t *lv;
be_irg_t *birg = chordal_env->birg;
const arch_register_class_t *cls = chordal_env->cls;
return;
be_assure_dom_front(birg);
- be_assure_liveness(birg);
+ lv = be_assure_liveness(birg);
+ be_liveness_assure_sets(lv);
+ be_liveness_assure_chk(lv);
+
assure_doms(irg);
env.chordal_env = chordal_env;