Message ID | bf333060-92d2-48e7-ab6b-0e56d9e868ec@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | [PATCH-1v4] fwprop: Replace rtx_cost with insn_cost in try_fwprop_subst_pattern [PR113325] | expand |
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
HAO CHEN GUI <guihaoc@linux.ibm.com> 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
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<insn_change *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)