Commit f903b91f by David S. Miller Committed by David S. Miller

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
parent 1b07eafa
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) 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 * collect2.c (main): Use "-x c" instead of "-lang-c" for force the
......
...@@ -605,15 +605,6 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -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_simplejump, this_is_condjump, reversep = 0;
int this_is_condjump_in_parallel; 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 0
/* If NOT the first iteration, if this is the last jump pass /* If NOT the first iteration, if this is the last jump pass
(just before final), do the special peephole optimizations. (just before final), do the special peephole optimizations.
...@@ -987,7 +978,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -987,7 +978,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
We set: We set:
TEMP to the "x = exp;" insn. 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". */ TEMP2 to "x". */
if (! reload_completed if (! reload_completed
...@@ -1021,6 +1012,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1021,6 +1012,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
PREV_INSN (temp3), temp); PREV_INSN (temp3), temp);
delete_insn (temp); delete_insn (temp);
reallabelprev = prev_active_insn (JUMP_LABEL (insn)); 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) ...@@ -1073,6 +1070,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (temp); delete_insn (temp);
delete_insn (temp3); delete_insn (temp3);
reallabelprev = prev_active_insn (JUMP_LABEL (insn)); 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) ...@@ -1133,6 +1136,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (temp); delete_insn (temp);
delete_insn (temp3); delete_insn (temp3);
reallabelprev = prev_active_insn (JUMP_LABEL (insn)); 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 */ #endif /* HAVE_cc0 */
...@@ -1244,7 +1253,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1244,7 +1253,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
if (target) if (target)
{ {
rtx seq1,seq2; rtx seq1,seq2,last;
/* Save the conditional move sequence but don't emit it /* Save the conditional move sequence but don't emit it
yet. On some machines, like the alpha, it is possible yet. On some machines, like the alpha, it is possible
...@@ -1266,13 +1275,20 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1266,13 +1275,20 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
emit_insns_before (seq1, temp5); emit_insns_before (seq1, temp5);
/* Insert conditional move after insn, to be sure that /* Insert conditional move after insn, to be sure that
the jump and a possible compare won't be separated */ 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. /* ??? We can also delete the insn that sets X to A.
Flow will do it too though. */ Flow will do it too though. */
delete_insn (temp); delete_insn (temp);
next = NEXT_INSN (insn); next = NEXT_INSN (insn);
delete_jump (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; changed = 1;
continue; continue;
} }
...@@ -1455,6 +1471,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1455,6 +1471,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (temp); delete_insn (temp);
next = NEXT_INSN (insn); next = NEXT_INSN (insn);
delete_jump (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; changed = 1;
continue; continue;
} }
...@@ -1574,6 +1597,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1574,6 +1597,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
delete_insn (prev_nonnote_insn (insn)); delete_insn (prev_nonnote_insn (insn));
#endif #endif
delete_insn (insn); delete_insn (insn);
if (after_regscan)
{
reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
changed = 1; changed = 1;
continue; continue;
} }
......
...@@ -673,7 +673,7 @@ static void record_address_regs PROTO((rtx, enum reg_class, int)); ...@@ -673,7 +673,7 @@ static void record_address_regs PROTO((rtx, enum reg_class, int));
#ifdef FORBIDDEN_INC_DEC_CLASSES #ifdef FORBIDDEN_INC_DEC_CLASSES
static int auto_inc_dec_reg_p PROTO((rtx, enum machine_mode)); static int auto_inc_dec_reg_p PROTO((rtx, enum machine_mode));
#endif #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. /* Return the reg_class in which pseudo reg number REGNO is best allocated.
This function is sometimes called before the info has been computed. This function is sometimes called before the info has been computed.
...@@ -1939,21 +1939,54 @@ reg_scan (f, nregs, repeat) ...@@ -1939,21 +1939,54 @@ reg_scan (f, nregs, repeat)
if (GET_CODE (PATTERN (insn)) == PARALLEL if (GET_CODE (PATTERN (insn)) == PARALLEL
&& XVECLEN (PATTERN (insn), 0) > max_parallel) && XVECLEN (PATTERN (insn), 0) > max_parallel)
max_parallel = XVECLEN (PATTERN (insn), 0); 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)) 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. /* 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 static void
reg_scan_mark_refs (x, insn, note_flag) reg_scan_mark_refs (x, insn, note_flag, min_regno)
rtx x; rtx x;
rtx insn; rtx insn;
int note_flag; int note_flag;
int min_regno;
{ {
register enum rtx_code code = GET_CODE (x); register enum rtx_code code = GET_CODE (x);
register rtx dest; register rtx dest;
...@@ -1976,24 +2009,27 @@ reg_scan_mark_refs (x, insn, note_flag) ...@@ -1976,24 +2009,27 @@ reg_scan_mark_refs (x, insn, note_flag)
{ {
register int regno = REGNO (x); register int regno = REGNO (x);
if (regno >= min_regno)
{
REGNO_LAST_NOTE_UID (regno) = INSN_UID (insn); REGNO_LAST_NOTE_UID (regno) = INSN_UID (insn);
if (!note_flag) if (!note_flag)
REGNO_LAST_UID (regno) = INSN_UID (insn); REGNO_LAST_UID (regno) = INSN_UID (insn);
if (REGNO_FIRST_UID (regno) == 0) if (REGNO_FIRST_UID (regno) == 0)
REGNO_FIRST_UID (regno) = INSN_UID (insn); REGNO_FIRST_UID (regno) = INSN_UID (insn);
} }
}
break; break;
case EXPR_LIST: case EXPR_LIST:
if (XEXP (x, 0)) 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)) 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; break;
case INSN_LIST: case INSN_LIST:
if (XEXP (x, 1)) 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; break;
case SET: case SET:
...@@ -2004,7 +2040,8 @@ reg_scan_mark_refs (x, insn, note_flag) ...@@ -2004,7 +2040,8 @@ reg_scan_mark_refs (x, insn, note_flag)
dest = XEXP (dest, 0)) dest = XEXP (dest, 0))
; ;
if (GET_CODE (dest) == REG) if (GET_CODE (dest) == REG
&& REGNO (dest) >= min_regno)
REG_N_SETS (REGNO (dest))++; REG_N_SETS (REGNO (dest))++;
/* If this is setting a pseudo from another pseudo or the sum of a /* 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) ...@@ -2021,6 +2058,7 @@ reg_scan_mark_refs (x, insn, note_flag)
if (GET_CODE (SET_DEST (x)) == REG if (GET_CODE (SET_DEST (x)) == REG
&& REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
&& REGNO (SET_DEST (x)) >= min_regno
/* If the destination pseudo is set more than once, then other /* If the destination pseudo is set more than once, then other
sets might not be to a pointer value (consider access to a sets might not be to a pointer value (consider access to a
union in two threads of control in the presense of global union in two threads of control in the presense of global
...@@ -2063,12 +2101,12 @@ reg_scan_mark_refs (x, insn, note_flag) ...@@ -2063,12 +2101,12 @@ reg_scan_mark_refs (x, insn, note_flag)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{ {
if (fmt[i] == 'e') 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) else if (fmt[i] == 'E' && XVEC (x, i) != 0)
{ {
register int j; register int j;
for (j = XVECLEN (x, i) - 1; j >= 0; 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);
} }
} }
} }
......
...@@ -1449,6 +1449,7 @@ extern void regset_release_memory PROTO ((void)); ...@@ -1449,6 +1449,7 @@ extern void regset_release_memory PROTO ((void));
extern void regclass_init PROTO ((void)); extern void regclass_init PROTO ((void));
extern void regclass PROTO ((rtx, int)); extern void regclass PROTO ((rtx, int));
extern void reg_scan PROTO ((rtx, int, 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)); extern void fix_register PROTO ((char *, int, int));
/* In regmove.c */ /* In regmove.c */
......
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