More efficient version of Jul 10 bugfix of mine, as discussed on egcs-patches.

More efficient version of Jul 10 bugfix of mine, as
discussed on egcs-patches.
	* regclass.c (reg_scan_mark_refs): New arg min_regno.  Only update
	regscan information for REGs with numbers greater than or equal to
	this.  All callers changed.
	(reg_scan_update): New function to efficiently update regscan
	information on the fly.
	* rtl.h: Add prototype.
	* jump.c (jump_optimize): Call it when we make a transformation
	which generates new pseudo-REGs.

From-SVN: r21096
This commit is contained in:
David S. Miller 1998-07-13 03:34:12 +00:00 committed by David S. Miller
parent 1b07eafaae
commit f903b91f37
4 changed files with 108 additions and 28 deletions

View File

@ -1,3 +1,14 @@
Mon Jul 13 02:24:08 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
* regclass.c (reg_scan_mark_refs): New arg min_regno. Only update
regscan information for REGs with numbers greater than or equal to
this. All callers changed.
(reg_scan_update): New function to efficiently update regscan
information on the fly.
* rtl.h: Add prototype.
* jump.c (jump_optimize): Call it when we make a transformation
which generates new pseudo-REGs.
Sun Jul 12 13:08:14 1998 Jeffrey A Law (law@cygnus.com)
* collect2.c (main): Use "-x c" instead of "-lang-c" for force the

View File

@ -605,15 +605,6 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
int this_is_simplejump, this_is_condjump, reversep = 0;
int this_is_condjump_in_parallel;
/* If one of our transformations has created more REGs we
must rerun reg_scan or else we risk missed optimizations,
erroneous optimizations, or even worse a crash. */
if (after_regscan &&
old_max_reg < max_reg_num ())
{
reg_scan (f, max_reg_num (), 0);
old_max_reg = max_reg_num ();
}
#if 0
/* If NOT the first iteration, if this is the last jump pass
(just before final), do the special peephole optimizations.
@ -987,7 +978,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
We set:
TEMP to the "x = exp;" insn.
TEMP1 to the single set in the "x = exp; insn.
TEMP1 to the single set in the "x = exp;" insn.
TEMP2 to "x". */
if (! reload_completed
@ -1021,6 +1012,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
PREV_INSN (temp3), temp);
delete_insn (temp);
reallabelprev = prev_active_insn (JUMP_LABEL (insn));
if (after_regscan)
{
reg_scan_update (temp3, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
}
}
@ -1073,6 +1070,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (temp);
delete_insn (temp3);
reallabelprev = prev_active_insn (JUMP_LABEL (insn));
if (after_regscan)
{
reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
}
}
@ -1133,6 +1136,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (temp);
delete_insn (temp3);
reallabelprev = prev_active_insn (JUMP_LABEL (insn));
if (after_regscan)
{
reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
}
}
#endif /* HAVE_cc0 */
@ -1244,7 +1253,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
if (target)
{
rtx seq1,seq2;
rtx seq1,seq2,last;
/* Save the conditional move sequence but don't emit it
yet. On some machines, like the alpha, it is possible
@ -1266,13 +1275,20 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
emit_insns_before (seq1, temp5);
/* Insert conditional move after insn, to be sure that
the jump and a possible compare won't be separated */
emit_insns_after (seq2, insn);
last = emit_insns_after (seq2, insn);
/* ??? We can also delete the insn that sets X to A.
Flow will do it too though. */
delete_insn (temp);
next = NEXT_INSN (insn);
delete_jump (insn);
if (after_regscan)
{
reg_scan_update (seq1, NEXT_INSN (last), old_max_reg);
old_max_reg = max_reg_num ();
}
changed = 1;
continue;
}
@ -1455,6 +1471,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (temp);
next = NEXT_INSN (insn);
delete_jump (insn);
if (after_regscan)
{
reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
changed = 1;
continue;
}
@ -1574,6 +1597,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (prev_nonnote_insn (insn));
#endif
delete_insn (insn);
if (after_regscan)
{
reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
changed = 1;
continue;
}

View File

@ -673,7 +673,7 @@ static void record_address_regs PROTO((rtx, enum reg_class, int));
#ifdef FORBIDDEN_INC_DEC_CLASSES
static int auto_inc_dec_reg_p PROTO((rtx, enum machine_mode));
#endif
static void reg_scan_mark_refs PROTO((rtx, rtx, int));
static void reg_scan_mark_refs PROTO((rtx, rtx, int, int));
/* Return the reg_class in which pseudo reg number REGNO is best allocated.
This function is sometimes called before the info has been computed.
@ -1939,21 +1939,54 @@ reg_scan (f, nregs, repeat)
if (GET_CODE (PATTERN (insn)) == PARALLEL
&& XVECLEN (PATTERN (insn), 0) > max_parallel)
max_parallel = XVECLEN (PATTERN (insn), 0);
reg_scan_mark_refs (PATTERN (insn), insn, 0);
reg_scan_mark_refs (PATTERN (insn), insn, 0, 0);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1);
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, 0);
}
}
/* Update 'regscan' information by looking at the insns
from FIRST to LAST. Some new REGs have been created,
and any REG with number greater than OLD_MAX_REGNO is
such a REG. We only update information for those. */
void
reg_scan_update(first, last, old_max_regno)
rtx first;
rtx last;
int old_max_regno;
{
register rtx insn;
allocate_reg_info (max_reg_num (), FALSE, FALSE);
for (insn = first; insn != last; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == INSN
|| GET_CODE (insn) == CALL_INSN
|| GET_CODE (insn) == JUMP_INSN)
{
if (GET_CODE (PATTERN (insn)) == PARALLEL
&& XVECLEN (PATTERN (insn), 0) > max_parallel)
max_parallel = XVECLEN (PATTERN (insn), 0);
reg_scan_mark_refs (PATTERN (insn), insn, 0, old_max_regno);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, old_max_regno);
}
}
/* X is the expression to scan. INSN is the insn it appears in.
NOTE_FLAG is nonzero if X is from INSN's notes rather than its body. */
NOTE_FLAG is nonzero if X is from INSN's notes rather than its body.
We should only record information for REGs with numbers
greater than or equal to MIN_REGNO. */
static void
reg_scan_mark_refs (x, insn, note_flag)
reg_scan_mark_refs (x, insn, note_flag, min_regno)
rtx x;
rtx insn;
int note_flag;
int min_regno;
{
register enum rtx_code code = GET_CODE (x);
register rtx dest;
@ -1976,24 +2009,27 @@ reg_scan_mark_refs (x, insn, note_flag)
{
register int regno = REGNO (x);
REGNO_LAST_NOTE_UID (regno) = INSN_UID (insn);
if (!note_flag)
REGNO_LAST_UID (regno) = INSN_UID (insn);
if (REGNO_FIRST_UID (regno) == 0)
REGNO_FIRST_UID (regno) = INSN_UID (insn);
if (regno >= min_regno)
{
REGNO_LAST_NOTE_UID (regno) = INSN_UID (insn);
if (!note_flag)
REGNO_LAST_UID (regno) = INSN_UID (insn);
if (REGNO_FIRST_UID (regno) == 0)
REGNO_FIRST_UID (regno) = INSN_UID (insn);
}
}
break;
case EXPR_LIST:
if (XEXP (x, 0))
reg_scan_mark_refs (XEXP (x, 0), insn, note_flag);
reg_scan_mark_refs (XEXP (x, 0), insn, note_flag, min_regno);
if (XEXP (x, 1))
reg_scan_mark_refs (XEXP (x, 1), insn, note_flag);
reg_scan_mark_refs (XEXP (x, 1), insn, note_flag, min_regno);
break;
case INSN_LIST:
if (XEXP (x, 1))
reg_scan_mark_refs (XEXP (x, 1), insn, note_flag);
reg_scan_mark_refs (XEXP (x, 1), insn, note_flag, min_regno);
break;
case SET:
@ -2004,7 +2040,8 @@ reg_scan_mark_refs (x, insn, note_flag)
dest = XEXP (dest, 0))
;
if (GET_CODE (dest) == REG)
if (GET_CODE (dest) == REG
&& REGNO (dest) >= min_regno)
REG_N_SETS (REGNO (dest))++;
/* If this is setting a pseudo from another pseudo or the sum of a
@ -2021,6 +2058,7 @@ reg_scan_mark_refs (x, insn, note_flag)
if (GET_CODE (SET_DEST (x)) == REG
&& REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
&& REGNO (SET_DEST (x)) >= min_regno
/* If the destination pseudo is set more than once, then other
sets might not be to a pointer value (consider access to a
union in two threads of control in the presense of global
@ -2063,12 +2101,12 @@ reg_scan_mark_refs (x, insn, note_flag)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
reg_scan_mark_refs (XEXP (x, i), insn, note_flag);
reg_scan_mark_refs (XEXP (x, i), insn, note_flag, min_regno);
else if (fmt[i] == 'E' && XVEC (x, i) != 0)
{
register int j;
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
reg_scan_mark_refs (XVECEXP (x, i, j), insn, note_flag);
reg_scan_mark_refs (XVECEXP (x, i, j), insn, note_flag, min_regno);
}
}
}

View File

@ -1449,6 +1449,7 @@ extern void regset_release_memory PROTO ((void));
extern void regclass_init PROTO ((void));
extern void regclass PROTO ((rtx, int));
extern void reg_scan PROTO ((rtx, int, int));
extern void reg_scan_update PROTO ((rtx, rtx, int));
extern void fix_register PROTO ((char *, int, int));
/* In regmove.c */