aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <wilson@cygnus.com>1998-03-18 12:45:22 +0000
committerJim Wilson <wilson@cygnus.com>1998-03-18 12:45:22 +0000
commitb73386246e0def9ee3c9fb0b3ff455fc2e43d428 (patch)
treedc379393257fcf76e99c1a751828c8bf90045de4
parentf0f4f7bd70171dd63f3df882e2d67a17f4397eed (diff)
Fix sparc-sun-solaris2 -O2 -fPIC bootstrap failure with gcse code.
* loop.c (struct movable): New field move_insn_first. (scan_loop): In consec sets code, set it. Clear it otherwise. (move_movables): In consec sets code, use it. Copy REG_NOTES from p to i1 only if i1 does not have REG_NOTES. Delete obsolete ifdefed out code. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@18669 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/loop.c62
2 files changed, 47 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cedf0084794..cb9b882c67b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+Wed Mar 18 12:43:20 1998 Jim Wilson <wilson@cygnus.com>
+
+ * loop.c (struct movable): New field move_insn_first.
+ (scan_loop): In consec sets code, set it. Clear it otherwise.
+ (move_movables): In consec sets code, use it. Copy REG_NOTES from
+ p to i1 only if i1 does not have REG_NOTES. Delete obsolete ifdefed
+ out code.
+
Wed Mar 18 09:52:56 1998 Richard Henderson <rth@cygnus.com>
* rtl.c (read_rtx): Fall back on homebrew atoll if HOST_WIDE_INT
diff --git a/gcc/loop.c b/gcc/loop.c
index 89402a547c1..5e3039f18ff 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -262,6 +262,8 @@ struct movable
invariant. */
unsigned int move_insn : 1; /* 1 means that we call emit_move_insn to
load SRC, rather than copying INSN. */
+ unsigned int move_insn_first:1;/* Same as above, if this is necessary for the
+ first insn of a consecutive sets group. */
unsigned int is_equiv : 1; /* 1 means a REG_EQUIV is present on INSN. */
enum machine_mode savemode; /* Nonzero means it is a mode for a low part
that we should avoid changing when clearing
@@ -861,6 +863,7 @@ scan_loop (loop_start, end, nregs, unroll_p)
m->forces = 0;
m->partial = 0;
m->move_insn = move_insn;
+ m->move_insn_first = 0;
m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
m->savemode = VOIDmode;
m->regno = regno;
@@ -885,6 +888,12 @@ scan_loop (loop_start, end, nregs, unroll_p)
if (m->consec > 0)
{
+ /* It is possible for the first instruction to have a
+ REG_EQUAL note but a non-invariant SET_SRC, so we must
+ remember the status of the first instruction in case
+ the last instruction doesn't have a REG_EQUAL note. */
+ m->move_insn_first = m->move_insn;
+
/* Skip this insn, not checking REG_LIBCALL notes. */
p = next_nonnote_insn (p);
/* Skip the consecutive insns, if there are any. */
@@ -1943,20 +1952,41 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
CALL_INSN_FUNCTION_USAGE (i1)
= copy_rtx (CALL_INSN_FUNCTION_USAGE (p));
}
+ else if (count == m->consec && m->move_insn_first)
+ {
+ /* The SET_SRC might not be invariant, so we must
+ use the REG_EQUAL note. */
+ start_sequence ();
+ emit_move_insn (m->set_dest, m->set_src);
+ temp = get_insns ();
+ end_sequence ();
+
+ add_label_notes (m->set_src, temp);
+
+ i1 = emit_insns_before (temp, loop_start);
+ if (! find_reg_note (i1, REG_EQUAL, NULL_RTX))
+ REG_NOTES (i1)
+ = gen_rtx_EXPR_LIST ((m->is_equiv ? REG_EQUIV
+ : REG_EQUAL),
+ m->set_src, REG_NOTES (i1));
+ }
else
i1 = emit_insn_before (PATTERN (p), loop_start);
- REG_NOTES (i1) = REG_NOTES (p);
+ if (REG_NOTES (i1) == 0)
+ {
+ REG_NOTES (i1) = REG_NOTES (p);
- /* If there is a REG_EQUAL note present whose value is
- not loop invariant, then delete it, since it may
- cause problems with later optimization passes.
- It is possible for cse to create such notes
- like this as a result of record_jump_cond. */
+ /* If there is a REG_EQUAL note present whose value
+ is not loop invariant, then delete it, since it
+ may cause problems with later optimization passes.
+ It is possible for cse to create such notes
+ like this as a result of record_jump_cond. */
- if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX))
- && ! invariant_p (XEXP (temp, 0)))
- remove_note (i1, temp);
+ if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX))
+ && ! invariant_p (XEXP (temp, 0)))
+ remove_note (i1, temp);
+ }
if (new_start == 0)
new_start = i1;
@@ -1965,20 +1995,6 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
fprintf (loop_dump_stream, " moved to %d",
INSN_UID (i1));
-#if 0
- /* This isn't needed because REG_NOTES is copied
- below and is wrong since P might be a PARALLEL. */
- if (REG_NOTES (i1) == 0
- && ! m->partial /* But not if it's a zero-extend clr. */
- && ! m->global /* and not if used outside the loop
- (since it might get set outside). */
- && CONSTANT_P (SET_SRC (PATTERN (p))))
- REG_NOTES (i1)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- SET_SRC (PATTERN (p)),
- REG_NOTES (i1));
-#endif
-
/* If library call, now fix the REG_NOTES that contain
insn pointers, namely REG_LIBCALL on FIRST
and REG_RETVAL on I1. */