foreach_out_edge(node, edge) {
ir_node *use = get_edge_src_irn(edge);
+ if(is_Anchor(use))
+ continue;
if(is_Phi(use)) {
int in = get_edge_src_pos(edge);
/* mode_T nodes define several values at once. Count them */
if(get_irn_mode(node) == mode_T) {
- ir_node *proj = sched_next(node);
+ const ir_edge_t *edge;
+
+ foreach_out_edge(node, edge) {
+ const ir_node *proj = get_edge_src_irn(edge);
- while(is_Proj(proj)) {
if(arch_irn_consider_in_reg_alloc(arch_env, cls, proj)) {
++additional_defines;
}
- proj = sched_next(proj);
}
}
if(bitset_is_set(spilled_nodes, get_irn_idx(node)))
return;
DBG((dbg, LEVEL_2, "\tspills needed after %+F: %d\n", node, spills_needed));
- candidates = malloc(node_count * sizeof(candidates[0]));
+ candidates = xmalloc(node_count * sizeof(candidates[0]));
/* construct array with spill candidates and calculate their costs */
i = 0;
/* spill cheapest ones */
cand_idx = 0;
while(spills_needed > 0) {
- if(cand_idx >= node_count) {
+ spill_candidate_t *candidate;
+ ir_node *cand_node;
+ int is_use;
+
+ if (cand_idx >= node_count) {
panic("can't spill enough values for node %+F\n", node);
}
- spill_candidate_t *candidate = &candidates[cand_idx];
- ir_node *cand_node = candidate->node;
- int is_use;
+
+ candidate = &candidates[cand_idx];
+ cand_node = candidate->node;
++cand_idx;
if(arch_irn_is(arch_env, cand_node, dont_spill))
/* make sure the node is not an argument of the instruction */
is_use = 0;
- for(i = 0; i < arity; ++i) {
+ for (i = 0; i < arity; ++i) {
ir_node *in = get_irn_n(node, i);
if(in == cand_node) {
is_use = 1;
* into the liveness set
*/
static
-void liveness_transfer(daemel_env_t *env, ir_node *node, ir_nodeset_t *nodeset)
+void liveness_transfer_remove_defs(daemel_env_t *env, ir_node *node,
+ ir_nodeset_t *nodeset)
{
- int i, arity;
const arch_register_class_t *cls = env->cls;
const arch_env_t *arch_env = env->arch_env;
- const bitset_t *bitset = env->spilled_nodes;
/* You should better break out of your loop when hitting the first phi
* function. */
assert(!is_Phi(node) && "liveness_transfer produces invalid results for phi nodes");
+ if (get_irn_mode(node) == mode_T) {
+ const ir_edge_t *edge;
+
+ foreach_out_edge(node, edge) {
+ const ir_node *proj = get_edge_src_irn(edge);
+
+ if (arch_irn_consider_in_reg_alloc(arch_env, cls, proj)) {
+ ir_nodeset_remove(nodeset, proj);
+ }
+ }
+ }
+
if(arch_irn_consider_in_reg_alloc(arch_env, cls, node)) {
ir_nodeset_remove(nodeset, node);
}
+}
+
+static void liveness_transfer_add_uses(daemel_env_t *env, ir_node *node,
+ ir_nodeset_t *nodeset)
+{
+ int i, arity;
+ const arch_register_class_t *cls = env->cls;
+ const arch_env_t *arch_env = env->arch_env;
+ const bitset_t *bitset = env->spilled_nodes;
+
arity = get_irn_arity(node);
for(i = 0; i < arity; ++i) {
ir_nodeset_iterator_t iter;
ir_node *node;
bitset_t *spilled_nodes = env->spilled_nodes;
- int phi_count;
+ int phi_count, spilled_phis, regpressure, phi_spills_needed;
DBG((dbg, LEVEL_1, "spilling block %+F\n", block));
ir_nodeset_init(&live_nodes);
- be_liveness_end_of_block_ir_nodeset(lv, arch_env, cls, block, &live_nodes);
+ be_liveness_end_of_block(lv, arch_env, cls, block, &live_nodes);
foreach_ir_nodeset(&live_nodes, node, iter) {
DBG((dbg, LEVEL_2, "\t%+F is live-end... ", node));
if(is_Phi(node))
break;
- if(is_Proj(node) || be_is_Keep(node)) {
- liveness_transfer(env, node, &live_nodes);
+ if(be_is_Keep(node)) {
+ /* remove defs should never do something for keep nodes, but we
+ * leave it here for consistency */
+ liveness_transfer_remove_defs(env, node, &live_nodes);
+ liveness_transfer_add_uses(env, node, &live_nodes);
continue;
}
+ liveness_transfer_remove_defs(env, node, &live_nodes);
do_spilling(env, &live_nodes, node);
- liveness_transfer(env, node, &live_nodes);
+ liveness_transfer_add_uses(env, node, &live_nodes);
}
phi_count = 0;
- int spilled_phis = 0;
+ spilled_phis = 0;
sched_foreach(block, node) {
if(!is_Phi(node))
break;
++spilled_phis;
}
}
- int regpressure = ir_nodeset_size(&live_nodes) + spilled_phis;
- int phi_spills_needed = regpressure - env->n_regs;
+ regpressure = ir_nodeset_size(&live_nodes) + spilled_phis;
+ phi_spills_needed = regpressure - env->n_regs;
DBG((dbg, LEVEL_3, "Regpressure before phis: %d phispills: %d\n",
regpressure, phi_spills_needed));
sched_foreach(block, node) {
if(n_regs == 0)
return;
- be_invalidate_liveness(birg);
- be_assure_liveness(birg);
+ be_liveness_assure_sets(be_assure_liveness(birg));
env.spill_env = be_new_spill_env(birg);
env.n_regs = n_regs;