Re: [PATCH-1v4] fwprop: Replace rtx_cost with insn_cost in try_fwprop_subst_pattern [PR113325]

2024-06-18 Thread Richard Sandiford
HAO CHEN GUI  writes:
> Hi Richard,
>
> 在 2024/6/17 17:04, Richard Sandiford 写道:
>> I don't think we should keep the single_set condition after this change.
>> insn_cost can handle all instructions.
>
> Just tested with removing single_set condition. It causes some regressions.
> If the new_rtl is a debug insn, it still can do the replacement as it can
> be recog and it's not a single_set rtl. After removing single_set condition,
> the "ok" (recog) will be reset to false in the "if" block as the cost of
> debug insn is unknown. So the replacement won't be done.
>
>   bool ok = recog (attempt, use_change);
>   if (ok && !prop.changed_mem_p () && !use_insn->is_asm ())
> {
>   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)
> {
>   /* The pattern didn't match, but if all uses of SRC folded to
>  constants, we can add a REG_EQUAL note for the result, if there
>  isn't one already.  */
>   if (!prop.folded_to_constants_p ())

We shouldn't be trying to cost changes to debug insns, so I think
the extra condition should be !use_insn->is_debug_insn ().

Thanks,
Richard



Re: [PATCH-1v4] fwprop: Replace rtx_cost with insn_cost in try_fwprop_subst_pattern [PR113325]

2024-06-18 Thread HAO CHEN GUI
Hi Richard,

在 2024/6/17 17:04, Richard Sandiford 写道:
> I don't think we should keep the single_set condition after this change.
> insn_cost can handle all instructions.

Just tested with removing single_set condition. It causes some regressions.
If the new_rtl is a debug insn, it still can do the replacement as it can
be recog and it's not a single_set rtl. After removing single_set condition,
the "ok" (recog) will be reset to false in the "if" block as the cost of
debug insn is unknown. So the replacement won't be done.

  bool ok = recog (attempt, use_change);
  if (ok && !prop.changed_mem_p () && !use_insn->is_asm ())
{
  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)
{
  /* The pattern didn't match, but if all uses of SRC folded to
 constants, we can add a REG_EQUAL note for the result, if there
 isn't one already.  */
  if (!prop.folded_to_constants_p ())

  Looking forwarding to your advice.

Thanks
Gui Haochen


[PATCH-1v4] fwprop: Replace rtx_cost with insn_cost in try_fwprop_subst_pattern [PR113325]

2024-06-17 Thread HAO CHEN GUI
Hi,
  This patch replaces rtx_cost with insn_cost in forward propagation.
In the PR, one constant vector should be propagated and replace a
pseudo in a store insn if we know it's a duplicated constant vector.
It reduces the insn cost but not rtx cost. In this case, the cost is
determined by destination operand (memory or pseudo). Unfortunately,
rtx cost can't help.

  The test case is added in the second rs6000 specific patch.

  Compared to previous version, the main changes are:
1. Invalidate recog_data when the cached INSN is swapped out.
2. Pass strict_p according to prop.likely_profitable_p () to
change_is_worthwhile.

Previous version
https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654276.html


  The patch causes a regression cases on i386 as the pattern cost
regulation has a bug. Please refer the patch and discussion here.
https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651363.html

  Bootstrapped and tested on powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?

ChangeLog
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.
* 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.

patch.diff
diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
index de543923b92..4a9f68b66b1 100644
--- a/gcc/fwprop.cc
+++ b/gcc/fwprop.cc
@@ -471,29 +471,18 @@ 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 ()
+  && single_set (use_rtl))
+{
+  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 a6799e3f5e6..56370e40e01 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 11639e81bb7..c5ac4956a19 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -186,6 +186,14 @@ rtl_ssa::changes_are_worthwhile (array_slice changes,
   if (!change->is_deletion ())
{
  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)



Re: [PATCH-1v4] fwprop: Replace rtx_cost with insn_cost in try_fwprop_subst_pattern [PR113325]

2024-06-17 Thread Richard Sandiford
HAO CHEN GUI  writes:
> Hi,
>   This patch replaces rtx_cost with insn_cost in forward propagation.
> In the PR, one constant vector should be propagated and replace a
> pseudo in a store insn if we know it's a duplicated constant vector.
> It reduces the insn cost but not rtx cost. In this case, the cost is
> determined by destination operand (memory or pseudo). Unfortunately,
> rtx cost can't help.
>
>   The test case is added in the second rs6000 specific patch.
>
>   Compared to previous version, the main changes are:
> 1. Invalidate recog_data when the cached INSN is swapped out.
> 2. Pass strict_p according to prop.likely_profitable_p () to
> change_is_worthwhile.
>
> Previous version
> https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654276.html
>
>
>   The patch causes a regression cases on i386 as the pattern cost
> regulation has a bug. Please refer the patch and discussion here.
> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651363.html
>
>   Bootstrapped and tested on powerpc64-linux BE and LE with no
> regressions. Is it OK for the trunk?
>
> ChangeLog
> 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.
>   * 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.
>
> patch.diff
> diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
> index de543923b92..4a9f68b66b1 100644
> --- a/gcc/fwprop.cc
> +++ b/gcc/fwprop.cc
> @@ -471,29 +471,18 @@ 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 ()
> +  && single_set (use_rtl))

I don't think we should keep the single_set condition after this change.
insn_cost can handle all instructions.

OK for trunk with that removed.

Thanks,
Richard

> +{
> +  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 a6799e3f5e6..56370e40e01 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 11639e81bb7..c5ac4956a19 100644
> --- a/gcc/rtl-ssa/changes.cc
> +++ b/gcc/rtl-ssa/changes.cc
> @@ -186,6 +186,14 @@ rtl_ssa::changes_are_worthwhile (array_slice *const> changes,
>if (!change->is_deletion ())
>   {
> 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)