@@ -4852,6 +4852,9 @@ rs6000_option_override_internal (bool global_init_p)
ap = __builtin_next_arg (0). */
if (DEFAULT_ABI != ABI_V4)
targetm.expand_builtin_va_start = NULL;
+
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ param_ira_consider_dup_in_all_alts, 1);
}
rs6000_override_options_after_change ();
@@ -1937,10 +1939,16 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
return -1;
str = recog_data.constraints[op_num];
use_commut_op_p = false;
+
+ rtx op = recog_data.operand[op_num];
+ int op_no = reg_or_subregno (op);
+ enum reg_class op_pref_cl = reg_preferred_class (op_no);
+ machine_mode op_mode = GET_MODE (op);
+
for (;;)
{
- rtx op = recog_data.operand[op_num];
-
+ bool saw_reg_cstr = false;
+
for (curr_alt = 0, ignore_p = !TEST_BIT (alts, curr_alt),
original = -1;;)
{
@@ -1963,9 +1971,25 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
{
enum constraint_num cn = lookup_constraint (str);
enum reg_class cl = reg_class_for_constraint (cn);
- if (cl != NO_REGS
- && !targetm.class_likely_spilled_p (cl))
- goto fail;
+ if (cl != NO_REGS && !targetm.class_likely_spilled_p (cl))
+ {
+ if (param_ira_consider_dup_in_all_alts
+ && op_pref_cl != NO_REGS)
+ {
+ /* If it's free to move from one preferred class to
+ the one without matching constraint, it doesn't
+ have to respect this constraint with costs. */
+ if (cl != op_pref_cl
+ && (ira_reg_class_intersect[cl][op_pref_cl]
+ != NO_REGS)
+ && (ira_may_move_in_cost[op_mode][op_pref_cl][cl]
+ == 0))
+ goto fail;
+ saw_reg_cstr = true;
+ }
+ else
+ goto fail;
+ }
if (constraint_satisfied_p (op, cn))
goto fail;
break;
@@ -1979,7 +2003,40 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
str = end;
if (original != -1 && original != n)
goto fail;
- original = n;
+ if (param_ira_consider_dup_in_all_alts && saw_reg_cstr)
+ {
+ rtx out = recog_data.operand[n];
+ if (!REG_P (out)
+ && (GET_CODE (out) != SUBREG
+ || !REG_P (SUBREG_REG (out))))
+ goto fail;
+ int out_no = reg_or_subregno (out);
+ if (out_no >= FIRST_PSEUDO_REGISTER)
+ {
+ const char *out_alts = recog_data.constraints[n];
+ int tot = curr_alt;
+ while (tot > 0)
+ {
+ if (out_alts[0] == ',')
+ tot--;
+ out_alts++;
+ }
+ enum reg_class out_cl = NO_REGS;
+ while (*out_alts != '\0' && *out_alts != ',')
+ {
+ enum constraint_num cn
+ = lookup_constraint (out_alts);
+ out_cl = reg_class_for_constraint (cn);
+ if (out_cl != NO_REGS)
+ break;
+ }
+ /* Respect this as it's for preferred rclass. */
+ if (out_cl == op_pref_cl)
+ original = n;
+ }
+ }
+ else
+ original = n;
continue;
}
}
@@ -326,6 +326,10 @@ Max size of conflict table in MB.
Common Joined UInteger Var(param_ira_max_loops_num) Init(100) Param Optimization
Max loops number for regional RA.
+-param=ira-consider-dup-in-all-alts=
+Common Joined UInteger Var(param_ira_consider_dup_in_all_alts) Init(0) IntegerRange(0, 1) Param Optimization
+Control ira to continue to find matching constraint (duplicated operand number) even if it has encountered some contraint that has the appropriate register class, it will skip those alternatives whose constraint don't have the same register class as which the operand prefers.
+
-param=iv-always-prune-cand-set-bound=
Common Joined UInteger Var(param_iv_always_prune_cand_set_bound) Init(10) Param Optimization
If number of candidates in the set is smaller, we always try to remove unused ivs during its optimization.