aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaochen Gui <guihaoc@gcc.gnu.org>2024-06-24 13:12:51 +0800
committerHaochen Gui <guihaoc@gcc.gnu.org>2024-06-24 13:17:27 +0800
commitea8061f46a301797e7ba33b52e3b4713fb8e6b48 (patch)
tree5af1a6d1acda729a73aba45c730b5e04b1df28a7
parentd820db38870155d941ffcad5846389e0de059534 (diff)
downloadgcc-ea8061f46a301797e7ba33b52e3b4713fb8e6b48.zip
gcc-ea8061f46a301797e7ba33b52e3b4713fb8e6b48.tar.gz
gcc-ea8061f46a301797e7ba33b52e3b4713fb8e6b48.tar.bz2
fwprop: invoke change_is_worthwhile to judge if a replacement is worthwhile
gcc/ * fwprop.cc (try_fwprop_subst_pattern): Invoke change_is_worthwhile to judge if a replacement is worthwhile. Remove single_set check and add is_debug_insn check. * recog.cc (swap_change): Invalidate recog_data when the cached INSN is swapped out. * rtl-ssa/changes.cc (rtl_ssa::changes_are_worthwhile): Check if the insn cost of new rtl is unknown and fail the replacement.
-rw-r--r--gcc/fwprop.cc37
-rw-r--r--gcc/recog.cc6
-rw-r--r--gcc/rtl-ssa/changes.cc8
3 files changed, 27 insertions, 24 deletions
diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
index de54392..bfdc7a1 100644
--- a/gcc/fwprop.cc
+++ b/gcc/fwprop.cc
@@ -453,7 +453,7 @@ try_fwprop_subst_pattern (obstack_watermark &attempt, insn_change &use_change,
&& (prop.changed_mem_p ()
|| contains_mem_rtx_p (src)
|| use_insn->is_asm ()
- || !single_set (use_rtl)))
+ || use_insn->is_debug_insn ()))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "cannot propagate from insn %d into"
@@ -471,29 +471,20 @@ try_fwprop_subst_pattern (obstack_watermark &attempt, insn_change &use_change,
redo_changes (0);
}
- /* ??? In theory, it should be better to use insn costs rather than
- set_src_costs here. That would involve replacing this code with
- change_is_worthwhile. */
bool ok = recog (attempt, use_change);
- if (ok && !prop.changed_mem_p () && !use_insn->is_asm ())
- if (rtx use_set = single_set (use_rtl))
- {
- bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_rtl));
- temporarily_undo_changes (0);
- auto old_cost = set_src_cost (SET_SRC (use_set),
- GET_MODE (SET_DEST (use_set)), speed);
- redo_changes (0);
- auto new_cost = set_src_cost (SET_SRC (use_set),
- GET_MODE (SET_DEST (use_set)), speed);
- if (new_cost > old_cost
- || (new_cost == old_cost && !prop.likely_profitable_p ()))
- {
- if (dump_file)
- fprintf (dump_file, "change not profitable"
- " (cost %d -> cost %d)\n", old_cost, new_cost);
- ok = false;
- }
- }
+ if (ok
+ && !prop.changed_mem_p ()
+ && !use_insn->is_asm ()
+ && !use_insn->is_debug_insn ())
+ {
+ bool strict_p = !prop.likely_profitable_p ();
+ if (!change_is_worthwhile (use_change, strict_p))
+ {
+ if (dump_file)
+ fprintf (dump_file, "change not profitable");
+ ok = false;
+ }
+ }
if (!ok)
{
diff --git a/gcc/recog.cc b/gcc/recog.cc
index a6799e3..56370e4 100644
--- a/gcc/recog.cc
+++ b/gcc/recog.cc
@@ -614,7 +614,11 @@ swap_change (int num)
else
std::swap (*changes[num].loc, changes[num].old);
if (changes[num].object && !MEM_P (changes[num].object))
- std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
+ {
+ std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
+ if (recog_data.insn == changes[num].object)
+ recog_data.insn = nullptr;
+ }
}
/* Temporarily undo all the changes numbered NUM and up, with a view
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index 3101f2d..bc80d7d 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -190,6 +190,14 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
&& INSN_CODE (change->rtl ()) != NOOP_MOVE_INSN_CODE)
{
change->new_cost = insn_cost (change->rtl (), for_speed);
+ /* If the cost is unknown, replacement is not worthwhile. */
+ if (!change->new_cost)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Reject replacement due to unknown insn cost.\n");
+ return false;
+ }
new_cost += change->new_cost;
if (for_speed)
weighted_new_cost += (cfg_bb->count.to_sreal_scale (entry_count)