aboutsummaryrefslogtreecommitdiff
path: root/gcc/fwprop.cc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2024-11-19 10:19:24 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2024-11-19 10:19:24 +0000
commit387dba05e4207fc3f9a2f2bcb09a343a999c76fc (patch)
tree6c93e63c5d1f6e48066ffbe8a0cf652b3114689e /gcc/fwprop.cc
parent694613a7f9adfa9c87e733adc63839c8801f2b5c (diff)
downloadgcc-387dba05e4207fc3f9a2f2bcb09a343a999c76fc.zip
gcc-387dba05e4207fc3f9a2f2bcb09a343a999c76fc.tar.gz
gcc-387dba05e4207fc3f9a2f2bcb09a343a999c76fc.tar.bz2
Avoid repeated calls to temporarily_undo_changes [PR117297]
In an attempt to reduce compile time, rtl-ssa computes the cost of existing instructions lazily rather than eagerly. However, this means that it might need to calculate the cost of an existing instruction while a change group is already in progress for the instruction. rtl_ssa::insn_info::calculate_cost therefore temporarily undoes any in-progress changes in order to get back the original pattern and insn code. rtl-ssa's main use of insn costs is in rtl_ssa::changes_are_worthwhile, which calculates the cost of a change involving an arbitrary number of instructions. Summing up the original cost of N instructions while those N instructions have in-progress changes could lead to O(N*N) rtl changes, since each lazy calculation might have to temporarily undo the changes to all N instructions. We can avoid that by converting the current temporarily_undo_changes/ redo_changes pair into an RAII class and extending it to allow nested uses. rtl_ssa::changes_are_worthwhile can then undo the in-progress changes once, before computing the original cost of all the instructions. gcc/ PR rtl-optimization/117297 * recog.h (temporarily_undo_changes, redo_changes): Delete in favor of... (undo_recog_changes): ...this new RAII class. * fwprop.cc (should_replace_address): Update accordingly. (fwprop_propagation::check_mem): Likewise. (try_fwprop_subst_note): Likewise. (try_fwprop_subst_pattern): Likewise. * rtl-ssa/insns.cc (insn_info::calculate_cost): Likewise. * rtl-ssa/changes.cc (rtl_ssa::changes_are_worthwhile): Temporarily undo all in-progress changes while computing the cost of the original sequence. * recog.cc (temporarily_undone_changes): Replace with... (undo_recog_changes::s_num_changes): ...this static member variable. (validate_change_1): Update check accordingly. (confirm_change_group): Likewise. (num_validated_changes): Likewise. (temporarily_undo_changes): Replace with... (undo_recog_changes::undo_recog_changes): ...this constructor. (redo_changes): Replace with... (undo_recog_changes::~undo_recog_changes): ...this destructor.
Diffstat (limited to 'gcc/fwprop.cc')
-rw-r--r--gcc/fwprop.cc30
1 files changed, 16 insertions, 14 deletions
diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
index 8cba6b7..5ddefdf 100644
--- a/gcc/fwprop.cc
+++ b/gcc/fwprop.cc
@@ -146,10 +146,11 @@ should_replace_address (int old_num_changes, rtx mem, rtx_insn *insn)
/* Prefer the new address if it is less expensive. */
bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
- temporarily_undo_changes (old_num_changes);
- gain = address_cost (XEXP (mem, 0), GET_MODE (mem),
- MEM_ADDR_SPACE (mem), speed);
- redo_changes (old_num_changes);
+ {
+ undo_recog_changes undo (old_num_changes);
+ gain = address_cost (XEXP (mem, 0), GET_MODE (mem),
+ MEM_ADDR_SPACE (mem), speed);
+ }
gain -= address_cost (XEXP (mem, 0), GET_MODE (mem),
MEM_ADDR_SPACE (mem), speed);
@@ -160,9 +161,8 @@ should_replace_address (int old_num_changes, rtx mem, rtx_insn *insn)
if (gain == 0)
{
gain = set_src_cost (XEXP (mem, 0), VOIDmode, speed);
- temporarily_undo_changes (old_num_changes);
+ undo_recog_changes undo (old_num_changes);
gain -= set_src_cost (XEXP (mem, 0), VOIDmode, speed);
- redo_changes (old_num_changes);
}
return (gain > 0);
@@ -220,9 +220,11 @@ fwprop_propagation::check_mem (int old_num_changes, rtx mem)
return false;
}
- temporarily_undo_changes (old_num_changes);
- bool can_simplify = can_simplify_addr (XEXP (mem, 0));
- redo_changes (old_num_changes);
+ bool can_simplify = [&]()
+ {
+ undo_recog_changes undo (old_num_changes);
+ return can_simplify_addr (XEXP (mem, 0));
+ } ();
if (!can_simplify)
{
failure_reason = "would replace a frame address";
@@ -414,9 +416,10 @@ try_fwprop_subst_note (insn_info *use_insn, set_info *def,
{
fprintf (dump_file, "\nin notes of insn %d, replacing:\n ",
INSN_UID (use_rtl));
- temporarily_undo_changes (0);
- print_inline_rtx (dump_file, note, 2);
- redo_changes (0);
+ {
+ undo_recog_changes undo (0);
+ print_inline_rtx (dump_file, note, 2);
+ }
fprintf (dump_file, "\n with:\n ");
print_inline_rtx (dump_file, note, 2);
fprintf (dump_file, "\n");
@@ -468,9 +471,8 @@ try_fwprop_subst_pattern (obstack_watermark &attempt, insn_change &use_change,
{
fprintf (dump_file, "\npropagating insn %d into insn %d, replacing:\n",
def_insn->uid (), use_insn->uid ());
- temporarily_undo_changes (0);
+ undo_recog_changes undo (0);
print_rtl_single (dump_file, PATTERN (use_rtl));
- redo_changes (0);
}
bool ok = recog (attempt, use_change);