aboutsummaryrefslogtreecommitdiff
path: root/gcc/df-core.cc
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2022-05-18 13:00:47 -0700
committerH.J. Lu <hjl.tools@gmail.com>2022-06-01 14:23:26 -0700
commita743a72714fc4a9d7036d28d0cacdf2a3621f629 (patch)
tree4a2da93e3ac20ae6f5be420e5792cc84a6f2f3ad /gcc/df-core.cc
parente2e471d83d16449a325315c0f33dc52b90ce0fac (diff)
downloadgcc-a743a72714fc4a9d7036d28d0cacdf2a3621f629.zip
gcc-a743a72714fc4a9d7036d28d0cacdf2a3621f629.tar.gz
gcc-a743a72714fc4a9d7036d28d0cacdf2a3621f629.tar.bz2
DSE: Use the constant store source if possible
RTL DSE tracks redundant constant stores within a basic block. When RTL loop invariant motion hoists a constant initialization out of the loop into a separate basic block, the constant store value becomes unknown within the original basic block. When recording store for RTL DSE, check if the source register is set only once to a constant by a non-partial unconditional load. If yes, record the constant as the constant store source. It eliminates unrolled zero stores after memset 0 in a loop where a vector register is used as the zero store source. gcc/ PR rtl-optimization/105638 * df-core.cc (df_find_single_def_src): Moved and renamed from find_single_def_src in loop-iv.cc. Change the argument to rtx and use rtx_equal_p. Return null for partial or conditional defs. * df.h (df_find_single_def_src): New prototype. * dse.cc (record_store): Use the constant source if the source register is set only once. * loop-iv.cc (find_single_def_src): Moved to df-core.cc. (replace_single_def_regs): Replace find_single_def_src with df_find_single_def_src. gcc/testsuite/ PR rtl-optimization/105638 * g++.target/i386/pr105638.C: New test.
Diffstat (limited to 'gcc/df-core.cc')
-rw-r--r--gcc/df-core.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/df-core.cc b/gcc/df-core.cc
index a901b84..e3a56bf 100644
--- a/gcc/df-core.cc
+++ b/gcc/df-core.cc
@@ -2009,6 +2009,47 @@ df_reg_used (rtx_insn *insn, rtx reg)
return df_find_use (insn, reg) != NULL;
}
+/* If REG has a single definition, return its known value, otherwise return
+ null. */
+
+rtx
+df_find_single_def_src (rtx reg)
+{
+ rtx src = NULL_RTX;
+
+ /* Don't look through unbounded number of single definition REG copies,
+ there might be loops for sources with uninitialized variables. */
+ for (int cnt = 0; cnt < 128; cnt++)
+ {
+ df_ref adef = DF_REG_DEF_CHAIN (REGNO (reg));
+ if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
+ || DF_REF_IS_ARTIFICIAL (adef)
+ || (DF_REF_FLAGS (adef)
+ & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+ return NULL_RTX;
+
+ rtx set = single_set (DF_REF_INSN (adef));
+ if (set == NULL || !rtx_equal_p (SET_DEST (set), reg))
+ return NULL_RTX;
+
+ rtx note = find_reg_equal_equiv_note (DF_REF_INSN (adef));
+ if (note && function_invariant_p (XEXP (note, 0)))
+ return XEXP (note, 0);
+ src = SET_SRC (set);
+
+ if (REG_P (src))
+ {
+ reg = src;
+ continue;
+ }
+ break;
+ }
+ if (!function_invariant_p (src))
+ return NULL_RTX;
+
+ return src;
+}
+
/*----------------------------------------------------------------------------
Debugging and printing functions.