===================================================================
@@ -2068,7 +2068,11 @@ process_alt_operands (int only_alternati
no_subreg_reg_operand[1])
|| (targetm.preferred_reload_class
(no_subreg_reg_operand[1],
- (enum reg_class) curr_alt[1]) != NO_REGS)))))
+ (enum reg_class) curr_alt[1]) != NO_REGS))
+ /* If it is a result of recent elimination in move
+ insn we can transform it into an add still by
+ using this alternative. */
+ && GET_CODE (no_subreg_reg_operand[1]) != PLUS)))
/* We have a move insn and a new reload insn will be similar
to the current insn. We should avoid such situation as it
results in LRA cycling. */
@@ -2444,6 +2448,15 @@ process_address (int nop, rtx *before, r
&& process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS))
change_p = true;
+#ifdef EXTRA_CONSTRAINT_STR
+ /* Target hooks sometimes reject extra constraint addresses -- use
+ EXTRA_CONSTRAINT_STR for the validation. */
+ if (constraint[0] != 'p'
+ && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)
+ && EXTRA_CONSTRAINT_STR (op, constraint[0], constraint))
+ return change_p;
+#endif
+
/* There are three cases where the shape of *AD.INNER may now be invalid:
1) the original address was valid, but either elimination or
===================================================================
@@ -977,6 +977,9 @@ eliminate_regs_in_insn (rtx insn, bool r
}
}
+ if (! validate_p)
+ return;
+
/* Substitute the operands; the new values are in the substed_operand
array. */
for (i = 0; i < static_id->n_operands; i++)
@@ -984,16 +987,13 @@ eliminate_regs_in_insn (rtx insn, bool r
for (i = 0; i < static_id->n_dups; i++)
*id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]];
- if (validate_p)
- {
- /* If we had a move insn but now we don't, re-recognize it.
- This will cause spurious re-recognition if the old move had a
- PARALLEL since the new one still will, but we can't call
- single_set without having put new body into the insn and the
- re-recognition won't hurt in this rare case. */
- id = lra_update_insn_recog_data (insn);
- static_id = id->insn_static_data;
- }
+ /* If we had a move insn but now we don't, re-recognize it.
+ This will cause spurious re-recognition if the old move had a
+ PARALLEL since the new one still will, but we can't call
+ single_set without having put new body into the insn and the
+ re-recognition won't hurt in this rare case. */
+ id = lra_update_insn_recog_data (insn);
+ static_id = id->insn_static_data;
}
/* Spill pseudos which are assigned to hard registers in SET. Add
===================================================================
@@ -644,10 +644,12 @@ lra_final_code_change (void)
}
lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+ struct lra_static_insn_data *static_id = id->insn_static_data;
bool insn_change_p = false;
for (i = id->insn_static_data->n_operands - 1; i >= 0; i--)
- if (alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
+ if ((DEBUG_INSN_P (insn) || ! static_id->operand[i].is_operator)
+ && alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
{
lra_update_dup (id, i);
insn_change_p = true;