aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@freesoft.cz>1999-12-17 11:10:58 +0000
committerJan Hubicka <hubicka@gcc.gnu.org>1999-12-17 11:10:58 +0000
commit833fc3ad2371e77287a7c2456b11d7da43f11d7c (patch)
treeb830cb088c1b2c2b3b055d29eab46f83ec51aec9
parent5928cc35dbc3f6fe25a288fccf389581f94c159e (diff)
downloadgcc-833fc3ad2371e77287a7c2456b11d7da43f11d7c.zip
gcc-833fc3ad2371e77287a7c2456b11d7da43f11d7c.tar.gz
gcc-833fc3ad2371e77287a7c2456b11d7da43f11d7c.tar.bz2
gcse.c (try_replace_reg): Do replacements in REG_EQUAL/REG_EQUIV notes too...
* gcse.c (try_replace_reg): Do replacements in REG_EQUAL/REG_EQUIV notes too, create one when replacement failed, attempt to simplify resulting notes. (cprop_insn): Propagate even to registers mentioned only in REG_EQUAL or REG_EQUIV notes. From-SVN: r30992
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/gcse.c61
2 files changed, 67 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2f486f7..1728e84 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+Fri Dec 17 12:08:11 MET 1999 Jan Hubicka <hubicka@freesoftr.cz>
+
+ * gcse.c (try_replace_reg): Do replacements in REG_EQUAL/REG_EQUIV
+ notes too, create one when replacement failed, attempt to simplify
+ resulting notes.
+ (cprop_insn): Propagate even to registers mentioned only in REG_EQUAL
+ or REG_EQUIV notes.
+
1999-12-16 Mark Mitchell <mark@codesourcery.com>
* crtstuff.c (__dso_handle): Declare.
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 701c515..dc45ac1f 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -3702,14 +3702,62 @@ static int
try_replace_reg (from, to, insn)
rtx from, to, insn;
{
+ rtx note;
+ rtx src;
+ int success;
+ rtx set;
+
+ note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+
+ if (!note)
+ note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
+
/* If this fails we could try to simplify the result of the
replacement and attempt to recognize the simplified insn.
But we need a general simplify_rtx that doesn't have pass
specific state variables. I'm not aware of one at the moment. */
- return validate_replace_src (from, to, insn);
-}
+
+ success = validate_replace_src (from, to, insn);
+ set = single_set (insn);
+
+ /* We've failed to do replacement. Try to add REG_EQUAL note to not loose
+ information. */
+ if (!success && !note)
+ {
+ if (!set)
+ return 0;
+ note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
+ copy_rtx (SET_SRC (set)),
+ REG_NOTES (insn));
+ }
+
+ /* Always do the replacement in REQ_EQUAL and REG_EQUIV notes. Also
+ try to simplify them. */
+ if (note)
+ {
+ rtx simplified;
+ src = XEXP (note, 0);
+ replace_rtx (src, from, to);
+
+ /* Try to simplify resulting note. */
+ simplified = simplify_rtx (src);
+ if (simplified)
+ {
+ src = simplified;
+ XEXP (note, 0) = src;
+ }
+
+ /* REG_EQUAL may get simplified into register.
+ We don't allow that. Remove that note. This code ought
+ not to hapen, because previous code ought to syntetize
+ reg-reg move, but be on the safe side. */
+ else if (REG_P (src))
+ remove_note (insn, note);
+ }
+ return success;
+}
/* Find a set of REGNO that is available on entry to INSN's block.
Returns NULL if not found. */
@@ -3897,6 +3945,7 @@ cprop_insn (insn, alter_jumps)
{
struct reg_use *reg_used;
int changed = 0;
+ rtx note;
/* Only propagate into SETs. Note that a conditional jump is a
SET with pc_rtx as the destination. */
@@ -3907,6 +3956,14 @@ cprop_insn (insn, alter_jumps)
reg_use_count = 0;
find_used_regs (PATTERN (insn));
+
+ note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
+ if (!note)
+ note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+
+ /* We may win even when propagating constants into notes. */
+ if (note)
+ find_used_regs (XEXP (note, 0));
reg_used = &reg_use_table[0];
for ( ; reg_use_count > 0; reg_used++, reg_use_count--)