diff options
author | wilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4> | 1993-09-28 22:57:44 +0000 |
---|---|---|
committer | wilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4> | 1993-09-28 22:57:44 +0000 |
commit | 7d3b208e6b6c83733c0e57d4f2de302006c6bb7c (patch) | |
tree | 06c304a7fa983850644e6cc50b5c881df2132047 /gcc/sched.c | |
parent | f0777d2c4c442ea424d6b882a2d75d80221e865b (diff) | |
download | gcc-7d3b208e6b6c83733c0e57d4f2de302006c6bb7c.tar.gz |
(schedule_insns): Don't zero reg_n_calls_crossed for
pseudos live across multiple blocks.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@5515 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sched.c')
-rw-r--r-- | gcc/sched.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/gcc/sched.c b/gcc/sched.c index b067d36abaa..a56aa47cd2e 100644 --- a/gcc/sched.c +++ b/gcc/sched.c @@ -4678,20 +4678,38 @@ schedule_insns (dump_file) regno, reg_live_length[regno], sched_reg_live_length[regno]); - if (reg_n_calls_crossed[regno] - && ! sched_reg_n_calls_crossed[regno]) - fprintf (dump_file, - ";; register %d no longer crosses calls\n", regno); - else if (! reg_n_calls_crossed[regno] - && sched_reg_n_calls_crossed[regno]) + if (! reg_n_calls_crossed[regno] + && sched_reg_n_calls_crossed[regno]) fprintf (dump_file, ";; register %d now crosses calls\n", regno); + else if (reg_n_calls_crossed[regno] + && ! sched_reg_n_calls_crossed[regno] + && reg_basic_block[regno] != REG_BLOCK_GLOBAL) + fprintf (dump_file, + ";; register %d no longer crosses calls\n", regno); + } /* Negative values are special; don't overwrite the current reg_live_length value if it is negative. */ if (reg_live_length[regno] >= 0) reg_live_length[regno] = sched_reg_live_length[regno]; - reg_n_calls_crossed[regno] = sched_reg_n_calls_crossed[regno]; + + /* We can't change the value of reg_n_calls_crossed to zero for + pseudos which are live in more than one block. + + This is because combine might have made an optimization which + invalidated basic_block_live_at_start and reg_n_calls_crossed, + but it does not update them. If we update reg_n_calls_crossed + here, the two variables are now inconsistent, and this might + confuse the caller-save code into saving a register that doesn't + need to be saved. This is only a problem when we zero calls + crossed for a pseudo live in multiple basic blocks. + + Alternatively, we could try to correctly update basic block live + at start here in sched, but that seems complicated. */ + if (sched_reg_n_calls_crossed[regno] + || reg_basic_block[regno] != REG_BLOCK_GLOBAL) + reg_n_calls_crossed[regno] = sched_reg_n_calls_crossed[regno]; } } } |