static void ou_optimize(unit_t *ou) {
int i;
qnode_t *curr = NULL, *tmp;
- bitset_t *pos_regs = bitset_alloca(ou->co->chordal_env->cls->n_regs);
+ arch_env_t *aenv = get_arch_env(ou->co);
+ const arch_register_class_t *cls = ou->co->chordal_env->cls;
+ bitset_t *pos_regs = bitset_alloca(cls->n_regs);
+ bitset_t *ign_regs = bitset_alloca(cls->n_regs);
DBG((dbg, LEVEL_1, "\tOptimizing unit:\n"));
for (i=0; i<ou->node_count; ++i)
/* init queue */
INIT_LIST_HEAD(&ou->queue);
- arch_get_allocatable_regs(get_arch_env(ou->co), ou->nodes[0], -1, pos_regs);
+
+ arch_get_allocatable_regs(aenv, ou->nodes[0], -1, pos_regs);
+
+ /* exclude ingore colors */
+ arch_put_non_ignore_regs(aenv, cls, ign_regs);
+ bitset_and(pos_regs, ign_regs);
+
+ /* create new qnode */
bitset_foreach(pos_regs, i)
ou_insert_qnode(ou, new_qnode(ou, i));
copy_opt_t *co = env;
unit_t *unit;
arch_register_req_t req;
+ arch_env_t *aenv = co->chordal_env->main_env->arch_env;
if (!is_curr_reg_class(irn))
return;
}
int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
- arch_env_t *aenv = co->chordal_env->main_env->arch_env;
+ arch_env_t *aenv = get_arch_env(co);
const ir_edge_t *edge;
+ if (arch_irn_is_ignore(aenv, irn))
+ return 0;
+
foreach_out_edge(irn, edge) {
ir_node *n = edge->src;
- arch_register_req_t req;
- arch_get_register_req(aenv, &req, n, -1);
+ if (!nodes_interfere(co->chordal_env, irn, n) || irn == n) {
+ arch_register_req_t req;
+ arch_get_register_req(aenv, &req, n, -1);
- if( ( (req.type == arch_register_req_type_should_be_same && req.other == irn) ||
- is_Reg_Phi(n) ||
- is_Perm(get_arch_env(co), n)
- ) && (irn == n || !nodes_interfere(co->chordal_env, irn, n)))
+ if(is_Reg_Phi(n) ||
+ is_Perm(aenv, n) ||
+ (arch_register_req_is(&req, should_be_same) && req.other == irn)
+ )
return 1;
+ }
}
return 0;
* @param irn The irn to check
* @param req A register_requirement structure (used to check for 2-addr-code)
*/
-#define is_optimizable(arch, irn, req) (is_Reg_Phi(irn) || is_Perm_Proj(arch, irn) || is_2addr_code(arch, irn, req))
+#define is_optimizable(arch, irn, req) (!arch_irn_is_ignore(arch, irn) && (is_Reg_Phi(irn) || is_Perm_Proj(arch, irn) || is_2addr_code(arch, irn, req)))
/**
* Checks if the irn is a non-interfering argument of a node which 'is_optimizable'
return !workset_contains(sws, irn);
}
+/**
+ * @return The distance to the next use
+ * Or 0 if irn is an ignore node
+ */
+#define get_distance(bel, from, from_step, def, skip_from_uses) \
+ ((arch_irn_is_ignore(bel->arch, def) ) ? 0 : be_get_next_use(bel->uses, from, from_step, def, skip_from_uses))
+
+
/**
* Collects all values live-in at block @p blk and all phi results in this block.
* Then it adds the best values (at most n_regs) to the blocks start_workset.
sched_foreach(blk, irn)
if (is_Phi(irn) && arch_get_irn_reg_class(bel->arch, irn, -1) == bel->cls) {
loc.irn = irn;
- loc.time = be_get_next_use(bel->uses, first, 0, irn, 0);
+ loc.time = get_distance(bel, first, 0, irn, 0);
obstack_grow(&ob, &loc, sizeof(loc));
DBG((dbg, DBG_START, " %+F:\n", irn));
count++;
live_foreach(blk, li)
if (live_is_in(li) && arch_get_irn_reg_class(bel->arch, li->irn, -1) == bel->cls) {
loc.irn = (ir_node *)li->irn;
- loc.time = be_get_next_use(bel->uses, first, 0, li->irn, 0);
+ loc.time = get_distance(bel, first, 0, li->irn, 0);
obstack_grow(&ob, &loc, sizeof(loc));
DBG((dbg, DBG_START, " %+F:\n", irn));
count++;
if (len > max_allowed) {
/* get current next-use distance */
for (i=0; i<ws->len; ++i)
- workset_set_time(ws, i, be_get_next_use(bel->uses, bel->instr, bel->instr_nr, workset_get_val(ws, i), !is_usage));
+ workset_set_time(ws, i, get_distance(bel, bel->instr, bel->instr_nr, workset_get_val(ws, i), !is_usage));
/* sort entries by increasing nextuse-distance*/
workset_sort(ws);