This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Why does IRA force all pseudos live across a setjmp call to be spilled?


On 3/3/18 10:29 AM, Jeff Law wrote:
> Here's the comment from regstat.c:
> 
>               /* We have a problem with any pseudoreg that lives
>                  across the setjmp.  ANSI says that if a user variable
>                  does not change in value between the setjmp and the
>                  longjmp, then the longjmp preserves it.  This
>                  includes longjmp from a place where the pseudo
>                  appears dead.  (In principle, the value still exists
>                  if it is in scope.)  If the pseudo goes in a hard
>                  reg, some other value may occupy that hard reg where
>                  this pseudo is dead, thus clobbering the pseudo.
>                  Conclusion: such a pseudo must not go in a hard
>                  reg.  */

I can't argue with anything in that comment, other than the conclusion. :-)
It's not the compiler's job to implement the setjmp/longjmp save/restore.
Maybe Kenny was working around a problem with some target's buggy setjmp
and spilling everything "fixed" it?

It is absolutely fine for a pseudo that is live across a setjmp call to
occupy a (non-volatile) hard register at the setjmp's call site, even if
some other value eventually occupies the same hard register between the
setjmp and the longjmp.  The reason is that setjmp saves all of the non-
volatile hard registers in the jmp_buf.  If our pseudo was assigned to
one of those non-volatile hard registers, then its value at the time of
the setjmp call is saved, so even if its hard register is clobbered before
we get to the longjmp call, the longjmp will restore the pseudos value from
the jmp_buf into the hard register, restoring the value it had at the time
of the setjmp call.

The only way I can see the above not working is either setjmp doesn't
save the entire register state it should, the jmp_buf somehow gets clobbered
before the longjmp call or longjmp doesn't restore the entire register
state that it should.  All of those would be bugs in my book.

The only thing the register allocator should need to do, is treat setjmp
just like any other function call and make all pseudos that are live across
it interfere with all volatile hard registers, so that they will be assigned
to either non-volatile hard registers or spilled (if no non-volatile registers
are available).

Peter


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]