diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-03-12 17:38:30 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-03-12 17:38:30 +0000 |
commit | 67962db535fa27c17bf93b7974b83f0aaa1b815a (patch) | |
tree | 4583547ab2a563ddc71a04db0660fe8ef047105a /gcc/combine.c | |
parent | 8937b6a2095b723cbdb1fd2be7cd6011c52fce1a (diff) | |
download | gcc-67962db535fa27c17bf93b7974b83f0aaa1b815a.zip gcc-67962db535fa27c17bf93b7974b83f0aaa1b815a.tar.gz gcc-67962db535fa27c17bf93b7974b83f0aaa1b815a.tar.bz2 |
combine.c (unmentioned_reg_p): New function to check whether an expression is a "specialization" of another, i.e.
* combine.c (unmentioned_reg_p): New function to check whether an
expression is a "specialization" of another, i.e. that there are
no registers or memory references mentioned in the first that don't
appear in the second.
(unmentioned_reg_p_1): New helper subroutine of unmentioned_reg_p.
(combine_instructions): Also try combining instructions using the
REG_EQUAL note from a preceding log-linked instruction.
From-SVN: r79398
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index c627187..a32e479 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -407,6 +407,8 @@ static int insn_cuid (rtx); static void record_promoted_value (rtx, rtx); static rtx reversed_comparison (rtx, enum machine_mode, rtx, rtx); static enum rtx_code combine_reversed_comparison_code (rtx); +static int unmentioned_reg_p_1 (rtx *, void *); +static bool unmentioned_reg_p (rtx, rtx); /* Substitute NEWVAL, an rtx expression, into INTO, a place in some insn. The substitution can be undone by undo_all. If INTO is already @@ -720,6 +722,31 @@ combine_instructions (rtx f, unsigned int nregs) &new_direct_jump_p)) != 0) goto retry; + /* Try this insn with each REG_EQUAL note it links back to. */ + for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) + { + rtx set, note; + rtx temp = XEXP (links, 0); + if ((set = single_set (temp)) != 0 + && (note = find_reg_equal_equiv_note (temp)) != 0 + && GET_CODE (XEXP (note, 0)) != EXPR_LIST + /* Avoid using a register that may already been marked + dead by an earlier instruction. */ + && ! unmentioned_reg_p (XEXP (note, 0), SET_SRC (set))) + { + /* Temporarily replace the set's source with the + contents of the REG_EQUAL note. The insn will + be deleted or recognized by try_combine. */ + rtx orig = SET_SRC (set); + SET_SRC (set) = XEXP (note, 0); + next = try_combine (insn, temp, NULL_RTX, + &new_direct_jump_p); + if (next) + goto retry; + SET_SRC (set) = orig; + } + } + if (GET_CODE (insn) != NOTE) record_dead_and_set_regs (insn); @@ -12979,6 +13006,33 @@ distribute_links (rtx links) } } +/* Subroutine of unmentioned_reg_p and callback from for_each_rtx. + Check whether the expression pointer to by LOC is a register or + memory, and if so return 1 if it isn't mentioned in the rtx EXPR. + Otherwise return zero. */ + +static int +unmentioned_reg_p_1 (rtx *loc, void *expr) +{ + rtx x = *loc; + + if (x != NULL_RTX + && (GET_CODE (x) == REG || GET_CODE (x) == MEM) + && ! reg_mentioned_p (x, (rtx) expr)) + return 1; + return 0; +} + +/* Check for any register or memory mentioned in EQUIV that is not + mentioned in EXPR. This is used to restrict EQUIV to "specializations" + of EXPR where some registers may have been replaced by constants. */ + +static bool +unmentioned_reg_p (rtx equiv, rtx expr) +{ + return for_each_rtx (&equiv, unmentioned_reg_p_1, expr); +} + /* Compute INSN_CUID for INSN, which is an insn made by combine. */ static int |