* beginning of a loop. We try to reload as much values as possible now so they
* don't get reloaded inside the loop.
*/
-static void compute_live_ins(const ir_node *block)
+static void decide_start_workset(const ir_node *block)
{
ir_loop *loop = get_irn_loop(block);
ir_node *first;
int free_slots, free_pressure_slots;
unsigned pressure;
int arity;
- int n_pred_worksets;
workset_t **pred_worksets;
/* Collect all values living at start of block */
* is no backedge) where the value is reloaded then we must set it to
* reloaded here. We place spills in all pred where the value was not yet
* reloaded to be sure we have a spill on each path */
- n_pred_worksets = 0;
arity = get_irn_arity(block);
pred_worksets = alloca(sizeof(pred_worksets[0]) * arity);
for(i = 0; i < arity; ++i) {
ir_node *pred_block = get_Block_cfgpred_block(block, i);
block_info_t *pred_info = get_block_info(pred_block);
- if(pred_info == NULL)
- continue;
- pred_worksets[n_pred_worksets] = pred_info->end_workset;
- ++n_pred_worksets;
+ if(pred_info == NULL)
+ pred_worksets[i] = NULL;
+ else
+ pred_worksets[i] = pred_info->end_workset;
}
for(i = 0; i < ws_count; ++i) {
loc_t *loc = &ws->vals[i];
ir_node *value = loc->node;
- bool spilled = true;
+ bool spilled;
int n;
/* phis from this block aren't spilled */
continue;
}
- /* set status to spilled if node was spilled on all predecessors */
- for(n = 0; n < n_pred_worksets; ++n) {
+ /* determine if value was spilled on any predecessor */
+ spilled = false;
+ for(n = 0; n < arity; ++n) {
workset_t *pred_workset = pred_worksets[n];
- int p_len = workset_get_length(pred_workset);
+ int p_len;
int p;
+ if (pred_workset == NULL)
+ continue;
+
+ p_len = workset_get_length(pred_workset);
for(p = 0; p < p_len; ++p) {
loc_t *l = &pred_workset->vals[p];
if (l->node != value)
continue;
- if (!l->spilled) {
- spilled = false;
+ if (l->spilled) {
+ spilled = true;
+ goto determined_spill;
+ }
+ break;
+ }
+ if (p >= p_len) {
+ spilled = true;
+ goto determined_spill;
+ }
+ }
+
+determined_spill:
+ if (spilled) {
+ for (n = 0; n < arity; ++n) {
+ workset_t *pred_workset = pred_worksets[n];
+ int p_len;
+ int p;
+
+ if (pred_workset == NULL)
+ continue;
+
+ p_len = workset_get_length(pred_workset);
+ for (p = 0; p < p_len; ++p) {
+ loc_t *l = &pred_workset->vals[p];
+
+ if (l->node != value)
+ continue;
+
+ if (!l->spilled) {
+ ir_node *pred_block = get_Block_cfgpred_block(block, n);
+ ir_node *insert_point
+ = be_get_end_of_block_insertion_point(pred_block);
+ DB((dbg, DBG_SPILL, "Spill %+F before %+F\n", node,
+ insert_point));
+ be_add_spill(senv, value, insert_point);
+ }
break;
}
}
/* we need 2 heuristics here, for the case when all predecessor blocks
* are known and when some are backedges (and therefore can't be known
* yet) */
- compute_live_ins(block);
+ decide_start_workset(block);
}
DB((dbg, DBG_DECIDE, "\n"));