rtlanal: Add simple_regno_set
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 17 Dec 2020 00:15:10 +0000 (00:15 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 17 Dec 2020 00:15:10 +0000 (00:15 +0000)
This patch adds a routine for finding a “simple” SET for a register
definition.  See the comment in the patch for details.

gcc/
* rtl.h (simple_regno_set): Declare.
* rtlanal.c (simple_regno_set): New function.

gcc/rtl.h
gcc/rtlanal.c

index e9df95b02c44e2b795c666c9a71ff5808d0e8095..3915fae61e730eca147bb375d2c0eef856ebdd4e 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3539,6 +3539,7 @@ extern void set_insn_deleted (rtx_insn *);
 /* Functions in rtlanal.c */
 
 extern rtx single_set_2 (const rtx_insn *, const_rtx);
+extern rtx simple_regno_set (rtx, unsigned int);
 extern bool contains_symbol_ref_p (const_rtx);
 extern bool contains_symbolic_reference_p (const_rtx);
 extern bool contains_constant_pool_address_p (const_rtx);
index 404813b76680c02e18632242c2bf93752fe18274..80e72d6049d55c486f08c9a1c97b1d1590280e3c 100644 (file)
@@ -1455,6 +1455,39 @@ set_of (const_rtx pat, const_rtx insn)
   return data.found;
 }
 
+/* Check whether instruction pattern PAT contains a SET with the following
+   properties:
+
+   - the SET is executed unconditionally;
+   - the destination of the SET is write-only rather than read-write; and
+   - either:
+     - the destination of the SET is a REG that contains REGNO; or
+     - the destination of the SET is a SUBREG of such a REG.
+
+   If PAT does have a SET like that, return the set, otherwise return null.
+
+   This is intended to be an alternative to single_set for passes that
+   can handle patterns with multiple_sets.  */
+rtx
+simple_regno_set (rtx pat, unsigned int regno)
+{
+  if (GET_CODE (pat) == PARALLEL)
+    {
+      int last = XVECLEN (pat, 0) - 1;
+      for (int i = 0; i < last; ++i)
+       if (rtx set = simple_regno_set (XVECEXP (pat, 0, i), regno))
+         return set;
+
+      pat = XVECEXP (pat, 0, last);
+    }
+
+  if (GET_CODE (pat) == SET
+      && covers_regno_no_parallel_p (SET_DEST (pat), regno))
+    return pat;
+
+  return nullptr;
+}
+
 /* Add all hard register in X to *PSET.  */
 void
 find_all_hard_regs (const_rtx x, HARD_REG_SET *pset)