aboutsummaryrefslogtreecommitdiff
path: root/gcc/fwprop.c
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2021-01-15 00:14:56 +0100
committerIlya Leoshkevich <iii@linux.ibm.com>2021-01-21 22:48:47 +0100
commitefb6bc55a93a1b8a719e0dab344c0a21344a67a9 (patch)
tree2dfe597bcf21dafb47d0ea95e64e812f4e74c4e9 /gcc/fwprop.c
parentf645da0e4ab9438dfd0c047c710c7ec6a7d6d8f3 (diff)
downloadgcc-efb6bc55a93a1b8a719e0dab344c0a21344a67a9.zip
gcc-efb6bc55a93a1b8a719e0dab344c0a21344a67a9.tar.gz
gcc-efb6bc55a93a1b8a719e0dab344c0a21344a67a9.tar.bz2
fwprop: Allow (subreg (mem)) simplifications
Suppose we have: (set (reg/v:TF 63) (mem/c:TF (reg/v:DI 62))) (set (reg:FPRX2 66) (subreg:FPRX2 (reg/v:TF 63) 0)) It is clearly profitable to propagate the first insn into the second one and get: (set (reg:FPRX2 66) (mem/c:FPRX2 (reg/v:DI 62))) fwprop actually manages to perform this, but doesn't think the result is worth it, which results in unnecessary store/load sequences on s390. Improve the situation by classifying SUBREG -> MEM changes as profitable. gcc/ChangeLog: 2021-01-15 Ilya Leoshkevich <iii@linux.ibm.com> * fwprop.c (fwprop_propagation::classify_result): Allow (subreg (mem)) simplifications.
Diffstat (limited to 'gcc/fwprop.c')
-rw-r--r--gcc/fwprop.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index eff8f7c..123cc22 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -176,7 +176,7 @@ namespace
static const uint16_t CONSTANT = FIRST_SPARE_RESULT << 1;
static const uint16_t PROFITABLE = FIRST_SPARE_RESULT << 2;
- fwprop_propagation (rtx_insn *, rtx, rtx);
+ fwprop_propagation (insn_info *, insn_info *, rtx, rtx);
bool changed_mem_p () const { return result_flags & CHANGED_MEM; }
bool folded_to_constants_p () const;
@@ -185,13 +185,20 @@ namespace
bool check_mem (int, rtx) final override;
void note_simplification (int, uint16_t, rtx, rtx) final override;
uint16_t classify_result (rtx, rtx);
+
+ private:
+ const bool single_use_p;
+ const bool single_ebb_p;
};
}
/* Prepare to replace FROM with TO in INSN. */
-fwprop_propagation::fwprop_propagation (rtx_insn *insn, rtx from, rtx to)
- : insn_propagation (insn, from, to)
+fwprop_propagation::fwprop_propagation (insn_info *use_insn,
+ insn_info *def_insn, rtx from, rtx to)
+ : insn_propagation (use_insn->rtl (), from, to),
+ single_use_p (def_insn->num_uses () == 1),
+ single_ebb_p (use_insn->ebb () == def_insn->ebb ())
{
should_check_mems = true;
should_note_simplifications = true;
@@ -262,6 +269,22 @@ fwprop_propagation::classify_result (rtx old_rtx, rtx new_rtx)
&& GET_MODE (new_rtx) == GET_MODE_INNER (GET_MODE (from)))
return PROFITABLE;
+ /* Allow (subreg (mem)) -> (mem) simplifications with the following
+ exceptions:
+ 1) Propagating (mem)s into multiple uses is not profitable.
+ 2) Propagating (mem)s across EBBs may not be profitable if the source EBB
+ runs less frequently.
+ 3) Propagating (mem)s into paradoxical (subreg)s is not profitable.
+ 4) Creating new (mem/v)s is not correct, since DCE will not remove the old
+ ones. */
+ if (single_use_p
+ && single_ebb_p
+ && SUBREG_P (old_rtx)
+ && !paradoxical_subreg_p (old_rtx)
+ && MEM_P (new_rtx)
+ && !MEM_VOLATILE_P (new_rtx))
+ return PROFITABLE;
+
return 0;
}
@@ -363,7 +386,7 @@ try_fwprop_subst_note (insn_info *use_insn, insn_info *def_insn,
rtx_insn *use_rtl = use_insn->rtl ();
insn_change_watermark watermark;
- fwprop_propagation prop (use_rtl, dest, src);
+ fwprop_propagation prop (use_insn, def_insn, dest, src);
if (!prop.apply_to_rvalue (&XEXP (note, 0)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -426,7 +449,7 @@ try_fwprop_subst_pattern (obstack_watermark &attempt, insn_change &use_change,
rtx_insn *use_rtl = use_insn->rtl ();
insn_change_watermark watermark;
- fwprop_propagation prop (use_rtl, dest, src);
+ fwprop_propagation prop (use_insn, def_insn, dest, src);
if (!prop.apply_to_pattern (loc))
{
if (dump_file && (dump_flags & TDF_DETAILS))