summaryrefslogtreecommitdiff
path: root/gcc/sched.c
diff options
context:
space:
mode:
authorwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>1993-09-28 22:57:44 +0000
committerwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>1993-09-28 22:57:44 +0000
commit7d3b208e6b6c83733c0e57d4f2de302006c6bb7c (patch)
tree06c304a7fa983850644e6cc50b5c881df2132047 /gcc/sched.c
parentf0777d2c4c442ea424d6b882a2d75d80221e865b (diff)
downloadgcc-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.c32
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];
}
}
}