From: Kyrylo Tkachov <[email protected]>
Every branchless noce_try_* matcher ends with the same tail: wind up the
candidate sequence with end_ifcvt_sequence, reject it when it fails to
build (and, for most, when the target deems it unprofitable), otherwise
emit it before the branch, record the transform name and return true. This
block is copy-pasted, with small whitespace drift, in more than a dozen
matchers.
Introduce noce_commit_sequence to hold it and route the uniform matchers
through it. A caller now ends with:
seq = end_ifcvt_sequence (if_info);
return noce_commit_sequence (if_info, seq, PROFITABLE, "noce_try_foo");
The PROFITABLE argument preserves each matcher exactly: the ones that never
consulted targetm.noce_conversion_profitable_p pass false. No functional
change.
noce_try_move and noce_try_bitop emit their sequence conditionally, and
noce_try_minmax and noce_try_abs write extra if_info fields in the tail, so
those keep their own tails.
gcc/ChangeLog:
* ifcvt.cc (noce_commit_sequence): New function.
(noce_try_ifelse_collapse, noce_try_store_flag,
noce_try_sign_bit_splat, noce_try_inverse_constants,
noce_try_shifted_store_flag, noce_try_store_flag_constants,
noce_try_store_flag_logical, noce_try_addcc,
noce_try_store_flag_mask, noce_try_cmove, noce_try_cmove_arith,
noce_try_cond_arith, noce_try_sign_mask): Use it.
Signed-off-by: Kyrylo Tkachov <[email protected]>
---
gcc/ifcvt.cc | 157 +++++++++++++++------------------------------------
1 file changed, 45 insertions(+), 112 deletions(-)
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 3d7054314b9..f0dcc13f786 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -1309,6 +1309,27 @@ noce_simple_bbs (struct noce_if_info *if_info)
return true;
}
+/* Commit the wound-up candidate SEQ produced by a noce transform for IF_INFO.
+ Reject it (returning false, emitting nothing) if it failed to build, or if
+ CHECK_PROFITABLE and the target deems it not worthwhile. Otherwise emit it
+ before the branch, record NAME as the winning transform and return true.
+ This is the shared tail of the noce_try_* matchers. */
+
+static bool
+noce_commit_sequence (noce_if_info *if_info, rtx_insn *seq,
+ bool check_profitable, const char *name)
+{
+ if (!seq
+ || (check_profitable
+ && !targetm.noce_conversion_profitable_p (seq, if_info)))
+ return false;
+
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATION (if_info->insn_a));
+ if_info->transform_name = name;
+ return true;
+}
+
/* Convert "if (a != b) x = a; else x = b" into "x = a" and
"if (a == b) x = a; else x = b" into "x = b". */
@@ -1552,14 +1573,7 @@ noce_try_sign_bit_splat (struct noce_if_info *if_info)
/* This ends the sequence and tests the cost model. */
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- /* Everything looks good. Install the if-converted sequence. */
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "splat_sign_bit_trivial";
- return true;
+ return noce_commit_sequence (if_info, seq, true, "splat_sign_bit_trivial");
fail:
end_ifcvt_sequence (if_info);
@@ -1589,14 +1603,7 @@ noce_try_ifelse_collapse (struct noce_if_info * if_info)
start_sequence ();
noce_emit_move_insn (if_info->x, if_then_else);
seq = end_ifcvt_sequence (if_info);
- if (!seq)
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
-
- if_info->transform_name = "noce_try_ifelse_collapse";
- return true;
+ return noce_commit_sequence (if_info, seq, false,
"noce_try_ifelse_collapse");
}
@@ -1636,13 +1643,7 @@ noce_try_store_flag (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (! seq)
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_store_flag";
- return true;
+ return noce_commit_sequence (if_info, seq, false, "noce_try_store_flag");
}
else
{
@@ -1714,14 +1715,8 @@ noce_try_inverse_constants (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
-
- if (!seq)
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_inverse_constants";
- return true;
+ return noce_commit_sequence (if_info, seq, false,
+ "noce_try_inverse_constants");
}
end_sequence ();
@@ -1856,14 +1851,8 @@ noce_try_shifted_store_flag (struct noce_if_info
*if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_shifted_store_flag";
-
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_shifted_store_flag");
}
@@ -2073,14 +2062,8 @@ noce_try_store_flag_constants (struct noce_if_info
*if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_store_flag_constants";
-
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_store_flag_constants");
}
return false;
@@ -2146,13 +2129,8 @@ noce_try_store_flag_logical (struct noce_if_info
*if_info)
/* We've generated all the RTL, make sure it recognizes and is
profitable. */
rtx_insn *seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_store_flag_logical";
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_store_flag_logical");
}
/* Convert "if (test) foo++" into "foo += (test != 0)", and
@@ -2204,14 +2182,8 @@ noce_try_addcc (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_addcc";
-
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_addcc");
}
end_sequence ();
}
@@ -2246,13 +2218,8 @@ noce_try_addcc (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_addcc";
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_addcc");
}
end_sequence ();
}
@@ -2297,14 +2264,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_store_flag_mask";
-
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_store_flag_mask");
}
end_sequence ();
@@ -2466,14 +2427,7 @@ noce_try_cmove (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_cmove";
-
- return true;
+ return noce_commit_sequence (if_info, seq, true, "noce_try_cmove");
}
/* If both a and b are constants try a last-ditch transformation:
if (test) x = a; else x = b;
@@ -2519,13 +2473,8 @@ noce_try_cmove (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_cmove";
- return true;
+ return noce_commit_sequence (if_info, seq, true,
+ "noce_try_cmove");
}
else
{
@@ -2962,13 +2911,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
noce_emit_move_insn (x, target);
ifcvt_seq = end_ifcvt_sequence (if_info);
- if (!ifcvt_seq || !targetm.noce_conversion_profitable_p (ifcvt_seq, if_info))
- return false;
-
- emit_insn_before_setloc (ifcvt_seq, if_info->jump,
- INSN_LOCATION (if_info->insn_a));
- if_info->transform_name = "noce_try_cmove_arith";
- return true;
+ return noce_commit_sequence (if_info, ifcvt_seq, true,
+ "noce_try_cmove_arith");
end_seq_and_fail:
end_sequence ();
@@ -3475,13 +3419,7 @@ noce_try_sign_mask (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, t);
seq = end_ifcvt_sequence (if_info);
- if (!seq)
- return false;
-
- emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
- if_info->transform_name = "noce_try_sign_mask";
-
- return true;
+ return noce_commit_sequence (if_info, seq, false, "noce_try_sign_mask");
}
/* Return the arithmetic operation in X, looking through an extension. */
@@ -3753,12 +3691,7 @@ success:
noce_emit_move_insn (if_info->x, target);
seq = end_ifcvt_sequence (if_info);
- if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
- goto fail;
-
- emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
- if_info->transform_name = "noce_try_cond_arith";
- return true;
+ return noce_commit_sequence (if_info, seq, true, "noce_try_cond_arith");
end_seq_n_fail:
end_sequence ();
--
2.50.1 (Apple Git-155)