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;
} else
/* Proj of a perm with corresponding arg */
- if (is_Copy(get_arch_env(co), irn)) {
+ if (is_Perm_Proj(get_arch_env(co), irn)) {
assert(!nodes_interfere(co->chordal_env, irn, get_Copy_src(irn)));
unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
unit->costs = xmalloc(2 * sizeof(*unit->costs));
/* Src == Tgt of a 2-addr-code instruction */
if (is_2addr_code(get_arch_env(co), irn, &req)) {
- int pos = req.data.pos;
- unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
- unit->costs = xmalloc(2 * sizeof(*unit->costs));
- unit->node_count = 2;
- unit->nodes[0] = irn;
- unit->nodes[1] = get_irn_n(irn, pos);
- unit->costs[1] = co->get_costs(irn, unit->nodes[1], pos);
+ ir_node *other = req.other_same;
+ if (!nodes_interfere(co->chordal_env, irn, other)) {
+ unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
+ unit->costs = xmalloc(2 * sizeof(*unit->costs));
+ unit->node_count = 2;
+ unit->nodes[0] = irn;
+ unit->nodes[1] = other;
+ unit->costs[1] = co->get_costs(irn, other, -120480);
+ }
} else
assert(0 && "This is not an optimizable node!");
/* Insert the new unit at a position according to its costs */
- {
+ if (unit->node_count > 1) {
int i;
struct list_head *tmp;
while (tmp->next != &co->units && list_entry_units(tmp->next)->sort_key > unit->sort_key)
tmp = tmp->next;
list_add(&unit->units, tmp);
+ } else {
+ free(unit);
}
}
copy_opt_t *co;
dbg = firm_dbg_register("ir.be.copyopt");
- firm_dbg_set_mask(dbg, DEBUG_LVL_CO);
co = xcalloc(1, sizeof(*co));
co->chordal_env = chordal_env;
len = strlen(s1) + strlen(s2) + strlen(s3) + 5;
co->name = xmalloc(len);
snprintf(co->name, len, "%s__%s__%s", s1, s2, s3);
- if (!strcmp(co->name, DEBUG_IRG))
- firm_dbg_set_mask(dbg, DEBUG_IRG_LVL_CO);
- else
- firm_dbg_set_mask(dbg, DEBUG_LVL_CO);
DBG((dbg, LEVEL_1, "\tCollecting optimization units\n"));
INIT_LIST_HEAD(&co->units);
xfree(co->name);
list_for_each_entry_safe(unit_t, curr, tmp, &co->units, units) {
xfree(curr->nodes);
+ xfree(curr->costs);
xfree(curr);
}
}
int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
- int i, max;
- 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;
- for(i=0, max=get_irn_n_outs(irn); i<max; ++i) {
- ir_node *n = get_irn_out(irn, i);
- arch_register_req_t req;
- arch_get_register_req(aenv, &req, n, -1);
+ foreach_out_edge(irn, edge) {
+ ir_node *n = edge->src;
- if( ( (req.type == arch_register_req_type_should_be_same && get_irn_n(n, req.data.pos) == irn) ||
- is_Reg_Phi(n) ||
- is_Perm(get_arch_env(co), n)
- ) && (irn == n || !nodes_interfere(co->chordal_env, irn, n)))
+ if (!nodes_interfere(co->chordal_env, irn, n) || irn == n) {
+ arch_register_req_t req;
+ arch_get_register_req(aenv, &req, n, -1);
+
+ if(is_Reg_Phi(n) ||
+ is_Perm(aenv, n) ||
+ (arch_register_req_is(&req, should_be_same) && req.other_same == irn)
+ )
return 1;
+ }
}
+
return 0;
}