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.

Reply via email to