diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-27 23:19:31 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-27 23:19:31 +0000 |
commit | d740a1dd2870ba202cd288ed8714540b0b60912d (patch) | |
tree | c70a7a8b1e67a64ee37c4cbef242efc253b9a280 /gcc/final.c | |
parent | 1063433ee616c7b224b1625c8c05c6619ffc6a25 (diff) | |
download | gcc-d740a1dd2870ba202cd288ed8714540b0b60912d.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23377 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/gcc/final.c b/gcc/final.c index 5b7874e7587..4c19c84a9fd 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) { |