Why does IRA force all pseudos live across a setjmp call to be spilled?
Vladimir Makarov
vmakarov@redhat.com
Sat Mar 3 03:21:00 GMT 2018
On 03/02/2018 02:45 PM, Peter Bergner wrote:
> While debugging the PR84264 ICE caused by the following test case:
>
> void _setjmp ();
> void a (unsigned long *);
> void
> b ()
> {
> for (;;)
> {
> _setjmp ();
> unsigned long args[9]{};
> a (args);
> }
> }
>
> I noticed that IRA is spilling all pseudos that are live across the call
> to setjmp. Why is that? Trying to look through the history of this, I see
> Jim committed a patch to reload that removed it spilling everything across
> all setjmps:
>
> https://gcc.gnu.org/ml/gcc-patches/2003-11/msg01667.html
>
> But currently ira-lives.c:process_bb_node_lives() has:
>
> /* Don't allocate allocnos that cross setjmps or any
> call, if this function receives a nonlocal
> goto. */
> if (cfun->has_nonlocal_label
> || find_reg_note (insn, REG_SETJMP,
> NULL_RTX) != NULL_RTX)
> {
> SET_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj));
> SET_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
> }
>
> ...which forces us to spill everything live across the setjmp by forcing
> the pseudos to interfere all hardregs. That can't be good for performance.
> What am I missing?
>
>
I see. There are a lot of history in this issue. The first version of
IRA (2008) had no such code. After merging IRA, I got a PR
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37359 for an IA64 code.
To fix the PR, I implemented global.c behaviour for setjmp. In
regstat.c pseudos crossing setjmp got REG_LIVE_LENGTH == -1. In
global.c pseudos with REG_LIVE_LENGTH == -1 did not get an allocno and a
hard reg as a consequence.
As I understand Jim Wilson wrote about fixing the issue in reload. I
guess inheritance could have improved the code generated by global after
fixing the issue in reload.
So basically IRA behaves as the old global. Probably we could improve
the current IRA code working with setjmp.
More information about the Gcc
mailing list