diff options
author | Jeffrey A Law <law@cygnus.com> | 1998-10-27 23:19:31 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1998-10-27 16:19:31 -0700 |
commit | 0304f7877c4c65d129ea00cc2964a0998b9031ce (patch) | |
tree | c70a7a8b1e67a64ee37c4cbef242efc253b9a280 /gcc | |
parent | bd09c530b225d9d838c63842e605aafe12a817e3 (diff) | |
download | gcc-0304f7877c4c65d129ea00cc2964a0998b9031ce.zip gcc-0304f7877c4c65d129ea00cc2964a0998b9031ce.tar.gz gcc-0304f7877c4c65d129ea00cc2964a0998b9031ce.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/final.c | 64 | ||||
-rw-r--r-- | gcc/flow.c | 17 | ||||
-rw-r--r-- | gcc/reload.h | 3 | ||||
-rw-r--r-- | gcc/reload1.c | 12 |
5 files changed, 70 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4cab3de..23af102 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/final.c b/gcc/final.c index 5b7874e..4c19c84 100644 --- a/gcc/final.c +++ b/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) { @@ -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 diff --git a/gcc/reload.h b/gcc/reload.h index 5606a4e..968d312 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -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)); diff --git a/gcc/reload1.c b/gcc/reload1.c index ae0eb77..7e702d3 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -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 |