- /* spill all delayed phis which didn't make it into start workset */
- for ( ; i < ARR_LEN(delayed); ++i) {
- ir_node *irn = delayed[i].irn;
- if (irn && is_Phi(irn) && get_nodes_block(irn) == block) {
- DBG((dbg, DBG_START, " spilling delayed phi %+F\n", irn));
- be_spill_phi(env->senv, irn);
+ /* so far we only put nodes into the starters list that are used inside
+ * the loop. If register pressure in the loop is low then we can take some
+ * values and let them live through the loop */
+ DB((dbg, DBG_START, "Loop pressure %d, taking %d delayed vals\n",
+ pressure, free_slots));
+ if (free_slots > 0) {
+ size_t i;
+
+ qsort(delayed, ARR_LEN(delayed), sizeof(delayed[0]), loc_compare);
+
+ for (i = 0; i < ARR_LEN(delayed) && free_slots > 0; ++i) {
+ int p, arity;
+ loc_t *loc = & delayed[i];
+
+ if (!is_Phi(loc->node)) {
+ /* don't use values which are dead in a known predecessors
+ * to not induce unnecessary reloads */
+ arity = get_irn_arity(block);
+ for (p = 0; p < arity; ++p) {
+ ir_node *pred_block = get_Block_cfgpred_block(block, p);
+ block_info_t *pred_info = get_block_info(pred_block);
+
+ if (pred_info == NULL)
+ continue;
+
+ if (!workset_contains(pred_info->end_workset, loc->node)) {
+ DB((dbg, DBG_START,
+ " delayed %+F not live at pred %+F\n", loc->node,
+ pred_block));
+ goto skip_delayed;
+ }
+ }
+ }
+
+ DB((dbg, DBG_START, " delayed %+F taken\n", loc->node));
+ ARR_APP1(loc_t, starters, *loc);
+ loc->node = NULL;
+ --free_slots;
+ skip_delayed:
+ ;