Commit 1a61c29f by Jim Wilson Committed by Jim Wilson

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.

From-SVN: r18669
parent 74ef3b26
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> 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 * rtl.c (read_rtx): Fall back on homebrew atoll if HOST_WIDE_INT
......
...@@ -262,6 +262,8 @@ struct movable ...@@ -262,6 +262,8 @@ struct movable
invariant. */ invariant. */
unsigned int move_insn : 1; /* 1 means that we call emit_move_insn to unsigned int move_insn : 1; /* 1 means that we call emit_move_insn to
load SRC, rather than copying INSN. */ 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. */ 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 enum machine_mode savemode; /* Nonzero means it is a mode for a low part
that we should avoid changing when clearing that we should avoid changing when clearing
...@@ -861,6 +863,7 @@ scan_loop (loop_start, end, nregs, unroll_p) ...@@ -861,6 +863,7 @@ scan_loop (loop_start, end, nregs, unroll_p)
m->forces = 0; m->forces = 0;
m->partial = 0; m->partial = 0;
m->move_insn = move_insn; m->move_insn = move_insn;
m->move_insn_first = 0;
m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0); m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
m->savemode = VOIDmode; m->savemode = VOIDmode;
m->regno = regno; m->regno = regno;
...@@ -885,6 +888,12 @@ scan_loop (loop_start, end, nregs, unroll_p) ...@@ -885,6 +888,12 @@ scan_loop (loop_start, end, nregs, unroll_p)
if (m->consec > 0) 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. */ /* Skip this insn, not checking REG_LIBCALL notes. */
p = next_nonnote_insn (p); p = next_nonnote_insn (p);
/* Skip the consecutive insns, if there are any. */ /* Skip the consecutive insns, if there are any. */
...@@ -1943,20 +1952,41 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs) ...@@ -1943,20 +1952,41 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
CALL_INSN_FUNCTION_USAGE (i1) CALL_INSN_FUNCTION_USAGE (i1)
= copy_rtx (CALL_INSN_FUNCTION_USAGE (p)); = 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 else
i1 = emit_insn_before (PATTERN (p), loop_start); 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 /* If there is a REG_EQUAL note present whose value
not loop invariant, then delete it, since it may is not loop invariant, then delete it, since it
cause problems with later optimization passes. may cause problems with later optimization passes.
It is possible for cse to create such notes It is possible for cse to create such notes
like this as a result of record_jump_cond. */ like this as a result of record_jump_cond. */
if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX)) if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX))
&& ! invariant_p (XEXP (temp, 0))) && ! invariant_p (XEXP (temp, 0)))
remove_note (i1, temp); remove_note (i1, temp);
}
if (new_start == 0) if (new_start == 0)
new_start = i1; new_start = i1;
...@@ -1965,20 +1995,6 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs) ...@@ -1965,20 +1995,6 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
fprintf (loop_dump_stream, " moved to %d", fprintf (loop_dump_stream, " moved to %d",
INSN_UID (i1)); 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 /* If library call, now fix the REG_NOTES that contain
insn pointers, namely REG_LIBCALL on FIRST insn pointers, namely REG_LIBCALL on FIRST
and REG_RETVAL on I1. */ and REG_RETVAL on I1. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment