diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2020-12-17 00:15:10 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2020-12-17 00:15:10 +0000 |
commit | a20cc01679040fb3b069285a638e3a469c688159 (patch) | |
tree | 3ebd7235e422ff4188b800acebed59a3b9e83d93 /gcc | |
parent | 04ee46ed1c06cbbffcd8eb0626b4ab6c3a5082d9 (diff) | |
download | gcc-a20cc01679040fb3b069285a638e3a469c688159.zip gcc-a20cc01679040fb3b069285a638e3a469c688159.tar.gz gcc-a20cc01679040fb3b069285a638e3a469c688159.tar.bz2 |
rtlanal: Add simple_regno_set
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 33 |
2 files changed, 34 insertions, 0 deletions
@@ -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); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 404813b..80e72d6 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -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) |