final.c (cleanup_subreg_operands): New function.
* final.c (cleanup_subreg_operands): New function. (final_scan_insn): Use it. (alter_subreg): Clear the "used" field when we turn a SUBREG into a REG. * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG operands when reload has finished. * reload.h (cleanup_subreg_operands): Declare.. * flow.c (life_analysis_1): No longer delete CLOBBER insns after reload. Handled in reload itself. Should fix sh, sparc and probably other problems with post-reload life pass and scheduling interactions. From-SVN: r23377
This commit is contained in:
parent
bd09c530b2
commit
0304f7877c
@ -1,3 +1,15 @@
|
||||
Wed Oct 28 00:10:35 1998 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* final.c (cleanup_subreg_operands): New function.
|
||||
(final_scan_insn): Use it.
|
||||
(alter_subreg): Clear the "used" field when we turn a SUBREG into
|
||||
a REG.
|
||||
* reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG
|
||||
operands when reload has finished.
|
||||
* reload.h (cleanup_subreg_operands): Declare..
|
||||
* flow.c (life_analysis_1): No longer delete CLOBBER insns after
|
||||
reload. Handled in reload itself.
|
||||
|
||||
Tue Oct 27 23:32:34 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
|
||||
|
||||
* reload.h (struct insn_chain): Add need_operand_change element.
|
||||
|
64
gcc/final.c
64
gcc/final.c
@ -2844,23 +2844,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
|
||||
insn_code_number = recog_memoized (insn);
|
||||
insn_extract (insn);
|
||||
for (i = 0; i < insn_n_operands[insn_code_number]; i++)
|
||||
{
|
||||
if (GET_CODE (recog_operand[i]) == SUBREG)
|
||||
recog_operand[i] = alter_subreg (recog_operand[i]);
|
||||
else if (GET_CODE (recog_operand[i]) == PLUS
|
||||
|| GET_CODE (recog_operand[i]) == MULT)
|
||||
recog_operand[i] = walk_alter_subreg (recog_operand[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < insn_n_dups[insn_code_number]; i++)
|
||||
{
|
||||
if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
|
||||
*recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
|
||||
else if (GET_CODE (*recog_dup_loc[i]) == PLUS
|
||||
|| GET_CODE (*recog_dup_loc[i]) == MULT)
|
||||
*recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
|
||||
}
|
||||
cleanup_subreg_operands (insn);
|
||||
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
if (! constrain_operands (insn_code_number, 1))
|
||||
@ -3039,6 +3023,49 @@ output_source_line (file, insn)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* For each operand in INSN, simplify (subreg (reg)) so that it refers
|
||||
directly to the desired hard register. */
|
||||
void
|
||||
cleanup_subreg_operands (insn)
|
||||
rtx insn;
|
||||
{
|
||||
int insn_code_number, i;
|
||||
|
||||
/* Ignore things we can not handle. */
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
|
||||
|| GET_CODE (PATTERN (insn)) == USE
|
||||
|| GET_CODE (PATTERN (insn)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
|
||||
|| asm_noperands (PATTERN (insn)) >= 0)
|
||||
return;
|
||||
|
||||
/* Try to recognize the instruction.
|
||||
If successful, verify that the operands satisfy the
|
||||
constraints for the instruction. Crash if they don't,
|
||||
since `reload' should have changed them so that they do. */
|
||||
|
||||
insn_code_number = recog_memoized (insn);
|
||||
insn_extract (insn);
|
||||
for (i = 0; i < insn_n_operands[insn_code_number]; i++)
|
||||
{
|
||||
if (GET_CODE (recog_operand[i]) == SUBREG)
|
||||
recog_operand[i] = alter_subreg (recog_operand[i]);
|
||||
else if (GET_CODE (recog_operand[i]) == PLUS
|
||||
|| GET_CODE (recog_operand[i]) == MULT)
|
||||
recog_operand[i] = walk_alter_subreg (recog_operand[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < insn_n_dups[insn_code_number]; i++)
|
||||
{
|
||||
if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
|
||||
*recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
|
||||
else if (GET_CODE (*recog_dup_loc[i]) == PLUS
|
||||
|| GET_CODE (*recog_dup_loc[i]) == MULT)
|
||||
*recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If X is a SUBREG, replace it with a REG or a MEM,
|
||||
based on the thing it is a subreg of. */
|
||||
|
||||
@ -3072,6 +3099,9 @@ alter_subreg (x)
|
||||
#else
|
||||
REGNO (x) = REGNO (y) + SUBREG_WORD (x);
|
||||
#endif
|
||||
/* This field has a different meaning for REGs and SUBREGs. Make sure
|
||||
to clear it! */
|
||||
x->used = 0;
|
||||
}
|
||||
else if (GET_CODE (y) == MEM)
|
||||
{
|
||||
|
17
gcc/flow.c
17
gcc/flow.c
@ -1358,23 +1358,6 @@ life_analysis_1 (f, nregs)
|
||||
if (reload_completed)
|
||||
bcopy (regs_ever_live, save_regs_ever_live, (sizeof (regs_ever_live)));
|
||||
|
||||
/* Also remove all CLOBBER insns after reload. They can cause us to think
|
||||
a value is dead when it really is not dead. */
|
||||
if (reload_completed)
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
for (insn = f; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (GET_CODE (insn) == INSN
|
||||
&& GET_CODE (PATTERN (insn)) == CLOBBER)
|
||||
{
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
bzero (regs_ever_live, sizeof regs_ever_live);
|
||||
|
||||
/* Allocate and zero out many data structures
|
||||
|
@ -339,3 +339,6 @@ extern void setup_save_areas PROTO((void));
|
||||
|
||||
/* Find the places where hard regs are live across calls and save them. */
|
||||
extern void save_call_clobbered_regs PROTO((void));
|
||||
|
||||
/* Replace (subreg (reg)) with the appropriate (reg) for any operands. */
|
||||
extern void cleanup_subreg_operands PROTO ((rtx));
|
||||
|
@ -1037,16 +1037,17 @@ reload (first, global, dumpfile)
|
||||
}
|
||||
|
||||
/* Make a pass over all the insns and delete all USEs which we inserted
|
||||
only to tag a REG_EQUAL note on them. Also remove all REG_DEAD and
|
||||
REG_UNUSED notes. */
|
||||
only to tag a REG_EQUAL note on them. Remove all REG_DEAD and REG_UNUSED
|
||||
notes. Delete all CLOBBER insns and simplify (subreg (reg)) operands. */
|
||||
|
||||
for (insn = first; insn; insn = NEXT_INSN (insn))
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
|
||||
{
|
||||
rtx *pnote;
|
||||
|
||||
if (GET_CODE (PATTERN (insn)) == USE
|
||||
&& find_reg_note (insn, REG_EQUAL, NULL_RTX))
|
||||
if ((GET_CODE (PATTERN (insn)) == USE
|
||||
&& find_reg_note (insn, REG_EQUAL, NULL_RTX))
|
||||
|| GET_CODE (PATTERN (insn)) == CLOBBER)
|
||||
{
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
@ -1063,6 +1064,9 @@ reload (first, global, dumpfile)
|
||||
else
|
||||
pnote = &XEXP (*pnote, 1);
|
||||
}
|
||||
|
||||
/* And simplify (subreg (reg)) if it appears as an operand. */
|
||||
cleanup_subreg_operands (insn);
|
||||
}
|
||||
|
||||
/* If we are doing stack checking, give a warning if this function's
|
||||
|
Loading…
Reference in New Issue
Block a user