}
}
-static void handle_phi_prefs(ir_node *phi)
+/**
+ * Set preferences for a phis register based on the registers used on the
+ * phi inputs.
+ */
+static void adapt_phi_prefs(ir_node *phi)
{
int i;
int arity = get_irn_arity(phi);
}
}
+/**
+ * After a phi has been assigned a register propagate preference inputs
+ * to the phi inputs.
+ */
+static void propagate_phi_register(ir_node *phi)
+{
+ int i;
+ ir_node *block = get_nodes_block(phi);
+ int arity = get_irn_arity(phi);
+ const arch_register_t *reg = arch_get_irn_register(phi);
+ unsigned r = arch_register_get_index(reg);
+
+ for (i = 0; i < arity; ++i) {
+ ir_node *op = get_Phi_pred(phi, i);
+ allocation_info_t *info = get_allocation_info(op);
+ ir_node *pred;
+ float weight;
+
+ /* already a register assigned? then we can't influence it anyway */
+ /* TODO: what about splits which we might still do... */
+ if (arch_get_irn_register(op) != NULL)
+ continue;
+
+ pred = get_Block_cfgpred_block(block, i);
+ weight = get_block_execfreq(execfreqs, pred);
+
+ /* promote the prefered register */
+ info->prefs[r] += AFF_PHI * weight;
+ }
+}
+
/**
* Walker: assign registers to all nodes of a block that
* need registers from the currently considered register class.
if (reg != NULL) {
use_reg(node, reg);
} else {
- /* TODO: give boni for registers already assigned at the
- predecessors */
- handle_phi_prefs(node);
+ adapt_phi_prefs(node);
assign_reg(block, node);
+ propagate_phi_register(node);
}
}
start = node;
continue;
assign_reg(block, node);
+ /* shouldn't happen if we color in dominance order */
+ assert (!is_Phi(node));
+#if 0
+ if (is_Phi(node))
+ propagate_phi_register(node);
+#endif
}
/* assign instructions in the block */